MS Teams client の作り方

Page content

自作ツールで、MS Teams に対して投稿を read/write する方法について書きます。

Teams の管理者権限の許可が必須

Teams の管理者権限の許可が必須 」です。

大事なことなので始めに書きます。

自作ツールで、MS Teams に任意に投稿を read/write するには、 「 Teams の管理者権限の許可が必須 」です。

たとえ自分自身のアカウントを使って投稿したくても、 自作ツールから行なうには管理者権限の許可が必須 なんです。

MS Graph API へのアクセス

MS Graph API は、以下のサイトにリファレンスが載っています。

<https://docs.microsoft.com/ja-jp/graph/>

これの Teams の API を叩けばアクセスできます。

当然と言えば当然ですが、MS Graph API で Teams にアクセスするには、 その Teams のアカウント認証が必要です。

そして、アカウント認証するには、Azure から発行した ClientID を使用する必要があります。

なお、 CliendID の発行時に、クライアントの種別を指定します。 その種別には、 そのクライアントを登録したアカウントに属する組織のみにアクセスするクライアントか、 それとも組織を限定せずにアクセス可能なクライアントか、を指定します。

より具体的な説明は以下を参照してください。

リンク

Azure の CliendID 発行が出来るユーザは当然限られています。

個人で作った Azure アカウントなら、 自分が管理者でもあるので自由にクライアントを登録できますが、 誰かから発行された Azure アカウントなら、 その発行者(管理者)によって、制限されている可能性があります。

ここで、クライアント登録が出来ないのであれば、ほとんどの場合そこで終わりです。

token 取得

発行された ClientID を指定して、アカウント認証するのですが、 通常はブラウザのインタフェースを通して認証するのが一般的です。

ですが、ブラウザを搭載していないアプリなどで利用する場合は、以下の手順になります。

<https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-device-code>

なお、 この device code を利用する方法は、 ClientID を発行したアプリの設定において、次をセットしておく必要があります。

Azure の 「アプリ登録」 → 「認証」 で 「モバイルとデスクトップのフローを有効」を 「はい」にする。

これを設定しておかないと、認証手順が進みません。

認証手順

device code 発行

まず以下を実行し、 device code 登録に必要な情報を取得します。

$ echo 'client_id={CLIENT_ID}&scope=openid%20offline_access%20https%3A%2F%2Fgraph.microsoft.com%2FChannelMessage.Send' | curl 'https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/devicecode' -H 'Content-Type: application/x-www-form-urlencoded' -d @-

ここで、 {CLIENT_ID} , {TENANT_ID} には、自分の環境に合せて設定してください。

また、scope には必要なパーミッションのスコープを指定してください。

上記の例は、所定のチャネルに新規登録する際に必要なパーミッション(ChannelMessage.Send)です。

これを実行すると、次のようなレスポンスを得られます。

 {
  "user_code":"??????????????????",
  "device_code":"??????????????????",
  "verification_uri":"https://microsoft.com/devicelogin",
  "expires_in":900,
  "interval":5,
  "message":"To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code H6YXVV74E to authenticate."
}

ここで、 user_codedevice_code をメモって起きます。

user_code は認証させたいユーザに表示し、 device_code は teams client を開発する側で一時的に保持しておきます。

認可

次に teams client を認証させたいユーザが以下の URL にブラウザでアクセスします。

<https://microsoft.com/devicelogin>

ここにアクセスすると、コード入力画面が表示されるので、 user_code を入力します。

user_code を入力すると、直ぐに Azure の認証画面に移るので ID/PASS を入力し、 teams client にアクセスを認可します。

token 取得

つぎに、token を取得します。

echo 'grant_type=urn:ietf:params:oauth:grant-type:device_code&client_id={CLIENT_ID}&device_code={DEVICE_CODE}' | curl -X POST https://login.microsoftonline.com/organizations/oauth2/v2.0/token -H 'Content-Type: application/x-www-form-urlencoded'  -d @-

ここで {CLIENT_ID} , {DEVICE_CODE} に client_id と device_code を指定します。

成功すると、次のレスポンスが返ってきます。

