メッセージの送信

トピックの作成が完了したら、いよいよプッシュメッセージの送信です。トピックにメッセージを送信すると、このトピックを購読している全てのユーザーに対してメッセージがプッシュされます。

アプリケーションスコープのトピックへの送信

アプリケーションスコープのトピックには、アプリ開発者のみが開発者ポータルを使ってメッセージを送信できます。

送信方法は ユーザープッシュ通知の送信 をご覧ください。

グループスコープ/ユーザースコープのトピックへの送信

グループスコープのトピックまたはユーザースコープのトピックには、モバイルアプリからメッセージを送信できます。

メッセージの送信

グループスコープのトピックには、任意のグループメンバーがメッセージを送ることができます。以下に、メッセージ送信を行うコード例を挙げます。

  • // Instantiate a group.
    KiiGroup group = KiiGroup.createByUri(groupUri);
    
    try {
      // Refresh the group.
      group.refresh();
    } catch (GroupOperationException e) {
      // Handle the error.
    }
    
    // Instantiate a topic in the group scope.
    String topicName = "GroupTopic";
    KiiTopic topic = group.topic(topicName);
    
    // Create push message data.
    Data data = new Data();
    data.put("str", "str");
    data.put("int", 1);
    data.put("bool", false);
    data.put("double", 1.12);
    
    // Create a push message.
    KiiPushMessage message = KiiPushMessage.buildWith(data).build();
    
    try {
      // Send the push message.
      topic.sendMessage(message);
    } catch (IOException ioe) {
      // Handle the error.
    } catch (AppException e) {
      // Handle the error.
    }
  • // Instantiate a group.
    KiiGroup group = KiiGroup.createByUri(groupUri);
    
    // Refresh the group.
    group.refresh(new KiiGroupCallBack() {
      @Override
      public void onRefreshCompleted(int token, KiiGroup group, Exception exception) {
        if (exception != null) {
          // Handle the error.
          return;
        }
        // Instantiate a topic in the group scope.
        String topicName = "GroupTopic";
        KiiTopic topic = group.topic(topicName);
    
        // Create push message data.
        Data data = new Data();
        data.put("str", "str");
        data.put("int", 1);
        data.put("bool", false);
        data.put("double", 1.12);
    
        // Create a push message.
        KiiPushMessage message = KiiPushMessage.buildWith(data).build();
    
        // Send the push message.
        topic.sendMessage(message, new KiiTopicCallBack() {
          @Override
          public void onSendMessageCompleted(int taskId, KiiTopic target, KiiPushMessage message, Exception exception) {
            if (exception != null) {
              // Handle the error.
              return;
            }
          }
        });
      }
    });

ユーザースコープのトピックには、このユーザーまたはトピックの所有者のみがメッセージを送信できます。以下に、メッセージ送信を行うコード例を挙げます。

  • try {
      // Instantiate a topic in the user scope.
      String topicName = "MyTODO";
      KiiTopic topic = KiiUser.topic(topicName);
    
      // Create push message data.
      Data data = new Data();
      data.put("Item", "Do something");
      data.put("Done", 0);
    
      // Create a push message.
      KiiPushMessage message = KiiPushMessage.buildWith(data).build();
    
      // Send the push message.
      topic.sendMessage(message);
    } catch (IOException ioe) {
      // Handle the error.
    } catch (AppException e) {
      // Handle the error.
    }
  • // Instantiate a topic in the user scope.
    String topicName = "MyTODO";
    KiiTopic topic = KiiUser.topic(topicName);
    
    // Create push message data.
    Data data = new Data();
    data.put("Item", "Do something");
    data.put("Done", 0);
    
    // Create a push message.
    KiiPushMessage message = KiiPushMessage.buildWith(data).build();
    
    // Send the push message.
    topic.sendMessage(message, new KiiTopicCallBack() {
      @Override
      public void onSendMessageCompleted(int taskId, KiiTopic target, KiiPushMessage message, Exception exception) {
        if (exception != null) {
          // Handle the error.
          return;
        }
      }
    });

