【UiPath】WebhookでSlack／Teamsにメッセージを投稿する

# はじめに

この投稿は、RPAツール「UiPath」で Slack や Teams に Incoming Webhooksでメッセージ投稿する方法 についての記事です。

# マーケットプレイス

今回紹介するコードは、UiPath MarketPlaceで公開中です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/dc388de6-e421-fa56-85a1-80e1cf66b1cb.png)

https://marketplace.uipath.com/listings/2858

# どういう時に使うか

例えば、以下のようなケースでロボットからチャットツールにメッセージを投稿したい時があります。

- 実行開始、終了、処理エラーを早く知りたい
- 処理がどこまで進んだかの状況確認を報告してほしい
- 実行記録をチャンネルに残しておきたい

メールやログで通知しても良いですが、チャットで通知が出来れば「**チャンネルを見れば状況が把握できる**」ので便利です。

チャットツールの場合「通知On」にしていれば新着メッセージをすぐに確認できるというメリットもあります。


# Incoming Webhookとは

Incoming Webhook は「特定チャンネルにAPI経由でメッセージを送る」シンプルな仕組みです。特徴として

- チャンネルに対して「投稿専用のURL」を用意する
- URLにメッセージを送信すると、そのチャンネルにメッセージが投稿される
- 認証がいらない。アクセス権限も考えなくて良い
- URLが部外者にバレたら、イタズラ投稿されるリスクはある
- が、URLはワンクリックで無効化・再発行できるので大丈夫

などがあります。

![tsチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/bdbf687d-1d19-2846-b110-26cc54877a02.png)

（botとして対話形式で使用するなら「アプリ登録して認証してスコープ設定して」という手順が必要ですが）
単純に「メッセージ投稿をするだけ」なら、Incoming Webhookの方が手軽です。

※ 2021年4月現在、UiPathマーケットにはこの「Incoming Webhook」でのメッセージ投稿のコンポーネントがありませんでした。（見つからなかっただけ？）

# Incoming WebhookのURLを発行する

わかりやすく手順を紹介されているブログが既にあるので、ここでは記事の紹介をしておきます。

Slackはこの辺を参考にすると良さそうです。

https://qiita.com/kshibata101/items/0e13c420080a993c5d16

Teamsはこちらが良さそうです。

https://mokudai.jp/knowledge-base/power-automate/post-to-teams-using-webhook/

# UiPathからTeamsにメッセージを送信

Teamsのメッセージ形式に従ってJsonを作成し、取得した「Incoming WebhookのURL」へHttpリクエストを送信します。

　`「代入」アクティビティでJson文字列を作成 ⇒ 「HTTP 要求」アクティビティを使用して送信`

でも出来ますが、「**コードを呼び出し (Invoke Code)**」アクティビティで一気に実施するほうが、シンプルです。


以下は **VB.Net** で「teams」にメッセージ送信するサンプルコードです。
UiPathの「コードを呼び出し (Invoke Code)」アクティビティに貼り付ければ、メッセージ送信できます。

``` VB
Try
    Dim inurl As String = "https://***（取得したIncoming WebhookのURL）***"
    Dim payLoad As String = String.Format(
        "{{""@type"": ""MessageCard""," & _
          """@context"": ""https://schema.org/extensions""," & 
          """summary"": ""{0}""," & 
          """themeColor"": ""0000ff""," &
          """title"": ""{0}""," & 
          """sections"": [{{""text"": ""{1}""}}]" & 
        "}}",
        "処理完了のお知らせ", 
        "Bot が正常に実行されました。+☆+☆+[◎□◎]+☆+☆+")
    Dim wc As New Net.WebClient
    wc.Encoding = System.Text.Encoding.UTF8
    wc.Headers.Add("Content-Type", "application/json")
    Console.WriteLine("[request] " & payLoad)
    Dim res As String = wc.UploadString(inurl, payLoad)
    Console.WriteLine("[response] " & res )
Catch ex As Exception
    Console.WriteLine("[error] " & ex.Message)
End Try
```

実行すると、以下のように投稿されます。
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/ff19ff43-5d65-1aea-166d-6b09e84c13cc.png)

Json文字列をカスタマイズすれば、メッセージのレイアウトを変えられます。詳しくはこちら。

https://messagecardplayground.azurewebsites.net/

実行しやすいように、xaml形式に切り出したものを用意しました。

