【Functions】GraphAPIを使ってSharePointへファイルアップロードする
こんにちは、しきゆらです。
今回は、Azure FunctionsからGraph APIを使ってSharePointへファイルをアップロードさせる方法をメモしておきます。
これまで何件かAzure Functions関連の記事を書いていましたが、今回がひとまずの最後です。
Azure FunctionsからSharePointへファイルアップロードする方法です。
用途としては、例えばFunctionsで何らかの処理をした結果を格納、とかでしょうか。
では、手順をまとめます。
クレデンシャルの作成
Entra IDにアプリを登録し、クライアントID/シークレットを取得して、これを使ってAPIを呼び出す形になります。
参考になりそうなのはこの辺。
アプリの登録
Entra IDにログインし、管理>アプリの登録からアプリの新規登録を行います。

適当な名前を付け、認証する種類を選択して作成します。
ここでは「この組織ディレクトリのみに含まれるアカウント」を選んでいます。


作成に成功すると下図のような画面になります。
ここの「アプリケーション(クライアント)ID」がそのままクライアントIDとなります。
合わせてディレクトリ(テナント)IDも必要になるので、覚えておきましょう。
クライアントシークレットを作成する
アプリを作成出来たら「管理」>「証明書とシークレット」から作成します。

シークレットの用途等を説明欄に記入し、シークレットの有効期限を適宜設定して作成します。
シークレットは作成したタイミングのみしか表示されないので、忘れずにコピーしておきましょう。
なお、わからなくなっても作り直せばよい。

これにて、クライアントID・シークレット・テナントIDが用意できました。
APIアクセス許可
アプリの作成ができたら、APIアクセスの許可をしてあげる必要があります。
いわゆるAPIのスコープを設定していきます。
参考になりそうなのは、以下あたり。
アクセス方法として、ユーザの代わりにアクセスする「委任アクセス」とユーザが関与しない「アプリ専用アクセス」の2種類があります。
今回は、Azure FunctionsからAPIアクセスするのでユーザではなくアプリ専用アクセスの方なので、その手順で設定していきます。
参考となるのはこの辺あたり。
スコープの確認
呼び出すAPIが必要とするスコープを確認しましょう。
スコープの一覧は以下にあります
ただし、上記を見てもどれがどれなのかいまいちわかりにくいので、これよりも各サービス・APIのページを確認した方が確実かと思います。
今回は、API経由でSharePointへファイルアップロードしたいので、以下からスコープを確認。
Files.ReadWrite.All
とSites.ReadWrite.All
が該当するようです。
ここでは面倒なので両方設定していきます。
スコープに対して許可する
アプリの「管理」>「APIアクセス許可」を開き「アクセス許可の追加」を開きます。

Graph APIを使うのでMicrosoft Graphを選択しますが、具体的なサービスからも設定可能です。


「アプリケーションの許可」を選択し、先ほど確認したスコープにチェックを入れます。
検索も可能。
追加後、リストに表示されます。
「管理者の同意が必要」が「はい」となっている場合は「<テナント名>に管理者の同意を与えます」をクリック。
なお、ここはテナント管理者の権限が必要そうです。

同意できるとチェックマークがつくので確認しましょう。

