如何在 RBM 廣告活動中處理離線使用者

代理程式訊息的傳送時間 代理程式進行時,您嘗試聯絡的使用者已有數據連線 傳送訊息。如果使用者處於離線狀態,RBM 平台會儲存訊息,並最多在 30 天內嘗試傳送。如果屆時還是無法傳送訊息, 但卻會從系統中移除

使用者無法連線的原因有很多 與虛擬服務專員聯絡時他們可能關閉了資料功能 行動資費方案可節省費用,或許可以在沒有 Wi-Fi 的飛機上操作 連線或可能位於隧道中的地鐵。視迫切程度而定 你的訊息要送達時,服務專員必須妥善處理 離線使用者,方法為撤銷未傳送的 RBM 訊息,然後重新轉送這些訊息。 並透過其他管道

以下各節將詳細說明如何使用 Google Cloud Datastore: 您傳送和傳送的訊息 如何使用 Cron 撤銷 ,以及如何透過簡訊重新轉送這些訊息。

追蹤已傳送的訊息

RBM 服務專員傳送的每則訊息都必須包含專屬的訊息 ID。如要追蹤服務專員傳送的訊息,你必須儲存訊息 ID。 電話號碼和每則訊息的時間戳記。

您可以使用各種技術儲存這類資訊,包括 Google Cloud Datastore。Cloud Datastore 是高度可擴充的 NoSQL 資料庫,可自動處理資料分割和複製作業。這是儲存非關聯資料 (例如由服務專員傳送的訊息) 的絕佳解決方案。Cloud Datastore 需要有效的 Google App Engine 執行個體,因此您可以使用 App Engine 代管 RBM 代理程式並設定 cron 工作。

Cloud Datastore 提供多種語言的用戶端程式庫。適用對象 本例中,您可以使用 Node.js,並以 第一個代理程式 Node.js 範例 請造訪 RBM 開發人員網站。首先,請執行下列指令,為我的 Node.js 專案安裝 Cloud Datastore:

npm install --save @google-cloud/datastore

在代理程式原始碼中,將全域參照新增至 Cloud Datastore 用戶端 資源庫。

// Imports the Google Cloud client library
const Datastore = require('@google-cloud/datastore');

// Creates a client
const datastore = new Datastore({
    projectId: PROJECT_ID,
});

建立資料儲存庫物件後,您可以引入函式,用於儲存每則訊息的 msisdnmessage idsent timedelivery 狀態。

/**
 *   Records an entry in the Cloud Datastore to keep track of the
 *   messageIds sent to users and the delivery state.
 *
 *   @property {string} msisdn The user's phone number in E.164 format.
 *   @property {string} messageId The unique message identifier.
 *   @property {boolean} delivered True if message has been delivered.
 */
function saveMessage(msisdn, messageId, delivered) {
    const messageKey = datastore.key(['Message', messageId]);

    const dataForMessage = {
        key: messageKey,
        data: {
            id: messageId,
            msisdn: msisdn,
            lastUpdated: new Date().getTime(),
            delivered: delivered
        },
    };

    // Record that the message was sent.
    datastore
        .save(dataForMessage)
        .then(function() {
            console.log('saved message successfully');
        })
        .catch((err) => {
            console.error('ERROR:', err);
        });
}

設定這個函式後,每當您的代理程式 向使用者傳送訊息。當 RBM Node.js 用戶端程式庫傳送 RBM 訊息時,程式庫會在回呼方法中提供回應物件,其中包含已傳送給使用者的訊息 messageId

以下範例是將純文字訊息傳送給使用者,並記錄下來 成功與 RBM API 通訊後,即訊息資訊。

let params = {
    messageText: 'Hello, World!',
    msisdn:'+12223334444',
};

// Send "Hello, World!" to the user.
rbmApiHelper.sendMessage(params,
function(response) {
    // Extract the message ID from the response
    let messageId = response.config.params.messageId;

    // Store the sent state in the Datastore
    saveMessage(phoneNumber, messageId, false);
});

執行程式碼後,您可以在 Google 「Cloud 控制台」中的 Datastore 實體 檢視畫面。

Datastore

更新訊息的傳送狀態

代理程式現在會將已傳送的訊息要求儲存至資料儲存庫,請更新 訊息成功傳送至使用者的裝置後傳送的狀態。

使用者裝置會將 DELIVEREDREADIS_TYPING 事件傳送給 RBM 代理程式 以及 Cloud Pub/Sub在 Pub/Sub 的處理常式中,檢查是否有已傳送的事件 並將所提供標記的 Datastore 設定更新為 true。

/**
 *   Uses the event received by the Pub/Sub subscription to send a
 *   response to the client's device.
 *   @param {object} userEvent The JSON object of a message
 *   received by the subscription.
 */
