こんにちは。CData Software Japan リードエンジニアの杉本です。
データレプリケーションツールのCData Sync ではジョブ完了時にメールで通知する機能が搭載されています。
www.cdata.com
cdn.cdata.com
しかしながら、昨今ではMS Teams や Slack といった社内チャットツール・コラボレーションツールに処理結果を通知してほしいという要望もあるのではないでしょうか。
実はCData Sync ではジョブの実行前もしくは完了時に様々な処理を追加することができるイベント機能というものがあります。

cdn.cdata.com
イベント機能は独自のXMLをカスタマイズすることで、ファイルの出力をしたり、APIリクエストを実行することができるようになっており、これを用いることで、外部のWebサービスに対して処理結果をリクエストすることができます。
cdn.cdata.com
そこで今回は Slack の Incoming Webhook の機能を使って、CData Sync の処理結果を Slack に通知する方法を紹介したいと思います。
Slack 側に Incoming Webhook のエンドポイントを準備する
まずは Slack 側のIncoming Webhook エンドポイントを準備しましょう。
対象のSlack チャネルにアクセスし右クリックから「チャネル詳細を開く」を選択します。

「インテグレーション」タブに移動して「アプリを追加する」をクリックし

一覧から「Incoming Webhook」を検索して「インストール」を行います。

「Slackに追加」をクリックし

利用規約などを確認した上で、任意のチャンネルにを選択し、「Incoming Webhook インテグレーションの追加」をクリックします。

すると以下のようにWebhook 用のURLが生成されるのでこれを控えておきます。

Sync に Post-Job イベントを追加する
Slack の Webhook URLを取得したら、そのURLを用いてPost-Job イベントのスクリプトを作成します。
cdn.cdata.com
APIリクエストは以下のようなイメージで実施します。Postman等でAPIリクエストを実行したことがあれば、馴染みやすい構文ではないでしょうか。
<api:set attr="http.url" value="http://mysite.com/log/"/>
<api:set attr="http.header:name#1" value="Token"/>
<api:set attr="http.header:value#1" value="MyToken"/>
<api:set attr="http.contenttype" value="application/json"/>
<api:set attr="http.postdata">
{
"JobName":"[_input.jobname]",
"Status":"[_input.JobStatus]
}
</api:set>
<api:call op="httpPost" in="http"/>
「http」という変数にそれぞれパラメータを設定して「httpPost」というオペレーションメソッドにその変数を渡すことで、APIリクエストが実行されます。
今回は私が簡単な雛形を作っているので、これを利用してみましょう。
「<api:set attr="http.url" value="https://hooks.slack.com/services/XXXXXX/XXXXXX/XXXXXXX"/> 」の部分だけ、作成したWebhook URLに差し替えてみてください。
<!-- NOTE: Do not edit api:info -->
<api:info title="After Run" desc="This event is fired after running a job.">
<input name="JobName" required="true" desc="The name of the job being executed." />
<input name="Source" required="true" desc="The name of source connection." />
<input name="Destination" required="true" desc="The name of destination connection." />
<input name="JobStatus" required="true" desc="The status of the completed run." />
<input name="Query#" required="true" desc="The hash of each query that ran." />
<input name="QueryStatus#" required="true" desc="The hash of the status of each query ran." />
</api:info>
<!-- NOTE: Slack Incoming Webhook URL -->
<api:set attr="http.url" value="https://hooks.slack.com/services/XXXXXX/XXXXXX/XXXXXXX"/>
<api:set attr="http.contenttype" value="application/json"/>
<api:set attr="_input.temp">
*Result*
</api:set>
<api:enum prefix="Query#">
<api:set attr="_input.temp">
[_input.temp]
- [_index | just(5)] : [_value] : [QueryStatus#[_index]]
</api:set>
</api:enum>
<api:set attr="text">
JobName: *[_input.jobname]*
JobStatus: *[_input.JobStatus]*
Source: *[_input.Source]*
Destination: *[_input.Destination]*
[temp]
</api:set>
<api:set attr="http.postdata">
{
"text":"[text]"
}
</api:set>
<api:call op="httpPost" in="http"/>
このScriptを対象のジョブの「Post-Job イベント」のところに貼り付けます。

設定を保存したら、試しにジョブを手動実行してみましょう。

ジョブが完了すると、以下のようにSlackにジョブの処理結果が通知されました!
それぞれのレプリケーション内容およびレプリケーション結果も表示できるので良いですね!

失敗の通知だけ行いたい場合(2021/10/13追記)
こちらの記事を公開した後に「失敗のときだけ通知したい場合はどうすればいいの?」という質問をお客様から頂きました。
スクリプトでは以下のようにIF文を使って、条件分岐を行うことができます。ここで「_input.JobStatus」の変数に格納されている処理結果を元に分岐して、失敗、つまり成功以外を通知させる設定にすることが可能です。
<api:if attr="_input.JobStatus" value="SUCCESS" operator="notequals">
(SUCCESSで無い場合)
</api:if>
スクリプトの全体像としては以下のようになります。もしスケジュールを細かく組んでいる場合はこちらのほうが良いかもですね。
<!-- NOTE: Do not edit api:info -->
<api:info title="After Run" desc="This event is fired after running a job.">
<input name="JobName" required="true" desc="The name of the job being executed." />
<input name="Source" required="true" desc="The name of source connection." />
<input name="Destination" required="true" desc="The name of destination connection." />
<input name="JobStatus" required="true" desc="The status of the completed run." />
<input name="Query#" required="true" desc="The hash of each query that ran." />
<input name="QueryStatus#" required="true" desc="The hash of the status of each query ran." />
</api:info>
<api:if attr="_input.JobStatus" value="SUCCESS" operator="notequals">
<!-- NOTE: Slack Incoming Webhook URL -->
<api:set attr="http.url" value="https://hooks.slack.com/services/XXXXXX/XXXXXX/XXXXXXX"/>
<api:set attr="http.contenttype" value="application/json"/>
<api:set attr="_input.temp">
*Result*
</api:set>
<api:enum prefix="Query#">
<api:set attr="_input.temp">
[_input.temp]
- [_index | just(5)] : [_value] : [QueryStatus#[_index]]
</api:set>
</api:enum>
<api:set attr="text">
JobName: *[_input.jobname]*
JobStatus: *[_input.JobStatus]*
Source: *[_input.Source]*
Destination: *[_input.Destination]*
[temp]
</api:set>
<api:set attr="http.postdata">
{
"text":"[text]"
}
</api:set>
<api:call op="httpPost" in="http"/>
</api:if>
おわりに
この仕組を利用することで、SlackだけでなくMS TeamsやChatworkなどにも通知することができます。
もし設定で不明な部分、よくわからない点があれば、テクニカルサポートまでお気軽にお問い合わせください。
https://jp.cdata.com/support/