みなさん、こんにちは。仕事を行う中、定型文のような固定連絡を送ったこと、ありますか? もはやコピペのような文章でも、その度に少し編集しては投稿する、そのようなどうでも良いものに時間が取られたりすることを感じたこと、ありますか? そのような悩みからみなさんを救う、最強の味方があります!
最強の味方!クセの強い、Microsoft Graph APIとは?
Microsoft Graph APIについて知っていますか? Microsoftの様々なサービスは現在アズールのバックエンドで動いています。 そのアズールのバックエンドに対するAPIの総称が、Microsoft Graph APIです。 幅広い機能があって、こちらではそのごく一部、Microsoft Teamsにメッセージを投稿する機能のAPIを扱います。 その仕組みを見てみましょう。
Microsoft Graph APIの仕組み
Microsoft Graph APIは、stableとしてv1.0が公開されます。 それ以外はbeta版も公開されます。 Microsoft Graph APIは、名前からしてGraphMLのAPIに見えますが、実は普通のREST APIです。 そのため、スクリプトに組み込みやすく、認証情報の取得も自動化して組み込めれば完全自動化を実現できます。 今回は認証情報取得の部分は手動で行う予定です。
利用シーンの一部
今回の記事では、簡単な報告や通知を自動化するスクリプトの作成について記載します。 主に想定されるシーンとしては以下の通りです。
- PR/MRを作成した時の通知
- 定期的な連絡
それ以外のシーンにも適用できますが、今回の記事はこれらに利用する想定で記載します。 主に、今回の記事は以下のようなメッセージを送信する場面を想定した内容となります。
@上司 プルリクを作りました。
https://github.com/fugu/hogehoge/pull/123
確認お願いします。
利用までの準備
まずは認証情報を取得する必要があります。 用途によっては2通りの認証方法があります。 まずはユーザに代わって行動を行う委任型(delegated)アクセスです。 名前通り、アプリがユーザに成り代わってユーザが持っている権限内であれば様々な行動を起こせます。 もう一つはアプリ専用アクセスです。 こちらの方はユーザ権限なしでのアクセスで、限定的な用途を作成したユーザが付与してアプリとして行動を起こすいわゆるbotです。 今回の用途上、ユーザに代わって投稿を行いたいため、委任型アクセスでアプリを作成します。以下の手順でアプリを準備します。
以下の手順でアプリを準備します。
アプリの権限を利用するには、代わりにしてもらうユーザからの承認が必要なため、認証情報取得を行います。 以下の手順でターミナルから取得可能です。今回の記事ではUnix系の標準アプリであるcURLを利用しますが、同じようなアプリやREST APIを実行できる環境であれば代用可能です。Windowsの場合、PowerShell3.0以上で利用可能のInvoke-RestMethodを中心に組み込んでみるのもいいです。
- 次のURLに対して、上記で控えたclientIdとtenantIdを置き換える。なお、redirectUriは上記で設定される
http://localhostと同じであることを確認。上記で異なるURLを設定する場合は、redirectUriのパラメータを調整してください。scopeで取得したい権限を指定するが、今回はChannelMessage.Sendのほか、User.Readで基本的なユーザ情報も併せて取得する。https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize?client_id={clientId}&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%2F&response_mode=query&scope=User.Read%20ChannelMessage.Send&state=terminal - 上記のURLをブラウザ等で開く。
- oAuth2.0の画面で代用させたいユーザの認証(ログイン)を行う。
- redirectUriの画面を開こうとしたが、ここで存在しないURLであればエラーが出てきた。それでもいいので、遷移後のURLを控える。以下のようなURLが取得できると思う。
http://localhost/?code=0.AVMA1hIwB...x9BONdNmvw&state=terminal&session_state=ac90d7fd-01c5-44ff-ac57-c75769032bbf - codeパラメータで指定される値を控える。こちらは認証トークンを取得するに必要な認証コードなので大切に保管してください。
- ターミナルを開く。
- 以下のcURLコマンドに、clientId、tenantId、codeを置き換える。redirectUriは上記で利用されると同じ値にすること。
curl --location --request POST 'https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id={clientId}' \
--data-urlencode 'scope=User.Read ChannelMessage.Send' \
--data-urlencode 'code=0.AVMA1hIwB...x9BONdNmvw' \
--data-urlencode 'redirect_uri=http://localhost/' \
--data-urlencode 'grant_type=authorization_code'
- レスポンスのJSONから、
access_tokenの中身がアクセストークンとなるため、こちらを控えて大切に保管する。 - ここまででアプリを利用する準備が整ったので、次は実際の利用となる。
実際メッセージを送るには、上記の認証、環境情報以外に、送り先のチャンネルのID、チャンネルの所属チームのID、メンションを送るならメンション先のユーザのIDも必要だが、今回はこちらの記事では割愛させてください。 いずれもMicrosoft Graph APIで取得できるので、同じ手順で、上記のパーミッション周りに必要な権限を追加し、適切なAPIを実行すれば容易に取得できます。 (またの機会があれば記事にするので、ご期待ください。)
利用手順
改めて、メッセージを送信するには、以下の情報が準備してきました。
- 認証情報(アクセストークン)
- 送信先のチャンネルのID
- 送信先のチャンネルのチームのID
- メンションがあれば、メンションするユーザのID
上記の情報をもとに、以下ののcURLコメンドに、上記の情報を置き換えます。 Bearerの後にはアクセストークンを置き換えます。
curl --location --request POST 'https://graph.microsoft.com/v1.0/teams/{teamId}/channels/{channelId}/messages' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {accessToken}' \
--data '{
"body": {
"contentType": "html",
"content": "<at id=\"0\">上司</at> プルリクを作りました。<br><a href=\"https://github.com/fugu/hogehoge/pull/123\">https://github.com/fugu/hogehoge/pull/123</a><br>確認お願いします。"
},
"mentions": [
{
"id": 0,
"mentionText": "上司",
"mentioned": {
"user": {
"displayName": "上司",
"id": "{上司のユーザID}",
"userIdentityType": "aadUser"
}
}
}
]
}'
mentionsのオブジェクトには、必要なのは正しいユーザIDだけで、mentionTextやdisplayNameについては自由記入となります。 全く異なるフリーテキスト扱いで十分です。 実際上司の名前が誰でも、ここに「上司」と記載できるのが、APIのみの面白い仕様です。 上記で見ればわかるように、HTMLテキストとなるため、自由なHTMLを利用できます。
試してみた結果・結論
調べた段階では難しそうに感じていたが、思いの外容易に利用できた印象がありました。 アプリ作成から認証情報取得、実際のメッセージの投稿までは30分以内で完成できる手軽さでした。 しかも技術的な内容はあまりなく、汎用的に利用できると思います。 cURLは慣れないとレスポンスの見方がわかりづらいなどがありますが、他のアプリで代用できます。 Microsoft Graph APIのドキュメントではPostmanを推奨します。 筆者もPostmanで試したがさらに便利になったと思いました。 ただし他のAPIと組み合わせて一連の自動化に組み込むにはスクリプト実行が望ましいので、今回はその方針を考慮してcURLメソッドで紹介しました。 実際、上記の手順で投稿されるメッセージが以下のスクショの通りです。

このような工夫で雑務を減らし作業効率向上に繋がれれば幸いです。 今回は基礎的な内容となっていて、トークンが失効時の更新などは特に取り上げていませんでした。 さらに別なAPIと連携し自動化を図る実践的な内容はまたの機会で、お会いしましょう。アデュー。











