RBM 캠페인에서 오프라인 사용자를 처리하는 방법

에이전트 메시지 전송 시간의 주요 요소는 연락하려는 사용자가 에이전트가 연결되었을 때 데이터 연결이 되어 있었습니다. 메시지를 보냅니다. 사용자가 오프라인 상태인 경우 RBM 플랫폼은 메시지를 저장하고 최대 30일 동안 전송을 시도합니다. 그때까지 메시지를 전송할 수 없는 경우 시스템에서 삭제됩니다.

사용자가 인터넷에 연결하지 못하는 이유와 상황은 여러 가지가 있습니다. 확인할 수 있습니다. 데이터를 사용 중지했을 수 있습니다 Wi-Fi가 없는 비행기 탑승을 할 수도 있고, 터널에서 지하철에 있을 수도 있습니다. 긴급한 상황에 따라 다름 에이전트는 메시지를 매끄럽게 처리해야 하므로 전달되지 않은 RBM 메시지를 취소하고 해당 메시지를 다시 라우팅하여 오프라인 사용자 다른 채널을 통해서였습니다.

다음 섹션에서는 Google Cloud Datastore에서 메시지를 보내고 전달하는 방법, 크론을 사용하여 취소 SMS를 통해 메시지를 다시 라우팅하는 방법

전송된 메시지 추적

RBM 에이전트에서 전송하는 모든 메시지에는 고유한 메시지 ID가 포함되어야 합니다. 상담사가 전송하는 메시지를 추적하려면 각 메시지의 메시지 ID, 전화번호, 타임스탬프를 저장해야 합니다.

이 정보를 저장하는 데 다음과 같은 다양한 기술을 사용할 수 있습니다. Google Cloud Datastore에서 사용할 수 있습니다 확장성이 높은 NoSQL인 Cloud Datastore 샤딩과 복제를 자동으로 처리하는 데이터베이스입니다. 정말 훌륭합니다. 에이전트에서 보낸 메시지와 같은 비관계형 데이터를 저장하기 위한 솔루션입니다. Cloud Datastore는 활성 상태의 Google App Engine 인스턴스이므로 App Engine을 사용하여 RBM 에이전트를 호스팅하고 크론 작업을 구성합니다.

Cloud Datastore용 클라이언트 라이브러리는 여러 언어로 제공됩니다. 이 예에서는 Node.js를 사용하고 RBM 개발자 웹사이트에서 제공하는 첫 번째 상담사 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,
});

Datastore 객체를 만들면 각 메시지의 msisdn, message id, sent time, delivery 상태입니다.

/**
 *   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를 포함하는 응답 객체를 콜백 메서드에 제공합니다.

다음은 사용자에게 일반 문자 메시지를 보내고 메시지 정보를 반환합니다.

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를 검사할 수 있습니다.

Datastore

메일 전송 상태 업데이트

이제 에이전트가 전송된 메시지 요청을 Datastore에 저장했으므로 메시지가 사용자 기기에 성공적으로 전송되면 전송 상태를 업데이트합니다.

사용자 기기는 Cloud Pub/Sub을 통해 DELIVERED, READ, IS_TYPING 이벤트를 RBM 에이전트로 전송합니다. 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에 저장하고 요청이 있을 때 데이터를 업데이트합니다. 전송 알림을 받게 됩니다. 다음 섹션에서는 Google App Engine에서 10분마다 실행되어 전송되지 않은 메시지를 모니터링하는 cron 작업을 설정하는 방법을 알아봅니다.

Google App Engine의 크론

크론 작업을 사용하여 서로 다른 간격으로 작업을 예약할 수 있습니다. Google의 App Engine에서는 크론 작업이 설명, URL, 간격으로 구성됩니다.

Node.js 앱에서는 cron.yaml 파일에서 이를 구성하며, 이 파일은 Google Cloud SDK를 사용하여 App Engine에 배포할 수 있습니다. 다음을 사용하여 작업 예약에서 다른 언어 구성 설정에 대해 알아보기 cron.yaml.

크론 작업에는 URL이 필요하므로 크론에서 호출할 URL 엔드포인트를 Express 앱 라우터에 추가해야 합니다. 이 웹훅은 Datastore에서 이전 메시지를 쿼리하고, RBM 플랫폼에서 삭제하고, SMS를 통해 사용자에게 전송합니다.

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();
});

다음은 10분마다 이 엔드포인트를 실행하는 cron.yaml 파일 구성입니다. 합니다.

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

크론 태스크를 App Engine에 배포하려면 다음 명령어를 실행합니다.

gcloud app deploy cron.yaml

배포 후에는 App Engine이 자동으로 크론 태스크를 구성하며 작업은 App Engine > 크론 작업.

크론 작업

Datastore에서 전송되지 않은 메시지 쿼리

이전 섹션에서 설정한 크론 작업의 웹훅에 delivered 상태가 false인 모든 전송된 메시지를 조회하는 로직 사전 정의된 제한 시간보다 lastUpdated배 더 오래 지속되므로 Google 사용 사례에 적합합니다 이 예에서는 1시간이 지난 메시지를 만료합니다.

이와 같은 복합 쿼리를 지원하려면 Datastore에 deliveredlastUpdated 속성이 모두 포함된 복합 색인이 있어야 합니다. 받는사람 프로젝트에 다음 정보를 참조하세요.

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

이전에 정의한 cron 작업을 배포하는 것과 마찬가지로 Google Cloud SDK를 사용하여 다음 명령어로 정의한 복합 색인을 배포합니다.

gcloud datastore create-indexes index.yaml

배포 후에는 App Engine이 자동으로 색인을 구성하고 데이터 저장소 > 색인.

데이터 저장소 색인

색인이 정의되면 크론용으로 만든 웹훅으로 돌아갈 수 있습니다. 메시지 만료 로직을 완료합니다.

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은 기본적으로 SMS 대체를 지원하지 않으므로 전송되지 않은 메시지를 SMS를 통해 전송하는 로직을 구현해야 합니다.

마무리 및 요약

오프라인 사용자를 처리하기 위해 전송되지 않은 RBM의 취소 로직을 빌드할 수 있습니다. 메시지를 보낼 수 있습니다 메시지가 만료되기까지 걸리는 시간은 다음에 따라 다릅니다. 얼마나 시간에 민감한지를 운용합니다. 시간에 민감함 권장되는 제한 시간은 2시간 미만입니다.

이 예시에서는 Cloud Datastore와 Google App Engine을 사용하여 쿼리, 취소 프로세스, 그리고 이전 데이터를 추적하기 위한 모든 저장 메커니즘은 전송 및 전송된 메시지가 작동할 것입니다.

행운을 빕니다. 즐겁게 코딩해 보세요.