Open CTI で Lightning Message Service を使用してみる


やりたいこと

screenPop()でVFページをポップアップさせて、そのVFからのイベント(ボタンクリックとか)をOpenCTIソフトフォンで受け取るのは可能か確認したい。

実現イメージ

先に出来たものをお見せしたいと思います。ソフトフォン側でSubscribeして、VF側のボタンからメッセージを受信しています。
他の検証用のボタンがありますが気にしないでください。(笑)

実現方法

前半は、screenPop()を使用するだけですので省略します。(コード見て頂ければと思います。)

VFからのイベント(ボタンクリックとか)をOpenCTIソフトフォンで受け取るのは可能か確認したい。

この部分は、Lightning Message Serviceを使用するのが良さそうでした。
Open CTIのJSライブラリでも出来るか見てみましたが、それらしいメソッドはありませんでした。

参考

Lightning Message Service を使用した DOM 間の通信
Open CTI で Lightning Message Service を使用するためのサンプルコード

LightningMessageChannelの作成

Lightning Message Serviceを使用するにはLightningMessageChannelを作成する必要があります。
LightningMessageChannelはメタデータからしか作れないみたいでしたので、VScodeを使っている方はこれを以下のフォルダとファイル名で作成しデプロイします
force-app/main/default/messageChannels/SampleMessageChannel.messageChannel-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
    <masterLabel>SampleMessageChannel</masterLabel>
    <isExposed>true</isExposed>
    <lightningMessageFields>
        <fieldName>recordId</fieldName>
    </lightningMessageFields>
    <lightningMessageFields>
        <fieldName>recordData</fieldName>
    </lightningMessageFields>
</LightningMessageChannel>

画面の作成

VF側(Publish)

ボタンをクリックしたらメッセージをPublishします。

//ScreenPopupPage(VF)
<apex:page >
    <head>
        <script>
        // Load the MessageChannel token in a variable
        var SAMPLEMC = "{!$MessageChannel.SampleMessageChannel__c}";
        function handleClick() {
            const payload = {
                recordId: "some string",
                recordData: {value: "some value"}
            }
            sforce.one.publish(SAMPLEMC, payload);
        }
        </script>
    </head>

    <body>
        <h1>スクリーンポップ用のVFです</h1>
        <div>
            <p>Publish SampleMessageChannel</p>
            <button onclick="handleClick()">Publish</button>
        </div>
    </body>

</apex:page>

ソフトフォン側(Subscribe)

メッセージ受信側の画面です。


//CtiSoftphone(VF)

<apex:page >
    <head>
        <script src="/support/api/50.0/lightning/opencti_min.js" type="text/javascript"></script>
        <script type="text/javascript">

        //**************VF,ソフトフォン間イベント通知テスト********************
        //ここは先ほど作成したLightningMessageChannelを指定します。
        var SAMPLEMC = "SampleMessageChannel__c";
        var SAMPLEMC_SUBSCRIPTION = null;

        function subscribeToSampleMC() {
            if (!SAMPLEMC_SUBSCRIPTION) {
                sforce.opencti.subscribe({channelName: SAMPLEMC, listener: onPublishMessage, callback: subscribeSampleMCCallback});
                let mcSubscribedToggle = document.querySelector("#opencti_mcSubscribedToggle");
                mcSubscribedToggle.innerHTML = "true";
            }
        }

        function unsubscribeToSampleMC() {
            if (SAMPLEMC_SUBSCRIPTION) {
                sforce.opencti.unsubscribe({subscription: SAMPLEMC_SUBSCRIPTION, callback: lightningMessageServiceCallback});
                let mcSubscribedToggle = document.querySelector("#opencti_mcSubscribedToggle");
                mcSubscribedToggle.innerHTML = "false";
                SAMPLEMC_SUBSCRIPTION = null;
            }
        }

        function lightningMessageServiceCallback(result) {
            if (result.success) {
                console.log(result.returnValue);
            } else {
                console.log(result.errors);
            }
        }

        function subscribeSampleMCCallback(result) {
            if (result.success) {
                SAMPLEMC_SUBSCRIPTION = result.subscription;
            } else {
                console.log(result.errors);
            }
        }

        function onPublishMessage(message) {
            console.log("onPublishMessage",message)
            var textArea = document.querySelector("#opencti_testMessageTextArea");
            textArea.innerHTML += message ? JSON.stringify(message, null, '\t') : 'no message payload';
        }
        </script>
    </head>

    <body>
        <div>
            <p>MessageChannel: SampleMC</p>
            <p>Subscribed: <span id="opencti_mcSubscribedToggle">false</span></p>
            <br/>
            <input value="Subscribe" type="button" onclick="subscribeToSampleMC()"/>
            <input value="Unsubscribe" type="button" onclick="unsubscribeToSampleMC()"/>
            <input value="Publish" type="button" onclick="publishSampleMC()"/>
            <br/>
            <p>Received message:</p>
            <textarea id="opencti_testMessageTextArea" class="opencti_testMessageTextArea" rows="10" style="disabled:true;resize:none;width:100%;"/>
        </div>
    </body>
</apex:page>   

終わりに

Lightning Message Service の情報は少なかったのでイメージでもわかって頂けたら幸いです。
同じOpen CTI系でこちらもどうぞ!
ストリーミングAPIで受信したイベントの絞込み