10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Microsoft Graphを使ってTeamsメッセージを取得する

Posted at

はじめに

データ解析をしようと思ったときによくあるデータの収集方法の例として、準備されているサンプルデータセットを利用したり、APIを使ってデータを要求することが挙げられます。

しかし、上記以外で解析できたら面白いデータはないかと考えたとき、Microsoft Teamsで送信されたメッセージを解析できたら面白いと感じたことが、Teamsメッセージを取得しようと思ったきっかけです。そこで、Teamsメッセージを取得する方法を調べていると、Microsoft Graphを使う必要があるということで、本記事ではMicrosoft Graphを使ってTeamsメッセージを取得する方法をまとめます。

Microsoft Graphとは

Microsoft Graphは、Microsoft 365サービス全体に保存されているデータへのアクセスを提供するREST APIです。Microsoft Graph APIを使用することで、Office 365OneDriveTeamsOutlookWindow10、などのMicrosoft 365のコアサービスのデータにアクセスすることができます。
image.png

Microsoft GraphとMicrosoft Graph APIの違い
Microsoft GraphはAPIの集合体であり、Microsoft Graph APIはその中の1つのAPIです。

Microsft Graph APIのアクセス許可

Microsoft Graph APIには、アプリケーションがMicrosoftのクラウドサービスにアクセスするために必要な以下の2種類のアクセス許可があります。

  • 委任されたアクセス
  • アプリ専用アクセス

本記事では、委任されたアクセスでMicrosoft Graphにアクセスし、Teamsメッセージの取得を行うことにします。

委任されたアクセス

委任されたアクセスは、ユーザーがクライアントアプリケーションにサインインし、クライアントアプリケーションがユーザーの代わりにMicrosoft Graphを呼び出します。委任されたアクセスでは、ユーザーとクライアントの両方が要求を行う権限を持っている必要があります。

委任されたアクセス許可には、スコープと呼ばれるものがあります。スコープはAPIへのアクセスを制御するために使用され、APIへのアクセスを許可する範囲を指定することができます。例えば、Microsoft Graph APIでは、User.Readというスコープがあり、このスコープを使用することでユーザー情報を読み取ることができます。

アプリ専用アクセス

アプリ専用アクセスでは、ユーザーの代わりにアプリケーションがMicrosoft Graph APIにアクセスできます。アプリはサインインしているユーザーなしで独自にデータを操作でき、バックグラウンドサービスまたはデーモンとして主に自動化やバックアップなどのシナリオで使用されます。

アプリ専用アクセスを使用する場合、ユーザーの同意なしでMicrosoft Graph APIにアクセスできるため、注意が必要です。

image.png

Teamsメッセージを取得する流れ

Teamsに保存されているメッセージにアクセスするには、ユーザーの認証と認可が必要です。

認証と認可について
認証はユーザーが自分自身であることを証明することであり、システムにログインするために必要なものです。一方で、認可はユーザーがアクセスできるリソースを決定することであり、リソースにアクセスするために必要なものです。例えば、ユーザーがパソコンにログインする際にIDとパスワードを入力することで、ユーザーが誰であるかを確認するのが認証です。その後、ユーザーが持つ権限に応じてファイルの閲覧や編集などの操作が可能かどうかを判断するのが認可です。

委任されたアクセスでは、OAuth2.0の認可フローに基づいてユーザーの認証・認可が行われます。OAuth2.0では、まず初めにサインインをしてユーザー認証を行い、その後にアクセストークンを要求・取得することで認可が行われます。

OAuth2.0とは、ユーザー権限の認可を行うためのプロトコルです。

以下に、Teamsメッセージを取得するフローをまとめます。

  1. 認証フロー
    1. サインイン
    2. 認証コードの取得
  2. 認可フロー
    1. アクセストークンの要求
    2. アクセストークンの取得
  3. Microsoft Graphへのアクセス
    1. アクセストークンを使ってHTTPリクエスト
    2. HTTPレスポンス