https://github.com/miyag/UiPath.ReusableCode/blob/master/PostMessage/PostTeamsMessage.xaml

処理フローはこんな感じです。
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/e73e4642-7e58-9040-8dfc-7291b6f5da98.png)
タイトルとテキストを指定し、実行すると以下のように投稿されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/d3c5d195-ed92-71f8-6570-c15177bf9956.png)
※ メッセージアイコンと表示名を変更しています。（Teamsの「Incoming Webhook」設定画面で指定）
※ 下部に「いつ？どこで？何のフローが？」を記載しています。


# UiPathからSlackにメッセージを送信

（teamsと同じく）
slackのメッセージ形式に従ってJsonを作成し、取得した「Incoming WebhookのURL」へHttpリクエストを送信します。

以下はVB.Netで「slack」にメッセージ送信するサンプルコードです。
「コードを呼び出し (Invoke Code)」アクティビティに貼り付けてそのまま実行できます。

``` VB
Try
    Dim inurl As String = "https://***（取得したIncoming WebhookのURL）***"
    '// attachments形式
    Dim payLoad As String = String.Format(
        "{{""attachments"":[" & 
              "{{""title"":""{0}"","  &
                 """text"":""{1}"","  &
                """color"":""#0000ff""}}" &
        "]}}", 
        "処理完了のお知らせ", 
        "Bot が正常に実行されました。+☆+☆+[◎□◎]+☆+☆+")
    Dim wc As New Net.WebClient
    wc.Encoding = System.Text.Encoding.UTF8
	wc.Headers.Add("Content-Type", "application/json")
	Console.WriteLine("[request] " & payLoad)
    Dim res As String = wc.UploadString(inurl, payLoad)
	Console.WriteLine("[response] " & res)
Catch ex As Exception
    Console.WriteLine("[error] " & ex.Message)
End Try
```

実行すると、以下のように投稿されます。
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/4d00e632-936a-bbf4-d437-92c045291db9.png)
slackのメッセージフォーマットは「Attachment方式」と「Block Kit方式」の2つがあります。
「Block Kit方式」の場合は以下のようにJsonを組み立てます。

```VB
    '// block Kit形式
    Dim payLoad As String = String.Format(
        "{{""blocks"":[" & 
            "{{""type"": ""header"", ""text"": {{""type"": ""plain_text"", ""text"": ""{0}""}}}}," & 
            "{{""type"": ""section"", ""text"": {{""type"": ""plain_text"", ""text"": ""{1}""}}}}" & 
        "]}}", 
        "処理完了のお知らせ", 
        "Bot が正常に実行されました。+☆+☆+[◎□◎]+☆+☆+")
```

Json文字列をカスタマイズすれば、メッセージのレイアウトを変えられます。詳しくはこちら。

https://api.slack.com/messaging/composing/layouts#building-attachments

https://api.slack.com/block-kit

実行しやすいように、xaml形式に切り出したものを用意しました。

https://github.com/miyag/UiPath.ReusableCode/blob/master/PostMessage/PostSlackMessage.xaml

処理フローはこんな感じです。
![sflow2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/310aff8d-e56c-8ca0-53c5-28d258f43ae5.png)

タイトルとテキストを指定し、実行すると以下のように投稿されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/7bf7be3e-3800-a29e-c711-a887b4915581.png)
※ メッセージアイコンと表示名を変更しています。（Teamsの「Incoming Webhook」設定画面で指定）
※ 下部に「いつ？どこで？何のフローが？」を記載しています。


# 投稿エラー

メッセージの内容によっては、以下のエラーが出ることがあります

```
 リモート サーバーがエラーを返しました: (400) 要求が不適切です
```

投稿メッセージは「Json」形式で送信しますが、メッセージの中に「Jsonで使用できない＝エスケープが必要な文字」が入っている可能性があります。

送信前にメッセージを以下のように変換しておくことをお勧めします。

```
    in_title = in_title.Replace("\", "\\").Replace("""", "\""")
    in_text = in_text.Replace("\", "\\").Replace("""", "\""")
```



# おわりに

いかがでしたでしょうか。
teamsやslackにロボットから通知が出来ると、ロボットと対話している感じが出て、開発も実行も楽しくなります。ぜひ試してみてください。


この記事が参考になったら、 LGTMをお願いします。閲覧ありがとうございました。