Salesforce Canvas イベントの作成・登録を試してみる

# はじめに
https://qiita.com/takaHAL/items/6fa0d76a4056045d76bc

前回のSalesforce Canvasの導入の続きにです。
キャンバスアプリケーションイベント実装について検証しようと思います。

**Salesforce（Visualforce）⇄ キャンバスアプリケーション（Webサイト）** 間でイベント実装します。

[キャンバスアプリケーションイベント作成](https://developer.salesforce.com/docs/atlas.ja-jp.platform_connect.meta/platform_connect/canvas_app_event_subscribe_code_example.htm)

[Visualforce-Canvasから公開された指定のイベントを登録](https://developer.salesforce.com/docs/atlas.ja-jp.platform_connect.meta/platform_connect/canvas_app_vf_subscribe_code_example.htm)

[Visualforceイベントを作成](https://developer.salesforce.com/docs/atlas.ja-jp.platform_connect.meta/platform_connect/canvas_app_vf_publish_code_example.htm)

[キャンバスアプリケーションイベント登録](https://developer.salesforce.com/docs/atlas.ja-jp.platform_connect.meta/platform_connect/canvas_app_event_subscribe_code_example.htm)

# 前提条件
- キャンバスアプリケーションの設定をした接続アプリケーションがあること
- キャンバスアプリケーションとして呼び出すWebサイトがあること

# イベント実装でできること

キャンバスアプリケーション側（埋め込みサイト）の方からSalesforceに〇〇したよ！とか〇〇お願いのメッセージ、レコードの外部ID等を通知したりすることができます。

以下のように実装すると、Salesforce側に` {status : 'Completed'}`という情報を渡すことができます。

```js: キャンバスアプリケーション側（埋め込みサイト）
Sfdc.canvas.client.publish(sr.client,
        {name : "mynamespace.statusChanged", payload : {status : 'Completed'}});
```

```js: Salesforce側 Visualforce
 Sfdc.canvas.controller.subscribe([
        {
          name: "mynamespace.statusChanged",
          onData: function (event) {
            console.log("Subscribed to custom event ", event);
          }
        }
      ]);
    });
```

逆も可能でVisualforce→キャンバスアプリケーションみたいにすることもできます。

こんな感じ!

![スクリーンショット 2022-12-12 3.36.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/239668e0-0081-fbab-ea1b-70a4ca3be595.png)


ではやってみる

# キャンバスアプリケーション→Visualforceパターン

## キャンバスアプリケーション： イベントの作成

コードは前回に引き続きGitHubに公開しているもので必要のないものを省きながら編集します。

:::note
GitHubへのコード反映をVisualforce分終わってないので、
終了次第記事に追記します。
:::

https://github.com/takaHAL/canvasAppTest/blob/main/index.html

以下のコードに修正しました。

```diff_html: index.html
<html>
  <head>
    <script src="./js/canvas-all.js"></script>
  </head>
  <body>
    <h1>埋め込みテスト</h1>
    <script>
      Sfdc.canvas.client.refreshSignedRequest(function(data) {
        if (data.status === 200) {

          const signedRequest =  data.payload.response;
          console.log(signedRequest);
          const part = signedRequest.split('.')[1];
          const obj = JSON.parse(Sfdc.canvas.decode(part));
          console.log(obj);
+          Sfdc.canvas.client.publish(obj.client, {
+            name: "mynamespace.Hello",
+            payload: {
+              status: 'Hello'
+            }
+         });
        }
      });
    </script>
  </body>
</html>
```

`mynamespace.Hello`というイベントを作成し、`Hello`という文字列を渡します。

## Visualforce：  イベントの登録

https://developer.salesforce.com/docs/atlas.ja-jp.platform_connect.meta/platform_connect/canvas_app_vf_subscribe_code_example.htm

Visualforceでキャンバスアプリケーションから公開された指定のイベントを登録するには

- [controller.js](https://developer.salesforce.com/docs/atlas.en-us.202.0.platform_connect.meta/platform_connect/canvas_vf_app_resizing.htm)の読み込み
- subscribeの実装

の2点が必要です。

```diff_html: canvasAppTest.page
<apex:page>
+  <script type="text/javascript" src="/canvas/sdk/js/55.0/controller.js"></script>
+  <script>
+    Sfdc.onReady(function () {
+      Sfdc.canvas.controller.subscribe([
+        {
+          name: "mynamespace.Hello",
+          onData: function (event) {
+            alert(event.status)
+          }
+        }
+      ]);
+    });
+  </script>
  <apex:canvasApp developerName="canvasAppTest" maxHeight="infinite" width="100%" entityFields="Phone, Name" parameters="{message:'キャンバステスト'}"
  />
</apex:page>
```

## 確認

Helloという文字を渡すことができました！

![スクリーンショット 2022-12-12 21.25.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/096cfcc8-8d6e-0c79-18f4-f41a6eef83bd.png)




# Visualforceパターン→キャンバスアプリケーションパターン

ボタンを押すと、キャンバスアプリケーションにイベントが通知されるようにします。

## Visualforce： イベントの作成

Visualforceでイベントを作成するには

- [controller.js](https://developer.salesforce.com/docs/atlas.en-us.202.0.platform_connect.meta/platform_connect/canvas_vf_app_resizing.htm)の読み込み
- publishの実装

```diff_html: 
<apex:page>
+  <script type="text/javascript" src="/canvas/sdk/js/55.0/controller.js"></script>
+  <script>
+    function publishStatus() {
+      Sfdc.canvas.controller.publish({
+        name: 'mynamespace.world',
+        payload: {
+          status: 'world'
+        },
+      });
+    }
+  </script>
+  <apex:form >
+    <apex:commandLink onclick="publishStatus()" value="Hello" />
+  </apex:form>
  <apex:canvasApp developerName="canvasAppTest" maxHeight="infinite" width="100%" entityFields="Phone, Name" parameters="{message:'キャンバステスト'}"
  />
</apex:page>
```

`mynamespace.world`というイベントを作成し、`world`という文字列を渡します。

## キャンバスアプリケーション：イベントの登録

```diff_html: index.html
<html>
  <head>
    <script src="./js/canvas-all.js"></script>
  </head>
  <body>
    <h1>埋め込みテスト</h1>
    <script>
      Sfdc.canvas.client.refreshSignedRequest(function(data) {
        if (data.status === 200) {

          const signedRequest =  data.payload.response;
          console.log(signedRequest);
          const part = signedRequest.split('.')[1];
          const obj = JSON.parse(Sfdc.canvas.decode(part));
          console.log(obj);
+         Sfdc.canvas.client.subscribe(obj.client, {
+          name: 'mynamespace.world',
+          onData: function (event) {
+            alert(event.status)
+          }
+        });
        }
       );
      });
    </script>
  </body>
</html>

```

## 確認

ボタンを押すと...

![スクリーンショット 2022-12-12 22.08.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/b14865ac-fa2f-2f29-83c7-d4dfc318895e.png)


無事受信できました。

![スクリーンショット 2022-12-12 22.08.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/103aa50d-bb3d-08f3-1443-bfbfb7ab5a74.png)


# 最後に

キャンバスアプリケーションとVisualforceでの通信ができました！
互いのフォームイベントを感知したり等いろいろ使い道はありそうです。

次は、Salesforce Canvas + jsforceでSalesforceのレコードの取得・作成をしようと思います。

# 参考

https://developer.salesforce.com/docs/atlas.ja-jp.pages.meta/pages/pages_compref_canvasApp.htm

https://developer.salesforce.com/docs/atlas.ja-jp.platform_connect.meta/platform_connect/canvas_app_events_considerations.htm

https://developer.salesforce.com/docs/atlas.ja-jp.platform_connect.meta/platform_connect/canvas_app_vf_subscribe_code_example.htm

https://developer.salesforce.com/docs/atlas.ja-jp.platform_connect.meta/platform_connect/canvas_app_vf_publish_code_example.htm

https://developer.salesforce.com/docs/atlas.ja-jp.platform_connect.meta/platform_connect/canvas_app_event_publish_code_example.htm

https://developer.salesforce.com/docs/atlas.ja-jp.platform_connect.meta/platform_connect/canvas_app_event_subscribe_code_example.htm

https://developer.salesforce.com/docs/atlas.en-us.202.0.platform_connect.meta/platform_connect/canvas_vf_app_resizing.htm