Salesforce上のWebhookはどう作成するか。

# Webhookについて
## Webhookとは何でしょうか。

※既にWebhookご存知の方は、[SalesforceでのWebhook作成](#salesforce%E3%81%A7%E3%81%AEwebhook%E4%BD%9C%E6%88%90 "SalesforceでのWebhook作成")節をご覧ください。

まずはRedhatの[記事をお読み](https://www.redhat.com/en/topics/automation/what-is-a-webhook "")になってください。


クライアントはサーバーにある最新情報を取得することに例えます。

サーバーの最新情報を得るため、クライアント側は、サーバー側へHTTPリクエスト発信し続けて、最新状態を主動的にプール（ポーリングとも言います）します。しかし、最新情報を得るために、発信し続けなければならく、通信資源が消耗され、効率はよくありません。

一方、もしサーバー側で、最新情報があったら、クライアント側へ発信することが出来たら、情報更新されるたびに、サーバーから一回の発信で済みます。

一回の送受信で最新情報を得られようにすることは、サーバー側の発信は何等かのトリガーでロジックを組めばいいが、クライアント側は発信を受け取るための仕掛けが必要です。
このクライアント仕掛けはWebhookのことです。

上記の例は、クライアント/サーバーのS/Cパータンを例にしています。
API同士でWebhook利用していることが多くあります。

## SalesforceのWebhookは何が出来るでしょうか。

Salesforceは、外部ERPを皮切り、外部WMSや会計システムなど外部サービスといった外部システム連携することが多々あります。外部システムで提供したPackage（パッケージ）、APIなどを利用して、簡易に連携出来ますが、それ以外の外部システムと送受信することは、カスタム開発が必要になります。
WebhookはSalesforce上の受信触点となり、外部システムからの情報を取得します。


# SalesforceでのWebhook作成

## 制作過程
・新規Restful API作成
　受信するためのAPEXを実装

・新規Site作成
　外部からアクセス可能にする

・SiteにRestful APIを関連する

### 新規Restful API作成
通常のRestfulAPIの作成と同じです。
例にしているのが「Webhook_Tracking」クラスで、「tracking」というAPIです。
~~~
@RestResource(urlMapping = '/tracking/*')
global with sharing class Webhook_Tracking {
    @HttpPost
    global static ReturnMessage doPost(WebhookPaylod payload){
        return new ReturnMessage();
    }

    @HttpGet
    global static ReturnMessage doGet(){
        return new ReturnMessage();
    }
    
    global class WebhookPaylod{
        global String event_id;
        global String event_type;
        global String tracking_number;
        global String tracking_update_id;
        global String date_added;
        global String tracking_status;
    }


    global class ReturnMessage{
        global String msg{ get; set;}
        global Integer code {get; set;}
        global  ReturnMessage(){
            msg = 'Calling successed. But Nothing return';
            code = 401;
        }
    }
}
~~~


### 新規Site作成
・Setup→UserInteface→Sites and Domains→Sitesへアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873024/81a3f794-561e-2b2c-3a5a-8e5e4a934d35.png)

・新規作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873024/1e4916eb-b9ca-e75f-81e2-c743df3f9fcb.png)

・必須項目記入して、保存してください。
　Active Site Home Page項目は、任意のページでいいです。
　その他項目は、そのままでいいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873024/282fc4c8-3f0d-1c5d-28a2-33cb03528703.png)

・新規作成したSiteにアクセス
　例にしたのは「webhook」というSiteです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873024/d60160cb-2976-9267-14ef-dd9eff2196da.png)

### SiteにRestful APIを関連する
・SiteのPublic Acess Settingsをクリックして、Restful API のApexにアクセス権限を付与
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873024/49ebd3a2-00d2-c771-69a7-99e5bc384d30.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873024/5984cdec-660e-0d27-bb94-455858eb187e.png)

・SiteのActiveにすることを忘れなく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873024/2f972a4a-33b5-0323-e3f2-f2b5370631ad.png)

・疎通テスト
 ｛Domain Name｝/services/apexrest/{urlMapping}/へアクセスして、疎通確認。
 　APEXクラスのurlMappingは「tracking」なので、ここは｛Domain Name｝/services/apexrest/tracking/へアクセス
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873024/21abf695-f10a-fa49-167b-4145dc9b3d06.png)
結果は想定通りでした！　Webhook成功

# セキュリティについて

SalesforceのSiteはユーザーの認証不要で、アクセス可能のため、セキュリティ面に十分ご注意ください。
・SitesのPublic Acess Settingsは、いつも最小限度のアクセス権限付与すること
・リクエスト出来るIPアドレスを制限すること
・リクエストの内容に認証エレメントをいれて、リクエストを認証すること
などの措置で、Salesforceシステムの安全性を保ちましょう。