Microsoft Graphでユーザーのアバター画像を取得する

Microsoft Graphにはv1.0とbetaのエンドポイントがあります。
どちらにもユーザーのアバターを取得するAPIがあります。  

しかし、v1.0とbetaで取得できる場合とそうでない場合があるようです。

https://docs.microsoft.com/ja-jp/graph/api/profilephoto-get?view=graph-rest-1.0 https://docs.microsoft.com/ja-jp/graph/api/profilephoto-get?view=graph-rest-beta

v1.0とbetaで同じユーザーのアバターを取得してみる

アバターはサイズを指定して取得をできるので、必要なサイズのものを取得します。
データはバイナリで受け取るので、適当にBufferなどに変えてファイルに書き出すかData URI schemeに置き換えて、DBに格納したりすることができます。

ここではData URI schemeに変えるコードを載せておきます。

import fetch from 'node-fetch';

const v1Endpoint = 'https://graph.microsoft.com/v1.0';
const betaEndpoint = 'https://graph.microsoft.com/beta';

type Endpoint = "v1.0" | "beta";
type AvatarSize = "48x48" | "64x64" | "96x96";

type Avatar = {
  mimeType: string;
  url: string;
};

const userAvatar = (endpointType: Endpoint, size: AvatarSize) => async (userId: string): Promise<Avatar | undefined> => {
  const options = {
    method: "get",
    headers: {
      Authorization: `Bearer ${process.env.ACCESS_TOKEN}`
    }
  };

  const endpoint = endpointType === 'v1.0' ? v1Endpoint : betaEndpoint;
  const response = await fetch(`${endpoint}/users/${userId}/photos/${size}/$value`, options);

  if (!response.ok) {
    const failedBody = await response.json();
    console.log(failedBody);
    return;
  }

  const mimeType = response.headers.get('content-type') as string;

  const buffer = await response.buffer();
  const data = buffer.toString('base64');

  const url = `data:${mimeType};base64,${data}`;

  return {
    mimeType,
    url
  };
};

const v1Avatar = userAvatar("v1.0", "48x48");
const betaAvatar = userAvatar("beta", "48x48");

const main = async (userId: string) => {
  const v1 = await v1Avatar(userId);
  const beta = await betaAvatar(userId);
  console.log(v1);
  console.log(beta);
};

const userId = process.argv[2];

main(userId).then(() => {
  console.log('done');
}).catch(err => {
  console.log(err.stack);
});

実行するにはアクセストークンとユーザーIDを指定します。

ACCESS_TOKEN=[アクセストークン] \
node avatar.js [ユーザーID]

v1.0では一部のユーザーのアバターが取得できない場合がある

一部のユーザーではアバターを設定しているのにもかかわらず、アバターが取得できないユーザーがいました。
そのユーザーの場合はMailboxNotEnabledForRESTAPIがエラー本文に含まれていました。  

{
  error: {
    code: 'MailboxNotEnabledForRESTAPI',
    message: 'REST API is not yet supported for this mailbox.',
    innerError: {
      date: '2020-08-25T10:53:21',
      'request-id': xxxxxxxxxxxx
    }
  }
}

betaで問題が発生しないのは一部のAPIの制限がなくなったものと思われます。
OfficeなどのAPIがMicrosoft Graphに統合されているはずなのですが、まだ完全には終わっていないのかもしれないです。