認証コードとアクセストークンについて
認証コードは、OAuth 2.0の認証フローで使用されるトークンの1つであり、アプリがユーザーのアクセス許可を取得するために使用されます。認証コードでは、アプリがユーザーに代わってリソースにアクセスすることはできません。一方で、アクセストークンは、OAuth 2.0の認可フローで使用されるトークンの1つであり、アプリがユーザーの代わりにリソースにアクセスするために使用されます。アクセストークンには、有効期限があります。

OAuth2.0の認可フロー

先述したTeamsメッセージを取得するフローは、OAuth2.0の認可フローに基づいています。以下はJavaScriptで書かれたSPA(Single Page Application)Microsoft identity platform(Azure ADなど)に認証コードとアクセストークンを要求・取得した後、Microsoft Graph APIに対してHTTPリクエストを要求している図になります。
image.png

Microsoft Graphを使用するための下準備

ここまで、Microsoft Graphの説明や、Teamsメッセージを取得する流れをOAuth2.0の認可フローを元に説明しました。ここからは実際に、Microsoft Graphを使用するための準備事項について説明していきます。

API呼び出しのアクセス許可の種類とスコープの確認

本記事では、Teamsメッセージを取得する必要があります。公式ドキュメントによると、Teamsメッセージにアクセスするための許可の種類として、委任(職場または学校のアカウント)、委任(個人用Microsoftアカウント)、アプリケーションの3種類がありますが、委任(個人用Microsoftアカウント)はアクセスがサポートされていないことがわかります。今回はアプリ専用アクセスではなく、委任されたアクセスでMicrosoft Graph APIを使用するため、委任(職場または学校アカウント)でアクセスすることになります。このとき、必要になるスコープはChannelMessage.Read.Allであるとわかります。

image.png

Microsoft 365テナントの作成

自身で管理している職場または学校用のアカウントを持っていない場合、委任(職場または学校のアカウント)でアクセスするためにはMicrosoft 365テナントを作成し、自身がテナント管理者になる必要があります。Microsoft 365 開発者プログラムに参加することで、無料でMicrosoft 365 E5開発者サンドボックスサブスクリプションのセットアップができ、90日間だけ有効のテナントの管理者になることができます。

登録すると、以下のようなダッシュボードが表示されます。
f77fac13-0f8d-e9d4-228e-4762736b5388.png

アプリケーションの登録

Azureポータルにログインし、Azure Active Directory>アプリの登録>+新規登録から任意のアプリ名でアプリを登録してください。本記事では、TeamsAPIAppとしました。TeamsAPIAppの概要ページでは、クライアントIDや、テナントID、クライアントシークレット、認証後のリダイレクトURI等の情報が表示されています。
スクリーンショット 2023-05-21 155352.png

次に、APIのアクセス許可>+アクセス許可の追加>Microsoft Graph>委任されたアクセス許可>ChannelMessage.Read.Allを選択して、アクセス許可の追加のボタンを押下します。その後、MSFTに管理者の同意を与えますをクリックします。最後に、以下のスクリーンショットのように、ChannelMessage.Read.AllMSFTに付与されましたという状態になればアプリの登録は完了です。
image.png

アプリケーションのコーディングと実行

ここでようやく、アプリケーションのコーディング及び実行を行っていくことができるようになりました。ここでは本記事の要点から外れるために説明を省略しますが、今回はJavaScriptで記述したSPAを作成しています。また、node.jsでWebアプリケーションを作成するためにフレームワークである、expressを使いました。

認証フロー

まずは、認証するためにアクセスするエンドポイントを指定します。IDやリダイレクト先URI等の情報は、Azureポータルのアプリの登録にあるTeamsAPIAppから確認することができます。

endpoint.js
const endpoint = "https://login.microsoftonline.com/<テナントID>/oauth2/v2.0/authorize" + 
"?client_id=<クライアントアプリケーションのID>" + 
"&response_type=code" + 
"&redirect_uri=<認証コードを受け取るためのリダイレクト先のURI>" +
"&response_mode=query" +
"&scope=<アクセストークンでアクセスしたいリソースの範囲>" +
"&state=<クライアントアプリケーションが任意に指定できるパラメータ>";

上で示したエンドポイントにアクセスすると、以下のようなサインインの画面が表示されます。

