最近 Salesforce を導入しましたが、
業務に関する各種通知をSlackで行っているため Salesforce から Slack 通知するまで、右も左もわからない状態からなんとかできました。
今では通知する種類も増え、構造は違っていますが(Webhook使ってないなど)参考にはなると思います。
基本的にここを参考にしています。
sandbox環境を作成
Salesforce上でなにか処理を行うにはApexという言語で記述する必要があります。
しかし、本番環境では新規にApexクラスを追加できません。
Sandbox環境を作り、そこに追加したApexクラスを本番にDeployという形で本番に適用する必要があります。
設定のクイック検索で sandbox
と検索します。
環境 -> sandbox という感じのメニューになるので、選択するとsandboxの一覧が確認できます。
すでにdevelopというものを作ってしまっていますが、新規sandboxから新しいものも作れます。
基本的に動作確認などはSandbox環境で行います。
Slack通知カスタムオブジェクトの作成
WebhookでのSlack通知用のオブジェクトを作成します。
オブジェクトマネージャ から作ります。
こんな感じのものを作りました。
URLがあるのは2種類の鹿島さんが存在する(請求情報変更・請求の確定通知)ので持たせています。
Webhookに渡す内容が { "text": "~~~~~"}
という感じなので、Textも用意しています。
__c
が気になりますか?僕はもう気にならなくなりました。
セキュリティ設定
今回は外部に通信を行うのでそういった設定が必要になります。
クイック検索に リモートサイト
と入力して リモートサイト設定
を行います。
こんな感じで設定しています。
これをしないと外部に接続できないので注意しましょう。
Slack送信部分の実装
クイック検索に「Apex」と入力すると
こんな感じになります。
「Apexクラス」から上記のような画面になりますので「新規」ボタンを押してください。
ここでコードがかけるようになります。
Javaではないことは確かなので、Javaのことは忘れてください。
Simpleが至高だと教えてくれるエディタです。
素直にVSCodeなど他のエディタで書いて上記エディタに貼り付けましょう。
今回はここで行っていますが、VSCodeにはSalesforce用の拡張があってVSCode上でSandboxにクラスを追加できると思います。(たぶん)
webhookたたく
外部へHttpリクエストを送る処理が含まれている場合 future
アノテーションが必要になります。
@future(callout=true)
private static void send(String endpoint, String message) {
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setEndpoint(endpoint);
request.setMethod('POST');
request.setHeader('Content-Type', 'application/json');
request.setBody(message);
HttpResponse response = http.send(request);
}
こんな感じ。
詰まったところ
親がとれない
たとえば請求を持つ案件の名前を取得したい場合、オブジェクトマネージャでの請求オブジェクトの案件項目は anken__c
となっているとします。
ただし、子から親の項目を参照する際は anken__r
になるそうです。
末尾の __c
が __r
となっています。
それでも親がとれない
次の項目のトリガにも関わりますが、トリガ上で対象レコードを取るのに Trigger
クラスを使います。
Trigger.new
などが対象のレコードのリストを返すのですが
for (seikyu__c seikyu : Trigger.new) {
String ankenName = seikyu.anken__r.Name;
}
これで ankenName
が null
になります。
for (seikyu__c seikyu : [SELECT anken__r.Name FROM seikyu__c WHERE Id IN :Trigger.new]) {
String ankenName = seikyu.anken__r.Name;
}
こうやって関連項目にアクセスするにはDBから取る必要があるようです。
癖が強い。
トリガの設定
オブジェクトマネージャ -> 対象のオブジェクト -> トリガから設定できます。
ここで追加しているはそれぞれ削除・追加・更新です。
ここで請求が追加されると、通知用のメッセージを追加するということを行っています。
エディタの上にある is_active
のチェックが外れていると思いますが、**新規作成の場合はデフォルトはONで、更新の場合はデフォルトがOFFです。**気をつけましょう。
ここのチェックが外れていると、トリガが実行されません。
Apex トリガから一覧で確認できます。
請求のトリガでは、各種変更に合わせてSlackMessageレコードを追加するというトリガになっています。
実際に通知を行っているのはSlackMessageの after insert
トリガで通知しています。
送信変更セットの作成
クイック検索に 変更セット
と入力すると 送信変更セット
が出てきます。
そこで今回の変更で本番に適用するものを定義します。
こんな感じに作れました。
セキュリティ設定が含まれていませんが、この時は気づいていなかっただけでよく探せばありました。
リリース設定
本番環境側で、どのsandboxから変更を受け取るか設定します。
これはsandboxを作ったタイミングで実施するもので、同じsandboxを使い回すのであれば基本は設定しなおす必要はないと思います。
こんな感じで設定しています。
送信変更セットのアップロード
送信変更セットの一覧から対象を選択し アップロード
を押します。
アップロードを押せば変更が適用されるはずです。
受信変更セットの適用
送信変更セットでアップロードが完了すると受信変更セットからリリースを実行できます。
リリースからポチポチ進んでいくと…
おめでとうございます!
ちゃんとテストコードを書きましょう!
実際送信部分はテストコードを書いていましたが、HTTP通信をともなうクラスはテスト不可と出て先に進めませんでした。
どうやら特別な手順が必要なようです。
コールアウトのMock
HttpCalloutMock#respond
を実装したクラスをモックとして用います。
@isTest
global class SlackWebhookResponseGenerator implements HttpCalloutMock {
global HTTPResponse respond(HTTPRequest request) {
String webhookUrlPrefix = 'https://hooks.slack.com/services';
HttpResponse response = new HttpResponse();
response.setHeader('Content-Type', 'application/json');
response.setStatusCode(200);
// WebhookのMock
if (request.getEndpoint().startsWith(webhookUrlPrefix)) {
response.setBody('{ "ok": true }');
}
return response;
}
}
こんな感じで書いています。
これをテストメソッドで使えと宣言します。
Test.setMock(HttpCalloutMock.class, new SlackWebhookResponseGenerator());
これはメソッド内で宣言しますので、コールアウト単位でモックを作ることができますが、面倒なので今回は1つで使いまわしています。
単体テストの実装
クラスを作成し @isTest
アノテーションをクラスとメソッドそれぞれに追加します。
テスト中はテスト用のDBを参照しているらしく、データ取得は基本的にテスト中に追加したデータしか参照できません。
これは実際 sandbox で動かしたあと、本番環境でもテストコードが実行されるのでどちらでも動くコードでないと駄目という事だと思います。
いやまあ普通に考えたらそうですよね。
ただしユーザデータなど、本番とSandboxで微妙に違ったりするのでテストで使うデータはすべてテストコード内で作ったほうが確実です。
トリガの単体テストコード
コードカバー率75%以上無いとリリースはできませんが、トリガのコードが0%でもリリースは失敗します。
トリガが発生するケースは必ず網羅する必要があります。
テストの実行とコードカバー率の確認
Apexテスト実行の「テストを選択」から、アノテーションをつけたクラスを選択できますので、そこから実行できます。
こんな感じで割と見やすいかと思いきやStackTraceがめちゃくちゃ見づらいですが、かわいいもんです。
コードカバー率は Apexクラス の 組織のコードカバー率を見積る リンクから見ることができます。
ドヤァ…
リリース!
あとは同じように 本番環境 の 受信変更セット からリリースを選択して見守ります。
無事にSalesforceでの更新情報などをSlackで通知できるようになりました。