いずれも、以下の処理をしています。

  • URI 指定されたグループ、または、ログイン中のユーザーから送信対象のトピックを取得。
  • メッセージに含めるキーと値のペアを定義した後、 buildWith メソッドを実行してプッシュメッセージを作成。
  • トピックの sendMessage メソッドを実行し、メッセージを送信。

なお、グループスコープのサンプルコードでは refresh() メソッドを実行していますが、group をプッシュメッセージの送信だけに使用する場合は、実行を省略することもできます。

各プッシュ通知ネットワークに特有のフィールドを設定する

グループスコープのトピックまたはユーザースコープのトピックにプログラムからメッセージを送信する際、各プッシュ通知ネットワークに特有のフィールド値を設定することで、デバイスでの動作などをカスタマイズすることができます。

プッシュメッセージをカスタマイズする方法を以下に示します。

  • // Assume that the target topic has been instantiated.
    
    // Create push message data.
    KiiPushMessage.Data data = new KiiPushMessage.Data();
    data.put("your_keys", "your_values");
    
    // Create FCM-specific data.
    GCMMessage gcm = GCMMessage.builder()
            .withCollapseKey("CollapseKey")
            .withRestrictedPackageName("your.package.name")
            .withTimeToLive(10)
            .build();
    
    // Create APNs-specific data.
    // Make the notification silent.
    APNSMessage.APNSData apnsData = new APNSMessage.APNSData();
    apnsData.put("From", "Alice");
    apnsData.put("MsgBody", "Hi all!");
    apnsData.put("Urgent", false);
    apnsData.put("Weight", 1.12);
    APNSMessage apns = APNSMessage.builder()
            .withContentAvailable(1)
            .withAPNSData(apnsData)
            .build();
    
    // Send an APNs message with rich content.
    // APNSMessage apns = APNSMessage.builder()
    //        .withAlertTitle("New message")
    //        .withAlertSubtitle("Message from Alice")
    //        .withAlertBody("It's been a while...")
    //        .withMutableContent(1)
    //        .withCategory("MESSAGE_CATEGORY")
    //        .withAPNSData(apnsData)
    //        .build();
    
    // Create MQTT-specific data.
    MqttMessage.Builder.MqttData mqttData = new MqttMessage.Builder.MqttData();
    mqttData.put("MsgTitle", "Message from Alice");
    MqttMessage mqtt = MqttMessage.builder()
            .withMqttData(mqttData)
            .build();
    
    // Create a push message.
    KiiPushMessage message = KiiPushMessage.buildWith(data)
            .withGCMMessage(gcm)
            .withAPNSMessage(apns)
            .withMqttMessage(mqtt)
            .build();
    
    try {
      // Send the push message.
      topic.sendMessage(message);
    } catch (IOException ioe) {
      // Handle the error.
    } catch (AppException e) {
      // Handle the error.
    }
  • // Assume that the target topic has been instantiated.
    
    // Create push message data.
    KiiPushMessage.Data data = new KiiPushMessage.Data();
    data.put("your_keys", "your_values");
    
    // Create FCM-specific data.
    GCMMessage gcm = GCMMessage.builder()
            .withCollapseKey("CollapseKey")
            .withRestrictedPackageName("your.package.name")
            .withTimeToLive(10)
            .build();
    
    // Create APNs-specific data.
    // Make the notification silent.
    APNSMessage.APNSData apnsData = new APNSMessage.APNSData();
    apnsData.put("From", "Alice");
    apnsData.put("MsgBody", "Hi all!");
    apnsData.put("Urgent", false);
    apnsData.put("Weight", 1.12);
    APNSMessage apns = APNSMessage.builder()
            .withContentAvailable(1)
            .withAPNSData(apnsData)
            .build();
    
    // Send an APNs message with rich content.
    // APNSMessage apns = APNSMessage.builder()
    //        .withAlertTitle("New message")
    //        .withAlertSubtitle("Message from Alice")
    //        .withAlertBody("It's been a while...")
    //        .withMutableContent(1)
    //        .withCategory("MESSAGE_CATEGORY")
    //        .withAPNSData(apnsData)
    //        .build();
    
    // Create MQTT-specific data.
    MqttMessage.Builder.MqttData mqttData = new MqttMessage.Builder.MqttData();
    mqttData.put("MsgTitle", "Message from Alice");
    MqttMessage mqtt = MqttMessage.builder()
            .withMqttData(mqttData)
            .build();
    
    // Create a push message.
    KiiPushMessage message = KiiPushMessage.buildWith(data)
            .withGCMMessage(gcm)
            .withAPNSMessage(apns)
            .withMqttMessage(mqtt)
            .build();
    
    // Send the push message.
    topic.sendMessage(message, new KiiTopicCallBack() {
      @Override
      public void onSendMessageCompleted(int taskId, KiiTopic target, KiiPushMessage message, Exception exception) {
        if (exception != null) {
          // Handle the error.
          return;
        }
      }
    });