function handleMessage(userEvent) {
    if (userEvent.senderPhoneNumber != undefined) {
        let msisdn = userEvent.senderPhoneNumber;
        let messageId = userEvent.messageId;
        let eventType = userEvent.eventType;

        if(eventType === 'DELIVERED') {
            saveMessage(msisdn, messageId, true);
        }

        // TODO: Process message and create RBM response
    }
}

代理程式會將傳出的訊息儲存至 Datastore,並在儲存時更新資料 這樣就會收到外送通知下一節將說明如何設定 Cron Google App Engine 上的工作,每 10 分鐘執行一次,以便監控未傳送量 訊息。

在 Google App Engine 上執行 Cron

您可以使用 Cron 工作,以不同的時間間隔排定工作。在 Google 的 App Engine 中,Cron 工作會搭配說明、網址和間隔時間進行設定。

在 Node.js 應用程式中,您可以在 cron.yaml 檔案中設定這些項目,並使用 Google Cloud SDK 部署至 App Engine。有關其他語言配置設定,請參閱利用 cron.yaml.

由於 Cron 工作需要網址,您必須在 Express 中新增網址端點 供 Cron 呼叫。這個 Webhook 負責查詢 Datastore 中的舊訊息,從 RBM 平台中刪除,並透過簡訊傳送給使用者。

router.get('/expireMessages', function(req, res, next) {
    // TOOD: Query the Datastore for undelivered messages,
    // remove them from the RBM platform, and send them over SMS

    res.status(200).send();
});

以下是 cron.yaml 檔案設定,可每 10 分鐘執行這個端點。

cron:
-   description: "Processing expired RBM messages"
  url: /expireMessages
  schedule: every 10 mins

如要將 Cron 工作部署至 App Engine,請執行下列指令:

gcloud app deploy cron.yaml

部署完成後,App Engine 會自動設定 cron 工作,您可以在「App Engine > Cron 工作」下方查看該工作。

Cron 工作

查詢 Datastore 中的未送達訊息

在先前章節中設定的 cron 工作 webhook 中,您需要新增邏輯,以便查詢所有傳送的訊息,這些訊息的 delivered 狀態等於 false,且 lastUpdated 時間早於適用於本用途的預先定義逾時時間。在本例中,系統會刪除一小時前傳送的訊息。

為了支援這類複合式查詢,資料儲存庫必須具備複合式索引,其中包含 deliveredlastUpdated 屬性。目的地: 方法是在專案中建立名為 index.yaml 的檔案, 以下資訊:

indexes:
-   kind: Message
  properties:
  -   name: delivered
    direction: asc
  -   name: lastUpdated
    direction: desc

與部署您先前定義的 Cron 工作類似,請使用 Google Cloud SDK 使用下列指令來部署您定義的複合式索引:

gcloud datastore create-indexes index.yaml

部署完成後,App Engine 會自動設定索引和索引 會顯示在 Datastore >索引

資料儲存庫索引

定義索引後,即可返回為 Cron 建立的 Webhook 工作,並完成訊息到期邏輯:

router.get('/expireMessages', function(req, res, next) {
    // Milliseconds in an hour
    const TIMEOUT = 3600000;

    // Threshold is current time minus one hour
    const OLD_MESSAGE_THRESHOLD = new Date().getTime() - TIMEOUT;

    // Create a query to find old undelivered messages
    const query = datastore
        .createQuery('Message')
        .filter('delivered', '=', false)
        .filter('lastUpdated', '<', OLD_MESSAGE_THRESHOLD);

    // Execute the query
    datastore.runQuery(query).then((results) => {
        for(var i = 0; i < results[0].length; i++) {
            let msisdn = results[0][i].msisdn;
            let messageId = results[0][i].id;

            // Stop the message from being sent
            rbmApiHelper.revokeMessage(msisdn, messageId);

            // Remove the message from the Datastore
            datastore.delete(results[0][i][datastore.KEY]);

            // TODO: Send the user the message as SMS
        }
    });

    res.status(200).send();
});

RBM 並未原生支援簡訊備用功能,因此您必須實作邏輯,透過簡訊傳送未送達的訊息。

總結

如要處理離線使用者,您可以為未送達的 RBM 訊息建立撤銷邏輯。訊息到期前應使用的時間取決於 傳送的資訊是否具時效性具時效性 資訊,建議的逾時時間不到兩小時。

此範例使用 Cloud Datastore 和 Google App Engine 管理儲存空間 以及撤銷程序,而是能記錄持續追蹤的 正常傳送和已傳送的郵件應該可以正常運作

祝一切順利,祝您順利寫程式!