{
   "token_type":"Bearer",
   "scope":"openid profile email https://graph.microsoft.com/ChannelMessage.Send",
   "expires_in":3749,
   "ext_expires_in":3749,
   "access_token":"?????????????",
   "refresh_token":"???????????",
   "id_token":"??????????????"
}

この access_tokenrefresh_token が Graph API を利用する際に必要になります。

なお、 access_token は短い間隔で expire し、 refresh_token を使って expire した access_token を取り直して利用する運用方法になります。

よって、refresh_token は非常に重要な情報です。

refresh_token 自体も、一定期間で expire するようです。

ここまでの作業を一定時間内で行なう必要あります。

token の refresh

前述の通り access_token は短かい時間で expire するので、 refresh token で取り直す必要があります。

以下を実行すると access_token を取り直せます。

echo 'client_id={CLIENT_ID}&scope=https%3A%2F%2Fgraph.microsoft.com%2FChannelMessage.Send&refresh_token={REFRESH_TOKEN}&grant_type=refresh_token' | curl 'https://login.microsoftonline.com/organizations/oauth2/v2.0/token' -d @- -H 'Content-Type: application/x-www-form-urlencoded'

成功すると以下が返ります。

{
   "token_type":"Bearer",
   "scope":"openid profile email https://graph.microsoft.com/ChannelMessage.Send",
   "expires_in":4745,
   "ext_expires_in":4745,
   "access_token":"????????????????",
   "refresh_token":"???????????????????",
   "id_token":"?????????????????????"
}
access token の指定

Graph API を利用するには access token が必要です。

Graph API の URL アクセス時の HTTP header に、以下を指定してください。

Authorization: Bearer {ACCESS_TOKEN}

permission

Graph API は、そのスコープごとにアクセス制御されます。

このアクセス制御に permission を与えることで、 API にアクセスできるようになります。

API に permission を与えるには権限が必要になります。 その権限には、個人アカウントで良いものと、管理者権限が必要なものとがあります。

なお、任意にメッセージを投稿するには、管理者権限による permission が必要です。

Teams への投稿

Teams へ投稿するには以下の API を利用します。

<https://docs.microsoft.com/ja-jp/graph/api/resources/teams-api-overview?view=graph-rest-1.0>

Teams のチームへの投稿は次の概念で管理され、 それぞれがユニークな ID を持っています。

  • team

    • Teams 内の各チーム
  • channel

    • 各チーム内に作られるチャネル
  • message

    • チャネル内に投稿された各メッセージ

例えば、あるチーム内の、ある channel に 新規投稿する 場合、 対象チームの ID と、対象 channel の ID を取得し、 それら ID を指定してメッセージを投稿します。

新規投稿ではなく、 あるメッセージに対する reply には、 前述の対象チームの ID と、対象 channel の ID に加え、 対象のメッセージ ID を取得する必要があります。

このメッセージ ID を取得するには、 ChannelMessage.Read.All スコープの permission が必要であり、 その permission を与えるには管理者権限が必要になります。

なお、個人間のチャットはチームのメッセージとは異なります。

新規投稿 API

あるチーム内の、あるチャネルにメッセージを新規投稿する場合は、以下を利用します。

https://graph.microsoft.com/v1.0/teams/{team-id}/channels/{channel-id}/messages

ここで {team-id} , {channel-id} は、チーム、チャネルの ID を指定します。

送信するデータは以下の情報を参考にしてください。

<https://learn.microsoft.com/en-us/graph/api/channel-post-messages?view=graph-rest-beta&tabs=http>

Graph Explorer

<https://developer.microsoft.com/en-us/graph/graph-explorer>

MS Graph API をブラウザから試すことができる Web ツール(Graph Explorer)が用意されています。

これを利用することで、 token 取得や permission の設定を簡単に行なえます。

なお、このツール上で token 取得はできますが、 その token は短時間で expire する access token なので、 実際にクライアントを自作する際には、 ClientID の発行が必須になります。

MS Graph API について

MS Graph API は、MS のさまざまなサービスにアクセスできる強力な API です。

ですが、強力であるために、セキュリティはかなり安全方面に振っているように思えます。 さまざまなケースで管理者権限による許可が必要になっています。

なんでもかんでも「管理者権限による許可が必要」というのは、 セキュリティの管理手法として、安直ではないのか?と思わないでもない。