こんな人向けの記事です
オンプレから、何かの情報をSharePointリストなどのMicrosoft 365のクラウド側へ値を渡したいけれど、OneDriveアプリも、PnP Onlineも、サービスプリンシパルもSharePoint APIも塞がれているような方向けの、選択肢のひとつとして書いてみています。
BlobストレージならAzcopyコマンドをSASで使うような方法があるのですが、SPOに値を持っていくってハードル高くないですか?
TeamsのIncomming Webhookって使えなくなるらしい
なんか最近この話題が出ていて、いろいろなシステムからTeamsのチャネルへ投稿させるのに使われていたInComming Webhookが使えなくなり、代替手段としてWorkflowを使いましょうということになっているようです。
まず、これまでの方法からおさらいします。まだIncomming Webhookは消えていません。
新しいTeamsから従来のIncomming Webhookを使う場合は、チャネルの3点リーダーから「チャネルを管理」を開き、コネクタの項目にある「編集」を開きます。
ここに表示されているのが話題のIncomming Webhookです。
これからはWorkflowをつかう
今後のお作法はワークフローをつかうこと。チャネルの3点リーダーから「ワークフロー」をクリックします。
中央あたりに「Webhook要求を受信するとチャネルに投稿する」を選択します。
フローに適当な名前をつけて「次へ」進みます。
すると、Webhook用のURLが発行されました。「変更を行いますか?ワークフローを管理する」の部分にリンクがあるので開いてみます。
Teams内ですが自動で作成されたクラウドフローが見えました。ちなみに、ふつうに https://make.powerautomate.com からもここで作成されたクラウドフローは開くことができます。クラウドフローは規定の環境に保存されていました。「編集」をクリックしてみます。
中身を見ると、先ほどのURLが変更できない状態で「When a Teams webhook request is received」トリガーに設定されています。その中身をアダプティブカードでチャネルに投稿するというシンプルな仕組みです。
POSTMANを使って、先ほどのURLにメッセージをPOSTしてみます。
POSTMANはMicrosoftのLearnでも紹介されているツールで、インストール版もWEB版もあり、Googleアカウントなどで簡単にサインインできます。 URLを入れてSendするだけなのですが、POSTも送信したい情報をBodyにペタリ。ヘッダーも枠に入力したり変数使えたり。おまけに主要な言語やスクリプトの場合はどう書けば良いのか、テストした結果を簡単にコピーして使えるという神仕様。日本語もエンコード処理せずにつかえるので使って損なしです。 始めてでしたらこちらが参考になりそうです。
Teams Webhookに対して、どんな本文を送れば良いかは、こちらのLearnに書いてありますので覗いてみましょう。
Learnのページの、Exampleに書かれているJSON文字列をそのままコピーしておきます。
先ほどのURLに対して、BodyにJSONをぺたりと貼り付けて、POSTに切り替えた状態で「Send」をクリックしてみます。
URLに対して投稿されると、クラウドフローがトリガーされ、JSONの内容が後続のアダプティブカード投稿に渡されて処理が成功しました。
結果として、チームのチャネルにJSONで送った内容がアダプティブカードとして表示されました。なるほど。これがWebhook! 便利そうですね。
さて、ここからが本題
決まった形のJSONを送信してやると、アダプティブカードに投稿できることはわかったけれど、JSONなら何でも送信できるんじゃない? と思ったので実験します。アダプティブカードの処理部分を削除して「作成」アクションをおき、トリガーの本文が表示できるようにしました。
Bodyには以下のとおり。送信してみると、202 Accepted!!ですやん。受け付けられました。
{"text":"はろーわーるど"}
というわけで、POSTMANで試したことをコマンドにするとこんな感じ。いずれでも投稿できました。
wget --no-check-certificate --quiet \
--method POST \
--timeout=0 \
--header 'Content-Type: application/json' \
--body-data '{"text":"はろーわーるど"}' \
'https://取得したURL'
curl --location 'https://取得したURL' \
--header 'Content-Type: application/json' \
--data '{"text":"はろーわーるど"}'
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Type", "application/json")
$body = @"
{`"text`":`"はろーわーるど`"}
"@
Invoke-RestMethod 'https://取得したURL' -Method 'POST' -Headers $headers -Body $body
値を渡せるということは、SharePointリストにだって
Teamsの機能としてのWebhookを借用して、値をアダプティブカードではなくてSharePointリストにだって渡せるでしょう?ということでやってみましょう。
トリガーのBodyをSharePointリストに渡します。動的な選択肢にはでてこなかったので、以下のように式を設定してください。
triggerBody()?['text']
SharePointリストに、PowerShellから投稿することができました!
ところで、MACでPowerShell使えるんですね。
普段はあまり使ってないのですが、たまたまこの記事はMacを使って書いていたので、いけねっ! PowerShellつかえないやん! と思ったのですが。
HomeBrewを使ってMacにもPowerShellを簡単にインストールできました。CurlもWgetでも、コマンドひとつで簡単インストール。
Homebrewってすごいですね。
Anyoneを避けるには?
すでにお気づきでしょうが、WebhookはURLさえ知っていればそこにPOSTするだけで受信してしまいます。
テナントのユーザー、特定のユーザーというトリガーの指定ができるのですが、POSTのヘッダーに Graph Explorerから取得したトークンを、Authorization: Bearer hogehoge をつけてみてもうまく認証できませんでした。
このあたり方法をご存知でしたら是非教えていただきたいです。
Webhookを使う時の注意点
こんなに簡単に渡せて良いのかしら? と素人ながら思います。やっぱり認証は必要ですよね。
Webhookを使う場合のベストプラクティスがこちらの記事で触れられていました。認証。どうやったらいいんだろう?