Salesforce Canvas でWebサイトを埋め込みしてみる

# これは何
- [Salesforce Canvas](https://developer.salesforce.com/docs/atlas.ja-jp.platform_connect.meta/platform_connect/canvas_framework_intro.htm)について設定方法をまとめたものです。
    - iframeの中で Salesforceのデータを扱いやすくなったり、Salesforceに画面をレコード詳細ページに画面を埋め込んだ際にサイズを自動調節してくれたりできます。


:::note 
検証につかう環境は、trailheadのハンズオン環境です。
出てくるデータも初期のデモデータになります。
:::

# Canvas使うと何がいいの？
- 複雑なロジックをSalesforceではなくWebサイトへ
- 効率的なUIをSalesforceで実現するのが難しそうな場合
    - SalesforceではなくWebサイトへ
- WebサイトとSalesforce間での通信

等実装をSalesforce内だけではなく、別のアプリケーションも併用してつかう選択肢としておすすめです。

# この記事でやること
- Canvas用Webサイトの用意
- Canvasアプリケーションの作成
- 取引先ページに埋め込み

# 概要
- [ Webサイトの準備](#webサイトの準備)
- [ Salesforce 設定](#設定)
- [ 取引先ページにCanvasアプリケーションを設置](#取引先ページにcanvasアプリケーションを設置)
- [まとめ](#まとめ)

# Webサイトの準備

埋め込みをするためのWebサイトを準備します。

ホスティング先は`netlify`を使用します。

https://qiita.com/NaokiIshimura/items/40ed08203b35aa0b527c

https://www.netlify.com/

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


作成したコードはGitHubに置いています。

GitHubのコードをダウンロードしていただき`netlify`にあげていただければそのまま使えます

https://github.com/takaHAL/canvasAppTest


コードに関しては、以下のhtmlと
`canvas-all.js`を読み込みんでいます。

https://github.com/forcedotcom/SalesforceCanvasJavascriptSDK/blob/master/js/canvas-all.js

```html: index.html
<html>
  <head>
    <script src="./js/canvas-all.js"></script>
  </head>
  <body>
    <h1>埋め込みテスト</h1>
    <div id="js-canvasArea">表示エリア</div>
    <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);
          const authBlock = document.getElementById('js-canvasArea');
          authBlock.innerHTML = JSON.stringify(obj);
        }
      });
    </script>
  </body>
</html>
```

# 設定

## 接続アプリケーション

### 1. アプリケーションの作成

`設定>アプリケーションマネージャ`にアクセスし、新規接続アプリケーションボタンを押す

![アプリケーションマネージャ _ Salesforce.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/9bd49a9f-31e5-2f2c-2600-e630cf974867.png)

![アプリケーションマネージャ _ Salesforce (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/b1315d31-3c2d-5c79-7bd1-47fd566e2c0a.png)


設定した内容は以下の通りです。

|項目|内容|
|---|---|
|接続アプリケーション名|キャンバスアプリテスト|
|API参照名|canvasAppTest|
|OAuth設定の有効化|チェック|
|コールバックURL|キャンバスアプリケーションのURL/callback|
|選択した OAuth 範囲|`フルアクセス`、`いつでも要求を実行`|
|キャンバス|チェック|
|キャンバスアプリケーションURL|埋め込みたいWebサイトURL|
|アクセス方法|署名付き要求（POST）|
|場所|Lightningコンポーネント、Visualforceページ|

CanvasはAuraとVisualforceで利用できるので、
場所は`Lightningコンポーネント、Visualforceページ`を選択しています。
別の記事でAuraとVisualforceでのCanvas操作を解説しようと思います。

### 2. キャンバスアプリケーションにアクセスできる権限を付与

作成したアプリケーションにアクセスし、`Manage`ボタンを押す。

![接続アプリケーションを管理する _ Salesforce.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/b2d9e1a5-a9d8-5089-7dd0-e6988b32ccf8.png)

`ポリシーを編集`ボタンを押す。

![Lightning Experience _ Salesforce.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/31532461-a790-e63f-6b35-d899b34eb39f.png)

許可されているユーザを`管理者が承認したユーザは事前承認済み`に変更

![Lightning Experience _ Salesforce (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/583930e4-d39f-a60c-3ecb-8463285c1f3e.png)

`プロファイルを管理する`ボタンを押し、システム管理者を追加。

![Lightning Experience _ Salesforce (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/ccdc3b25-dfb0-8d5f-32f7-547ae8b37d7f.png)



### 3. キャンバスアプリケーションの確認

`設定>キャンバスアプリケーションのプレビューア`にアクセス
下記のように埋め込む対象のWebサイトが表示されていればOKです。

trailheadのハンズオン組織で検証していて以下のようなエラーメッセージが出た場合は、
ハンズオン組織をログアウトしユーザ名とパスワードを入力してログインし直してみてください。

:::note warn
Your browsing session has ended or is invalid. Please re-login to Salesforce.com again.
:::

![キャンバスアプリケーションのプレビューア _ Salesforce.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/4d7407ed-b33d-61de-9a59-e8cb85dfcac6.png)

# 取引先ページにCanvasアプリケーションを設置

## 1. Visualforce作成

```html: canvasAppTest.page
<apex:page>
  <apex:canvasApp developerName="canvasAppTest"
    height="1000px" width="100%"
    entityFields="Phone, Name"
    parameters="{message:'キャンバステスト'}"/>
</apex:page>
```

|属性|説明|
|---|---|
|entityFields|Canvasアプリケーション側に渡す、項目。Accountページで表示させ <br /> Phone, Nameを指定すると取引先名と電話番号がCanvasに渡されます。|
|parameters|entityFields以外で値をCanvasに渡したい場合に使用|

`	Lightning Experience、エクスペリエンスビルダーサイト、およびモバイルアプリケーションで利用可能`にチェックを入れましょう

![Visualforce ページ _ Salesforce.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/2a20c9a4-5a53-d276-7cb7-869250d42178.png)

## 2. 取引先のLightningページに設置

![取引先 レコードページ - Lightning アプリケーションビルダー (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/b245d116-3a2a-0c4c-cf93-952b0de7cf9d.png)

:::note warn
netlifyでホスティングしたURLにPOSTすると404になってしまうので
設定等で解決策がわかりましたら冒頭に記載します。
今回は`` Back to our site``のリンクをクリックすると問題なく挙動するので
そちらで対応します。
:::

![Edge Communications _ Salesforce.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/40a2e392-e142-bd72-9bc6-79990b84652a.png)

下記の様にCanvasアプリケーションにTokenや、アクセスしたSalesforceのユーザ情報が渡されます。
Tokenを利用してCanvasアプリケーション側でSalesforceのAPIを実行することもできます。

![Edge Communications _ Salesforce (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/16c524fe-a9e8-0724-367d-dec2213afeed.png)

entityFieldsやparametersも、Canvasアプリケーション側に渡されています。

```json: entityFields
"record":{"attributes":{"type":"Account","url":"/services/data/v56.0/sobjects/Account/0012w000017ipeMAAQ"},
"Id":"0012w000017ipeMAAQ","Phone":"(512) 757-6000","Name":"Edge Communications"}
```

```json: parameters
{"message":"キャンバステスト"}
```


# まとめ

- 埋め込むサイトの中で 認証情報をもとに埋め込みのブロッキング等したい場合
  - ifarmeにアクセスできるアカウントを絞り込むことも可能
  - 渡されるアカウントのトークンでAPIの実行権限制御など
-  Salesforceの認証情報が欲しい場合
-  Salesforceのレコード情報を簡単に使いたい場合
  - 表示している画面の情報を渡すことができる

https://developer.salesforce.com/docs/atlas.ja-jp.sso.meta/sso/sso_examples_canvas.htm

SAML SSO の設定もできるぽい


実装に関して

-  Salesforceに接続アプリケーションを追加
-  埋め込み側に [canvas-all.js](https://github.com/forcedotcom/SalesforceCanvasJavascriptSDK/blob/master/js/canvas-all.js)を追加
    -   SalesforceのAPIを実行したい場合は jsforce等を利用

# 次回

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

- Canvasのサイズを自動で変更する
- AuraでCanvasを使ってみる
- 埋め込みの親子間でイベントを送受信してみる
- jsforceでSalesforceのレコードを取得してみる

等本格的にSalesforce Canvasを使っていこうと思います。

# 参考

https://developer.salesforce.com/docs/atlas.ja-jp.sso.meta/sso/sso_examples_canvas.htm

https://github.com/forcedotcom/SalesforceCanvasJavascriptSDK/blob/master/js/canvas-all.js

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

https://qiita.com/NaokiIshimura/items/40ed08203b35aa0b527c

https://www.netlify.com/

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