これにて設定完了です。
実装
では実際にコードを書いていきます。
まずはライブラリのインストールから。
ライブラリ追加
Graph APIのSDKと認証用のライブラリを追加します。
yarn add @microsoft/microsoft-graph-client @azure/identity
追加出来たら、コード書いていきます。
アップロードするAPIの確認
スコープを確認したページに書いてあるので確認しておきます。
いくつかあるようですが、今回は以下を選択。
PUT https://graph.microsoft.com/v1.0/sites/SiteID/drive/root:/path/to/Dir/fileName:/content
追加で確認が必要なのはSiteID。
サイトIDを確認
参考になりそうなのはこの辺かと。
コードからAPI叩いて結果を確認するのでもよいですが、Graph Editorを入れてGUI上で確認するのが楽でした。
以下のような形でサイトで検索して、IDを取得しましょう。
GET https://graph.microsoft.com/v1.0/sites?search=hogehoge
結果が以下のような形で返ってきます。
value配下の1要素が1サイトを表していて、そのIDがサイトIDです。
3つの値がカンマで並んでいる形ですが、3つ合わせてIDのようです。
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites",
"value": [
{
"createdDateTime": "2025-05-14T10:21:05Z",
"id": "<tenant>.sharepoint.com,xxxxxxxxxxxxx,xxxxxxxxxxxxxxx",
"lastModifiedDateTime": "2025-05-14T10:21:08Z",
"name": "name",
"webUrl": "https://<tenant>.sharepoint.com/sites/aaaaa",
"displayName": "サイトの表示名"
},
{
"createdDateTime": "2025-04-26T02:39:58Z",
"id": "<tenent>.sharepoint.com,xxxxxxxxxxxxxxxx,xxxxxxxxxxxxxxxxxxx",
"lastModifiedDateTime": "2025-04-26T02:40:06Z",
"name": "NAME",
"webUrl": "https://<tentn>.sharepoint.com/sites/hogehoge",
"displayName": "サンプルサイト",
"root": {},
"siteCollection": {
"hostname": "<tenant>.sharepoint.com"
}
}
]
}
コード
ざっくり以下のような感じ。
import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
import { ClientSecretCredential } from "@azure/identity";
import { Client } from "@microsoft/microsoft-graph-client";
import { TokenCredentialAuthenticationProvider } from '@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials';
const tenantId = 'xxxxxxxxxxxxxxxxxxxxxxxxx';
const clientId = 'xxxxxxxxxxxxxxxxxxxxxxxxx';
const clientSecret = 'xxxxxxxxxxxxxxxxxxxxx';
const folderPath = "/sites/<SiteID>/drive/root:/path/to/directory";
const httpTrigger1 = async (request: HttpRequest, context: InvocationContext) => {
try {
const credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
const authProvider = new TokenCredentialAuthenticationProvider(credential, {
scopes: ["https://graph.microsoft.com/.default"]
});
const client = Client.initWithMiddleware({
authProvider: authProvider,
debugLogging: true,
});
const fileName = `result_${Date.now()}.txt`;
const fileContent = JSON.stringify(request.body);
await uploadFileToSharePoint(client, fileName, fileContent);
return { status: 200, body: `File uploaded successfully: ${fileName}` };
} catch (e) {
context.log("Error:", e);
return { status: 500, body: "Internal Server Error" };
}
}
const uploadFileToSharePoint = async (graphClient: Client, fileName: string, fileContent: string): Promise<void> => {
try {
console.log(`uploadPath ==> ${folderPath}/${fileName}:/content`)
const result = await graphClient.api(`${folderPath}/${fileName}:/content`)
.put(fileContent);
console.log("File upload result:", result);
console.log(`File uploaded: ${folderPath}/${fileName}`);
} catch (e) {
console.log("Error uploading file:", e);
throw e;
}
}
app.http('httpTrigger1', {
methods: ['GET', 'POST'],
authLevel: 'anonymous',
handler: httpTrigger1
});
ざっくり解説すると、以下の部分が認証とAPIをたたくクライアント作成周り。
参考となるのはこの辺。
テナントID・クライアントID・シークレットをClientSecretCredential
に食わせてTokenProvider
を作成。
作成したTokenProvider
をClient
の初期化時に渡してクライアントを作成します。
const credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
const authProvider = new TokenCredentialAuthenticationProvider(credential, {
scopes: ["https://graph.microsoft.com/.default"]
});
const client = Client.initWithMiddleware({
authProvider: authProvider,
debugLogging: true,
});
クライアントが作成出来たら、APIをたたきましょう。
今回は、アップロード部分は別関数に分けています。
処理に関する部分はこの辺。
const folderPath = "/sites/<SiteID>/drive/root:/path/to/directory";
...
const result = await graphClient.api(`${folderPath}/${fileName}:/content`)
.put(fileContent);
確認したAPI/サイトIDをもとに変数folderPath
を定義。
このパスに対してファイル名を合わせてAPIを実行します。
putメソッドの引数としてファイルの内容を渡しています。
実行すると以下のような感じでファイルが作成されるはずです。

今回はテストとしてコードを書いているので、クレデンシャルを直書きしています。
動作確認ができたら、クレデンシャル情報は例えばKeyVaultに格納して環境変数として参照するなどしましょう。
Azure FunctionsからKeyValutの値を参照する方法は以前メモしているので、こちらも併せてご確認ください。
まとめ
今回はAzure FunctionsからGraph APIを使ってSharePointへファイルをアップロードする方法をメモしました。
SharePointのAPIをほかのものに置き換えれば、MSのサービス・データを参照した処理を実装可能になるかと思います。
そのベースとなる部分をふれられたので今回は満足です。
今回は、ここまで。
おわり
ディスカッション
コメント一覧
まだ、コメントがありません