最近Microsoftから新サービスとして、MicrosoftFlowとMicrosoftTeamsが法人向けのOffice365ユーザーを対象にプレビューとして公開されました。
どちらも面白そうだったのですが、なぜかFlowとTeamsが連携する口が存在していなかったので、
試しに無理やり連携してみました。結構ハマったのでログとして残しておきます。
概要
SlackのOutboundsMessageを利用してMicrosoftFlowへ通知を行い、MicrosoftFlowからMicrosoftTeamsのInboudsMessageへの通知を行います。イメージ的にはこんな感じになります。
TODO あとで絵を貼る
動機
ウチの会社はセキュリティ上の問題でSlackを業務で利用することができないという微妙な会社セキュリティが非常に堅牢な会社となっておりますが、MS製品はなぜか許容されるケースが多いのでMicrosoftTeamsの導入を狙ってたりします。
書かないこと
- MicrosoftTeamsのサインアップ方法&有効化
(ただ、 URLがわからなくてすごく苦労したことは主張しておきたい!! => https://teams.microsoft.com/が実際のURLです) - MicrosoftFlowのサインアップ方法&初期設定
- Slackのサインアップ方法&初期設定
手順
以下の手順で構築します。1-5までは簡単です。
- MicrosoftFlowでフロー(トリガー)を設定
- SlackのOutBoudsMessageを設定
- MicrosoftTeamsのInBoundMessageを設定
- MicrosoftFlowでフロー(アクション)を設定
- 疎通確認
- MicrosoftFlowでデータの加工
1. MicrosoftFlowsでフロー(トリガー)を設定
- Microsoft Flowにサインイン
- ヘッダーにある自分のフローを選択
- 一から作成をクリック(なんで『一』という漢字なんだろう...)
- 適当なフロー名をつける
- 検索ボックスに要求と入力して合致したトリガーを追加
- +新しいステップ => アクションの追加から応答と入力しアクションを追加。
- 一度保存しないとURLが生成されないので一旦フローの作成で保存する。
- 要求で新規URLが構築されるのでコピーしておく

※5.のタイミングで保存しようとしてもトリガーとアクションが少なくとも 1 つずつ必要です
と警告が出て保存できない。
2. SlackのOutBoudsMessageを設定
SlackのIntegration機能であるOutgoing Webhooksを利用して
Slack上への投稿をトリガーにMicrosoftFlowに対して通知を行います。
1.Outgoing WebHooksのAdd Configurationから、Add Outgoing WebHooks integrationを選択する。
2.Integration Settingsを以下のように設定する
key | value |
---|---|
Channel | 監視したい任意のchannel |
Trigger Word(s) | 全て処理したいので入力しない |
URL(s) | 1-8.でコピーしたURLを設定する |
3.Save Settingsを押して保存 | |
4.2.のChannelで設定したtimelineにadded an integration to this channel: outgoing-webhookと表示されることを確認。 |
3. MicrosoftTeamsのInBoundMessageを設定
- MicrosoftTeamsにログインして任意のチームを開き、**一般の横にある...**をクリックし、コネクタを選択
- Incoming WebHookの追加をクリック
- 任意の名前を入力して作成をクリック
- **https://outlook.office365.com/webhook/XXXXXXXXXX...**的なURLが生成されるのでコピーする
4. MicrosoftFlowsでフロー(アクション)を設定
1.再度Microsoft Flowへ。
2.自分のフローから先ほど作成したフローを選択
3.+新しいステップからアクションの追加を選択
4.HTTPを選び以下の様に設定する
key | value |
---|---|
方法 | POST |
URI | 3-4でコピーしたURL |
ヘッダー | 空(何も設定しない) |
本文 | { "text": "hello" } |
5.D&Dで作成したHTTPを移動して、要求 => HTTP => 応答という形に移動する |

5. 疎通確認
これで接続まではできるはずなので、疎通確認を行う。
2-2.で設定したchannelで任意のコメントを入力した場合に、実行の一覧表示にログが表示され、3-1で選択した、フロー上にHelloと表示されていればOK
6. MicrosoftFlowで詳細設定を行います。
さて、ここからが本題です。
Slackのoutgoing-webhookはJSON形式になっておりbase64でエンコードされたパラメーターを渡してくれるのですが、
これをMicrosoftFlow上で加工した上でMicrosoftTeamsに投げる必要があります。
6-1. POSTの内容をJSONスキーマでマッピングする
まずは、要求を編集して要求本文のJSONスキーマを設定します。
ここのフォーマットはJSON Schema形式で定義することでプロパティをActionの引数として利用可能になります。Slackのoutgoing-webhookを受け取りたい場合はこんな形で定義します。
{
"properties": {
"$content": {
"type": "string"
}
},
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"required": [
"$content"
]
}
こうすることで、動的なコンテンツとして$contentが利用可能になります。
6-2. マッピングされたデータの解析と加工
次に**+新しいステップから作成**を選択し$contentをHTTPで送信する形に加工します。
加工する際はWorkflowDefinitionLanguageとして簡易的なfunctionがいくつか提供されていますので、これらの関数を利用することが可能です。
(かなり限定的なfunctionしかありませんが...)。
今回はtext=xxxx
という値を取得するために、以下のように入力を設定しました。
"@{decodeUriComponent(json(concat('{"', replace(replace(decodeBase64(triggerBody()['$content']), '=', '":"'), '&', '","'), '"}')).text)}"
かなり無茶してるのでざっと分解しておきます。
@{
# 5. encodeURIComponentされているので、戻します。
decodeUriComponent(
# 4. json化した上でドットオペレーターを通してtext文字列を取得します。
json(
# 3. key=value&key2=valueの形式を無理やりjsonにするためにreplaceをかけています。
# `=`を`:`に、`&`を`=`にした上で、`{}`を付与してJSONでparseできる文字列に変換します。
concat(
'{"',
replace(
replace(
# 2. $contentがbase64でencodeされているのでdecodeします
decodeBase64(
# 1. 要求$contentを指します。動的コンテンツから追加した場合にfunctionを組み合わせるとエラーになるので直接書いています。
triggerBody()['$content']
),
'=',
'":"'
),
'&',
'","'
),
'"}'
)
).text
)
}
6-3. 加工されたデータをHTTPで送信する
HTTPの本文を以下のように設定します。
保存するとわかりますが、{ "text": "@outputs('作成')" }
に実際は置換されます。
これでtext本文をMicrosoftTeamに送信可能になります。
今回はテキストだけ送っていますが、いろいろサポートしていて結構リッチなメッセージも送れます。
結果的にはこんな感じのワークフローになりました。

オチ
まぁ、そのうち公式にFlowがSlackを受け取れるようになるか、
TeamsがSlackの通知を受け取れるようになるでしょう(というかしてください)。
はまったところ
保存したFlowが消える
上記のように長めの関数を書いたところ、フローを保存した後に**"**だけしか残らないという悲しい目にあいました。コマンド自体は正しく動いてはいるのですが。。。作成で入力をする前に一旦ローカルにバックアップを取る事を強くお勧めします。
リファレンスどこ
参考サイトを参考にしてください。Workflow Definition Languageが一番参考になります(大枠を理解していれば)
あとで書く
* 作成したHTTP本文が消せなくなる
* デバッグ方法