ここでは以下の処理をしています。

  • GCMMessage インスタンスを生成して FCM 特有のフィールドをセットします。
  • APNSMessage インスタンスを生成して APNs 特有のフィールドをセットします。
  • MqttMessage インスタンスを生成して MQTT 特有のフィールドをセットします。
  • KiiPushMessage インスタンス生成時に、用意した GCMMessageAPNSMessage、および MqttMessage インスタンスを指定します。 なお、iOS デバイスに サイレント通知 を送信する場合は、このコード例のように withContentAvailable() メソッドでフラグを立ててください。また、iOS に画像付きメッセージなどのリッチ通知を送信したい場合は、コメントアウトされている部分を参考にフィールドをセットしてください。

プッシュメッセージはデフォルトで全てのプッシュ通知ネットワークに送信されます。次の例に示すように、KiiPushMessage インスタンス生成時にフラグを設定することによりプッシュメッセージの送信先を制御できます。

// Deliver a push message to Android devices using FCM only.
KiiPushMessage message = KiiPushMessage.buildWith(data)
        .withGCMMessage(gcm)
        .enableAPNS(false)
        .enableMqtt(false)
        .build();

// Deliver a push message to iOS devices only.
KiiPushMessage message = KiiPushMessage.buildWith(data)
        .withAPNSMessage(apns)
        .enableGCM(false)
        .enableMqtt(false)
        .build();

// Deliver a push message using MQTT only.
KiiPushMessage message = KiiPushMessage.buildWith(data)
        .withMqttMessage(mqtt)
        .enableAPNS(false)
        .enableGCM(false)
        .build();

APNs のペイロードを節約する

FCM のペイロード上限は 4 KB(4096 バイト)です。一方、APNs のペイロード上限は 2 KB(2048 バイト)と限られているため、特に長いメッセージを送る際に問題となることがあります。

Kii Cloud は、デフォルトでは指定されたメッセージ内容に加え、いくつかの既定値をプッシュメッセージとして送信します。一例として、以下のように APNs の Body に "short msg only!" を指定したケースを想定します。

  • // Create APNs-specific data.
    APNSMessage apns = APNSMessage.builder()
            .withAlertBody("short msg only!")
            .build();
    
    // Create a push message.
    KiiPushMessage.Data commonData = new KiiPushMessage.Data();
    KiiPushMessage message = KiiPushMessage.buildWith(commonData)
            .withAPNSMessage(apns)
            .build();
    
    try {
      // Send the push message.
      topic.sendMessage(message);
    } catch (IOException ioe) {
      // Handle the error.
    } catch (AppException e) {
      // Handle the error.
    }
  • // Create APNs-specific data.
    APNSMessage apns = APNSMessage.builder()
            .withAlertBody("short msg only!")
            .build();
    
    // Create a push message.
    KiiPushMessage.Data commonData = new KiiPushMessage.Data();
    KiiPushMessage message = KiiPushMessage.buildWith(commonData)
            .withAPNSMessage(apns)
            .build();
    
    // Send the push message.
    topic.sendMessage(message, new KiiTopicCallBack() {
      @Override
      public void onSendMessageCompleted(int taskId, KiiTopic target, KiiPushMessage message, Exception exception) {
        if (exception != null) {
          // Handle the error.
          return;
        }
      }
    });

