S.B.S. Salesforce技術ブログ

教えて921さん!

レコードの情報をslackに投稿する

こんにちはyumotoです。

任意のタイミングでボタンを押し、
salesforceのレコードの情報を、slackに投稿するプログラムを作成しました。
ライセンスなどの問題でSalesforceアカウントを持っていない人にレコードの情報を連携する際などに役立ちそうです。

作業の大まかな流れ

1, slack側でwebhookURLを取得
2, salesforceでリモートサイトを設定
3, apexを作成
4, apexを呼び出すVisualforceページを作成
5, slackに連携するためのボタンを作成

Slack側の準備

1.ワークスペースの[設定と管理]から[アプリを管理する]を選択
2.画面上部の検索画面で「Incoming webhook」と検索し下画像のアプリをSlackに追加
f:id:sbsSF:20210422142332p:plain

3.任意のチャンネルを選択して[Incoming Webhookインテグレーションの追加]を選択
   Slackに追加した際に選択するチャンネルはなんでも大丈夫です。
   後に投稿するチャンネルをsalesforce側で選択するように変更できます。
   ここでは#generalとか選んでおけば大丈夫です。 f:id:sbsSF:20210422143732p:plain

4.Incoming Webhookの設定画面にあるwebhookURLをコピーします。
    このURLは外部へ公開しないように注意!!! f:id:sbsSF:20210422144348p:plain

以上でSlack側の設定は終了です。

Salesforce側の設定

1.リモートサイトの設定
salesforceの設定画面、クイック検索で「リモートサイト」と検索
表示された[リモートサイトの設定]を選択

2.[新規リモートサイト]をクリックし以下のように設定

リモートサイト名 SlackAPI
リモートサイトのURL https://hooks.slack.com
説明 任意

3.Apexクラスの作成
今回は取引先の情報をSlackに送る前提で作成します。
以下のコードでApexクラスを作成します。
Apexの名前は後述のVisualforceとの兼ね合いもありますが、今回は「publishToSlackAccount」で作成しました。

解説

・getAccountメソッドでSlackに送る取引先の項目を拾ってきています。
・generateMessageメソッドでSlackに送るメッセージを作成しています。
・publishToSlackメソッドのwebhookURLの変数に先ほどslack側からコピーしてきたwebhookURLを貼り付けます。
 また、 sR.channel の変数がslackのチャンネルを指定する変数です。
例えばチャンネルを指定する選択リストなどを作り、
ここにその値を入れてあげることによって、
salesforce側から投稿するslackチャンネルを指定することもできます。

public class publishToSlackAccount{
    public Account acc{get;set;}
    public List<slackRequest> requests = new List<slackRequest>();
    
    public publishToSlackAccount(ApexPages.StandardController stdController){
        acc = (Account)stdController.getRecord();
        acc = getAccount(acc.id);
    }
    
    private Account getAccount(ID id){
        Account rtnAcc = [   SELECT  id
                          ,Name
                          ,BillingCountry
                          ,BillingState
                          ,BillingCity
                          ,BillingStreet
                          ,Phone
                          ,Rating
                          FROM    Account
                          WHERE   id =:id
                          
                         ];
        return rtnAcc;
    }
    
    private String generateMessage(){
        String rtnMessage = '';
        
        rtnMessage += '(サンプルメッセージ)\n新たな取引先が登録されました。\n';
        
        //取引先名
        rtnMessage += '《取引先名》:' + acc.Name;
        rtnMessage += '\n';
        
        //住所
        rtnMessage += '《 住所 》:';
        rtnMessage += acc.BillingCountry;
        rtnMessage += acc.BillingState;
        rtnMessage += acc.BillingCity;
        rtnMessage += acc.BillingStreet;
        rtnMessage += '\n';
        
        //電話
        rtnMessage += '《 電話 》:';
        rtnMessage += acc.phone;
        rtnMessage += '\n';
        
        //評価
        rtnMessage += '《 評価 》:';
        rtnMessage += acc.Rating;
        rtnMessage += '\n';
        
        return rtnMessage;
    }
    
    public class slackRequest {
        public String slackMessage{get;set;}
        public String channel{get;set;}
    }
    
    public PageReference publishToSlack() {
        List<slackRequest> requests = new List<slackRequest>();
        slackRequest sR = new slackRequest();
        sR.slackMessage = generateMessage();
        sR.channel = '#取引先';
        
        requests.add(sR);
        
        String webhookURL='----------------------------------------------------'; //ここに先ほどコピーしたwebhookURLを張り付け
        for(slackRequest r:requests){
            JSONGenerator gen = JSON.createGenerator(true);
            gen.writeStartObject(); //Inserts {
            gen.writeStringField('text', r.slackMessage);
            gen.writeStringField('channel', r.channel);
            gen.writeStringField('username', 'Salesforce Bot');
            gen.writeStringField('icon_emoji', ':monkey_face:');
            gen.writeEndObject(); //Inserts }
            
            String body = gen.getAsString(); //Translates JSONGenerator to string to be passed to callout
            System.debug(body);
            System.enqueueJob(new qCallOut(webhookURL, 'POST', body));
        }
        
        //取引先情報へ戻す
        PageReference pr = new ApexPages.StandardController(acc).view();
        pr.setRedirect(true);
        return pr;
        
        
    }
    
    public class qCallOut implements System.Queueable, Database.AllowsCallouts {
        
        private final String url;
        private final String method;
        private final String body;
        
        public qCallOut(String url, String method, String body) {
            this.url = url;
            this.method = method;
            this.body = body;
        }
        
        public void execute(System.QueueableContext ctx) {
            HttpRequest req = new HttpRequest();
            req.setEndpoint(url);
            req.setMethod(method);
            req.setBody(body);
            Http http = new Http();
            HttpResponse res = http.send(req);
        }
    }
}

4.取引先オブジェクトで上記apexを起動するためのvisualforceページを作成
salesforce設定画面のクイック検索で「visual」と検索、表示された[Visualforce ページ]をクリック

5.[新規]ボタンをクリックし、visualforceページを作成。
  表示ラベルと名前は任意で構いません。
  今回は取引先の情報をSlackに送るので以下画像のように設定しました。 f:id:sbsSF:20210422180123p:plain

visualforceのソースコードは以下です。

<apex:page standardController="Account" extensions="publishToSlackAccount" action="{!publishToSlack}">
</apex:page>

VF側からactionで先のapexを呼び出すだけなので、こちらはシンプルです。

6.VFを呼び出すボタンを作成
オブジェクトマネージャから[取引先]を選択
左部メニューの[ボタン、リンク、およびアクション]を選択
右上の[新規ボタンまたはリンク]を選択
以下画像のように設定します。 f:id:sbsSF:20210422180905p:plain

7.ページレイアウトに6番で作成したボタンを配置 f:id:sbsSF:20210422181139p:plain

実行結果

取引先のボタンを押下するとSlackに投稿されます。
以下画像の取引先情報をSlackに投稿してみます。 f:id:sbsSF:20210422181321p:plain

Slack側 f:id:sbsSF:20210422181903p:plain

まとめ

プログラムをいろいろいじることによって、タイミングや投稿するチャンネル、文章等変更できます。

是非活用してください。