Salesforce→Slackに通知を送る
2019-10-17: Slack本家からとても使いやすいアプリが発表されました。
これはこれでとても使いやすく、ChatterではなくSlackとSalesforceとをシームレスに使えるできるのはとても良さそう。
然しながら今回はレコードの作成や更新の通知を確認したいなーと思うので、このプラグインの紹介はまた今度。
Salesforce and Slack: Unlocking collaboration for sales and service | The Official Slack Blog
https://slackhq.com/salesforce-and-slack-for-sales-and-service
目的
レコードの新規作成や更新の通知を受け取りたい。
また、全ての処理をコードで書くのではなくGUI上で変更することも可能にしたい。
あくまでコードを変更する回数を減らすという目的なので、内容によってはApexで書いた方が工数が掛からないケースも十分考えられます。
WIP:attachmentとかBlockで送る
構築
プロセスビルダーで送信する内容を記載・修正できるようにします。
1つApex Classを作成して、送信する内容は数式で生成します。
Salesforce to Slack Integration – Cloud Daemon
https://cloud-daemon.com/salesforce-slack-integration/
とても参考になりました、ありがとうございます。
Apex Classの作成(Sandbox環境で)
こんな感じのApex Classを作成します。
@InvocableVariable はプロセスビルダーから設定できる値になります。
@InvocableMethod はプロセスビルダーでApexを選択するときに表示されるものなので、わかりやすい名前にすると良いです。
public class PostToSlackWebhook {
public class slackRequest {
@InvocableVariable(label='webhookURL')
public String webhookURL;
@InvocableVariable(label='Channel/User to post to' required=true)
public String channel;
@InvocableVariable(label='icon_emoji')
public String iconEmoji;
@InvocableVariable(label='投稿者-姓' required=true)
public String postUserLastName;
@InvocableVariable(label='投稿者-名')
// 名はSalesforce側でrequiredではないため、属性は付与しない
public String postUserFirstName;
@InvocableVariable(label='Slack Text Message' required=true)
public String slackTextMessage;
}
@InvocableMethod(label='Post to Slack')
public static void publishToSlack(List<slackRequest> requests) {
for(slackRequest r:requests){
JSONGenerator gen = JSON.createGenerator(true);
gen.writeStartObject(); //Inserts {
if (r.postUserFirstName != null) {
gen.writeStringField('username', r.postUserLastName + ' ' + r.postUserFirstName );
} else {
gen.writeStringField('username', r.postUserLastName);
}
if (r.channel != null) {
gen.writeStringField('channel', r.channel);
}
if (r.iconEmoji != null) {
gen.writeStringField('icon_emoji', ':' + r.iconEmoji + ':');
}
if (r.slackTextMessage != null) {
gen.writeStringField('text', r.slackTextMessage);
}
gen.writeEndObject(); //Inserts }
if (r.webhookURL == null) {
r.webhookURL = 'https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/xxxxxxxxxxxxxxxxxxxxxxxx';
}
String body = gen.getAsString(); //Translates JSONGenerator to string to be passed to callout
System.debug(body);
System.enqueueJob(new qCallOut(r.webhookURL, 'POST', body));
}
}
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);
}
}
}
こちらはテストクラス。
@isTest
public class testPostToSlackWebhook{
static testmethod void testPublishToSlack(){
Test.setMock(HttpCalloutMock.class, new mockCallout());
List<PostToSlackWebhook.slackRequest> requests = new List<PostToSlackWebhook.slackRequest>();
PostToSlackWebhook.slackRequest r = new PostToSlackWebhook.slackRequest();
r.webhookURL = 'https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/xxxxxxxxxxxxxxxxxxxxxxxx';
r.channel='#general';
r.iconEmoji = 'v';
r.postUserLastName = 'APEX';
r.postUserFirstName = 'TEST';
r.slackTextMessage = 'THIS IS TEXT MESSAGE';
requests.add(r);
PostToSlackWebhook.publishToSlack(requests);
}
public class mockCallout implements HttpCalloutMock
{
public HttpResponse respond(HttpRequest request)
{
HttpResponse res = new HttpResponse();
res.setBody( '{"text":"value"}');
res.setStatusCode(200);
return res;
}
}
}
プロセスビルダー
新規作成や更新のときに通知を受け取りたいので、最終更新日時が更新されたときに発動するようにします。


アクションはApexクラスを選択、デフォルトで表示されるのは先程のApexクラスで
の属性を付与したものだけなので、@InvocableVariable(required=true)
required
になっていないものは “行を追加” から選択してください。

"New Lead" & BR() &
"https://xxxx.lightning.force.com/" & [Lead].Id & BR() &
BR() &
"状況: " & TEXT( [Lead].Status ) & BR() &
"会社名: " & [Lead].Company & BR() &
"氏名 " & [Lead].LastName & " " & [Lead].FirstName
通知する内容の URLはこれで生成
自サイトのURLはユーザに持っておくと便利じゃないかと思っている。
大抵はベタ打ちで大丈夫だろうけど…。
リモートサイトの設定
SlackのWebhook URLをリモートサイトとして有効にしておかないと、Salesforceから送信ができない。必ず忘れずに対応する。

確認
リードを新規作成・編集したときにSlackに通知が飛んで来ればよし。
飛んだ飛んだ。

良いSalesforce Success ライフを。
自サイトのURLはこの数式で取得できるそうです。
LEFT($Api.Partner_Server_URL_350 ,FIND("/services/Soap/", $Api.Partner_Server_URL_350)) + [Account].Id
絵文字アイコン生成はこちらのサイトが最強に便利です。
絵文字ジェネレーター – Slack 向け絵文字を無料で簡単生成
https://emoji-gen.ninja/