Microsoft Graph API を実行して SharePoint のドキュメント情報を取得する場合に必要な siteId の取得の仕方 (C#)

## 1. はじめに

Microsoft Graph API を利用すると、SharePointのサイトの情報を取得したり、SharePointのファイルをダウンロードしたり、アップロードしたりと様々なことができるようになります。
ただ、SharePoint のドキュメントの情報を Microsoft Graph API を使って取得する際にsiteId、driveId、itemIdなどの情報の取得が必要になることもあるかと思います。

今回はsiteIdに絞って、そのIdの取得方法をご紹介します。

言語はC#です。

なお、SharePointのドキュメントのダウンロード、アップロードに関しては以下の記事で説明していますので、それぞれご覧ください。

 - [SharePoint のファイルを Microsoft Graph API を使用してダウンロードする　～API理解編～](https://qiita.com/Takuma_Kondo/items/af11257b3e2dcb9d8869)
 - [SharePoint のファイルを Microsoft Graph API を使用してダウンロードする(C#)　～実装編～](https://qiita.com/Takuma_Kondo/items/a9cefb6128e092ff27a9)

## 2. siteIdの取得

### 2.1. siteレスポンス

以降で紹介するsiteIdの取得は、基本的にGetリクエストをして帰ってくるサイトレスポンスからidを取得することを前提としています。
Getリクエストの実施方法などは、以下の記事等で触れていますのでそちらを参考にして下さい。
 - [Microsoft Graph API を Graph Client Service を利用せずに GET PUT POST を HTTPで実行する（C#)](https://qiita.com/Takuma_Kondo/items/8102977024231d33fdb1)
 - [SharePoint のファイルを Microsoft Graph API を使用してダウンロードする(C#)　～実装編～](https://qiita.com/Takuma_Kondo/items/a9cefb6128e092ff27a9)

getリクエストで返ってくるサイトのレスポンスの例は以下です。
```
HTTP/1.1 200 OK
Content-type: application/json

{
  "value": [
    {
      "id": "contoso.sharepoint.com,da60e844-ba1d-49bc-b4d4-d5e36bae9019,712a596e-90a1-49e3-9b48-bfa80bee8740",
      "name": "Team A Site",
      "description": "",
      "createdDateTime": "2016-10-18T03:05:59Z",
      "lastModifiedDateTime": "2016-10-18T10:40:59Z",
      "webUrl": "https://contoso.sharepoint.com/sites/siteA"
    },
    {
      "id": "contoso.sharepoint.com,da60e844-ba1d-49bc-b4d4-d5e36bae9019,0271110f-634f-4300-a841-3a8a2e851851",
      "name": "Team B Site",
      "description": "",
      "createdDateTime": "2016-10-18T03:05:59Z",
      "lastModifiedDateTime": "2016-10-18T10:40:59Z",
      "webUrl": "https://contoso.sharepoint.com/sites/siteB"
    }
  ]
}
```
上記の例において、"id"プロパティが今回取得したsiteIdになります。
"id"プロパティは以下の複合になっています。
 - サイト コレクションのホスト名 (contoso.sharepoint.com)
 - サイト コレクションの一意 ID (GUID)
 - サイトの一意 ID (GUID)

用途によって使い分けができますが、SharePointのドキュメント情報の取得においては、「サイトコレクションのGUID」を使用します。

### 2.2. サイトのキーワード検索機能を使用した取得

Graph Client Serviceを使用する場合は以下を実行します。
```C#
var result = await graphClient.Sites.GetAsync((requestConfiguration) =>
{
	requestConfiguration.QueryParameters.Search = "{query}";
});
```

以下のエンドポイントでHTTPのGETを実行します。
```
$"https://graph.microsoft.com/v1.0/sites?search={query}"
```
これでqueryから検索に引っ掛かったsite情報を取得することができます。

ではqueryからどのような検索条件で出力されるのか・・・？  
どんなqueryを与えればよいのか気になりますよね。  

調べました。  

結論、公式ドキュメントからはこれといった解は得られませんでした。
おそらくで言うと、**取得できるレスポンスの各プロパティの値に対して、文字列一致で検索をかけているのではないか**と考えています。  
もし、知っている方ましたら教えてほしいです。  

従って、例えば、「Sample」というサイト名のsiteIdを取得したいとします。
そうしましたら、「Sample」をqueryに与えればよいわけです。  
まぁ他のプロパティも存在しているので、以下に表示するsiteリソースのプロパティから一致するものが検索結果として引っ掛かると考えるのが良いでしょう。
```
// サイトリソース
{
  "id": "string",
  "isPersonalSite": "bool",
  "root": { "@odata.type": "microsoft.graph.root" },
  "sharepointIds": { "@odata.type": "microsoft.graph.sharepointIds" },
  "siteCollection": {"@odata.type": "microsoft.graph.siteCollection"},
  "displayName": "string",

  /* relationships */
  "analytics": { "@odata.type": "microsoft.graph.itemAnalytics" },
  "contentTypes": [ { "@odata.type": "microsoft.graph.contentType" }],
  "drive": { "@odata.type": "microsoft.graph.drive" },
  "drives": [ { "@odata.type": "microsoft.graph.drive" }],
  "items": [ { "@odata.type": "microsoft.graph.baseItem" }],
  "lists": [ { "@odata.type": "microsoft.graph.list" }],
  "operations": [ { "@odata.type": "microsoft.graph.richLongRunningOperation" }],
  "permissions": [ { "@odata.type": "microsoft.graph.permission" }],
  "sites": [ { "@odata.type": "microsoft.graph.site"} ],
  "columns": [ { "@odata.type": "microsoft.graph.columnDefinition" }],
  "onenote": { "@odata.type": "microsoft.graph.onenote"},
  "termStore": { "@odata.type": "microsoft.graph.termStore.store" },
  "termStores": [ { "@odata.type": "microsoft.graph.termStore.store" } ],

  /* inherited from baseItem */
  "name": "string",
  "createdDateTime": "datetime",
  "description": "string",
  "eTag": "string",
  "lastModifiedDateTime": "datetime",
  "webUrl": "url"
}
```
※サイトリソース等を詳しく知りたい方は[こちら](https://learn.microsoft.com/ja-jp/graph/api/resources/site?view=graph-rest-1.0)をご覧ください。

小ネタですが、SharePointのサイトはNameとDisplayNameがあるので、どちらでもかかるようになっています。

いろいろ試しましたが、urlでは検索できませんでした。
ただUrlの場合は次章の方法で、siteIdを取得できました。

### 2.2. サイトのUrlから取得

2.1章の検索からの取得では、サイトを一意に特定できません。  
検索では、似たような名前のサイトが複数あればおそらく、すべて検出されるでしょう。 
従って一意にサイトを特定するために、Urlを使用します。  

Graph Client Service を使用する方法を試せていないので、とりあえずGetメソッドに渡す方法をやってみます。
以下のエンドポイントをHTTPのGETで実行します。
```C#
$"https://graph.microsoft.com/v1.0/shares/{encodedUrl}/site"
```
なお、encodedUrl は変数名の通り、SharePointのUrlを以下の手順でエンコードしたものになります。
```C#
string base64Value = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(searchQuery));
string encodedUrl = "u!" + base64Value.TrimEnd('=').Replace('/', '_').Replace('+', '-');
```

これでサイトレスポンスを取得できます。  
後は、レスポンスからsiteIdを取得するだけですね。

## 3. おわり

今回はここで終わりです。
次回は SharePoint のドキュメントの itemId の取得を紹介します。  
ぜひそちらもご覧ください。