この結果、送信されるプッシュメッセージは以下のようなものになります。指定した "short msg only!" だけではなく、いくつかデフォルトキーが追加されていることが分かります。

{
  aps = {
    alert = {
      body = "short msg only!";
    };
  };
  s = "cf6de5b5-8927-48a4-a410-xxxxxxxxxxxx";
  sa = 9a2385ce;
  st = "APP_AND_USER";
  su = "e26ad504-8100-4056-b3d3-xxxxxxxxxxxx";
  to = "MyTopic";
  w = 1373623307000;
}

デフォルトでメッセージに含まれるキーの詳細は以下のとおりです。

  • s:プッシュメッセージ送信者の UserID
  • sa:プッシュメッセージを送信したアプリの AppID
  • st:プッシュメッセージが送信されたトピックのスコープ
    • アプリケーションスコープの場合は "APP"
    • グループスコープの場合は "APP_AND_GROUP"
    • ユーザースコープの場合は "APP_AND_USER"
  • sg:プッシュメッセージが送信されたトピックが属するグループの GroupID(グループスコープのトピックの場合のみ)
  • su:プッシュメッセージが送信されたトピックのオーナーの UserID(ユーザースコープのトピックの場合のみ)
  • to:プッシュメッセージが送信されたトピックの TopicID
  • w:プッシュメッセージ送信時間(UNIX 時間、ミリ秒、UTC)

長いメッセージを送信する場合は、これらのデフォルトキーを抑制することにより使用可能なペイロードを増やすことができます。以下に、デフォルトキーを抑制してプッシュメッセージを送信する例を挙げます。

  • // Create APNs-specific data.
    APNSMessage apns = APNSMessage.builder()
            .withAlertBody("Looooooooooooooooooong Message!!")
            .build();
    
    // Create a push message with the default keys suppressed.
    KiiPushMessage.Data commonData = new KiiPushMessage.Data();
    KiiPushMessage message = KiiPushMessage.buildWith(commonData)
            .sendSender(false)
            .sendObjectScope(false)
            .sendTopicId(false)
            .sendWhen(false)
            .withAPNSMessage(apns)
            .build();
    
    try {
      // Send the push message.
      topic.sendMessage(message);
    } catch (IOException ioe) {
      // Handle the error.
    } catch (AppException e) {
      // Handle the error.
    }
  • // Create APNs-specific data.
    APNSMessage apns = APNSMessage.builder()
            .withAlertBody("Looooooooooooooooooong Message!!")
            .build();
    
    // Create a push message with the default keys suppressed.
    KiiPushMessage.Data commonData = new KiiPushMessage.Data();
    KiiPushMessage message = KiiPushMessage.buildWith(commonData)
            .sendSender(false)
            .sendObjectScope(false)
            .sendTopicId(false)
            .sendWhen(false)
            .withAPNSMessage(apns)
            .build();
    
    // Send the push message.
    topic.sendMessage(message, new KiiTopicCallBack() {
      @Override
      public void onSendMessageCompleted(int taskId, KiiTopic target, KiiPushMessage message, Exception exception) {
        if (exception != null) {
          // Handle the error.
          return;
        }
      }
    });

上記のコードにより送信されるプッシュメッセージは以下のようになります。

{
  aps = {
    alert = {
      body = "Looooooooooooooooooong Message!!";
    };
  };
}

デフォルトキーを抑制するには、KiiPushMessage インスタンスを作成する際に以下のメソッドに対して false を指定します。

抑制するキー 送信抑制のためのメソッド名
s sendSender
sa, st, sg, su sendObjectScope
to sendTopicID
w sendWhen