サインインは、ユーザーの認証を行うプロセスです。ユーザーが自分自身であることを証明するために、IDとパスワードなどの資格情報を使用します。

サインインに成功すると認証コードが返され、Azureポータルとredirect_uri=<認証コードを受け取るためのリダイレクト先のURI>でリダイレクト先として設定したURLに飛ばされます。Azureポータルでは、http://localhost/accesstokenと設定しています。

スクリーンショット 2023-05-21 162912.png

Azureポータルとredirect_uri=<認証コードを受け取るためのリダイレクト先のURI>で指定したURLが異なると、以下のようなエラーになります。
スクリーンショット 2023-05-18 135101.png

認可フロー

これまでで認証コードを取得できているため、次は認可フローを経てアクセストークンを取得していきます。HTTPリクエストを簡単に行えるライブラリであるaxiosconst axios = require('axios');として、別箇所にて読み込まれています。以下のJavaScript関数によって、アクセストークンを取得することができます。

token.js
async function getAccessToken(code, axios) {
  const options = {
    method: 'POST',
    url: "https://login.microsoftonline.com/<テナントID>/oauth2/v2.0/token",
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    data: {
      client_id: <クライアントID>,
      scope: <スコープ>,
      code: code,
      redirect_uri: <アクセストークンを受け取るためのリダイレクト先のURL>,
      grant_type: 'authorization_code',
      client_secret: <クライアントアプリケーションの秘密鍵>,
    }
  };
  return await axios(options)
  // レスポンスが正常に受信された場合
  .then((response) => {
    return response.data.access_token;
  })
  // レスポンスがエラーになった場合
  .catch((error) => {
    console.error(error);
    return undefined;
  });
}

ここで、取得したアクセストークンはブラウザのCookieに保存しました。

Microsoft Graphへのアクセス

ここまでで、アクセストークンを取得することができました。アクセストークンはCookieに保存されているため、Microsoft Graphへアクセスする際はCookieから毎回アクセストークンを取得します。以下のJavaScript関数は、endpointで指定されたMicrosoft Graph APIに対して、HTTPヘッダーにAuthorization:<Bearer token>を設定した上で、GETリクエストを送信する関数です。

msgraph.js
async function callMSGraph(endpoint, token, axios) {
    const options = {
    method: 'GET',
    url: endpoint,
        headers: {
            Authorization: token
        }
    };
    return await axios(options)
    // レスポンスが正常に受信された場合
    .then((response) => {
        return response.data;
    })
    // レスポンスがエラーになった場合
    .catch((error) => {
        console.error(error);
        return error;
    });
}

今回のように、Teamsメッセージを取得するためのendpointhttps://graph.microsoft.com/v1.0/teams/${teamId}/channels/${channelId}/messagesです。

HTTP
GET /teams/{team-id}/channels/{channel-id}/messages

Teamsチャネルメッセージを一覧表示するMicrosoft Graphの公式ドキュメントはこちらの記事になります。

上記のエンドポイントに対してGETリクエストを送信すると、以下のようなレスポンスが返ってきました。
スクリーンショット 2023-05-21 165648.png
ちなみに、私がテナント管理者となっているテナント内で作成したMicrosoft Teamsのチャネル内におけるメッセージは以下の通りになります。これにより、Microsoft GraphTeamsメッセージを正しく取得できたことを確認することができました。
スクリーンショット 2023-05-21 165833.png

おわりに

本記事ではMicrosoft Graphを使ってTeamsメッセージを取得するために、OAuth2.0の認可フローに触れながら解説させていただきました。今回はMicrosoft Teamsを対象としていますが、OutlookOneDriveといった製品についても、Microsoft Graphを使えばアクセスすることができるため、本記事の内容の理解を深めれば、応用の幅が広がると思います。私は実のところ、今回初めてMicrosoft Graphに触れましたが、認証・認可について理解があれば簡単に使用できて便利なAPIであると感じたので、この記事を読んでくださった方は是非このAPIを使ってみてください。私もまだまだAzureについて勉強している途中なので、本記事の内容で間違っている箇所があればご教授していただけると嬉しいです。

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?