OneDriveAPIから画像ファイルのURLを取ってくる

 OneDriveにアップロードした画像で、APIを使ってその画像にいつでもアクセスできるURLを取ってきたい。そのあたりをゴリゴリやってみたのでまとめておく。

 まず、いろいろやってみた結果として取ってこれる画像のURLでは、アップロードしたsource画像にアクセスするのは無理そうである。長辺が800px以下になるようにリサイズされたものしかとってこれなかった。

 画像URLはthumbnailデータとして取ってくる。
httpClient.DefaultRequestHeaders.Add("Authorization", $"BEARER {oauthToken}");

var id = Request.Query["id"];
var uri = $"https://api.onedrive.com/v1.0/drive/items/{id}/?select=id,name&expand=thumbnails(select=large,source)";
var response = await httpClient.GetAsync(uri);

 デフォルトのデータセットの中にもダウンロードURLが入っているが、そのURLは非永続的なものなのでぼくのほしいものではなかった。同様にthumbnailのサイズをsourceで取ってきても非永続的なURLになっているのでダメ。
 結果、画像の永続的なURLを取ってこれるのは、先に書いたように最大で長辺800pxのlargeサイズ画像ということになった。

 createLinkというのがAPIの中にあり、これ使えば共有リンク作れるでとあったので試してみたが、こっちも目的のものではなかった。
https://dev.onedrive.com/items/sharing_createlink.htm
それで返ってくるのはiframeに入ったファイルで、ワードとかエクセルのファイルで使うと便利なものだろう。今回はいらん。

 というわけで今回OneDriveから取ってこれた画像のURLは、サムネイルのものだった。欲しかったsourceの永続的なURLは取ってこれなかった。
…なんか不満だからAzureBlobを使うことを考えてみるか。
comment: 0

C#でGETやPOSTを使ってWeb API(OneDriveAPI)をつっつく

 このブログのバイナリファイルのストレージはOneDriveを使っている。そしてファイルに関するデータをそのAPIからとってきている。そこでWeb API(OneDrive)のC#でのつっつき方をまとめておく。OneDriveAPIを使うのに必要な認証は以前にやったので今回は認証のあとから入る。
認証


 まず基本となるHttpClientを用意する。これにトークンをヘッダでくっつけて以降のリクエストは行う。
var httpClient = new System.Net.Http.HttpClient();

httpClient.DefaultRequestHeaders.Add("Authorization", $"BEARER {oauthToken}");


 GETでつっつく
var uri = $"https://api.onedrive.com/v1.0/drive/items/{id}/?expand=thumbnails(select=small,source)";

var response = await httpClient.GetAsync(uri);
var responseBody = await response.Content.ReadAsStringAsync();



 POSTでJSONを投げてつっつく
var dict = new Dictionary<string, string>

{
{ "type", "embed" },
};
var json = JsonConvert.SerializeObject(dict);
var content = new StringContent(json, Encoding.UTF8, "application/json");

var uri = $"https://api.onedrive.com/v1.0/drive/items/{id};
var response = await httpClient.PostAsync(uri, content);



 POSTでmultipart/form-dataを投げるのは認証の時にやった。おさらい
var content = new FormUrlEncodedContent(new Dictionary<string, string>

{
{ "client_id", client_id },
{ "redirect_uri", redirect_uri },
{ "client_secret", client_secret },
{ "code", code },
{ "grant_type", "authorization_code" },
});
var codeResponse = await httpClient.PostAsync("https://login.live.com/oauth20_token.srf", content);
comment: 0

ブラウザにOneDriveAPIのJSONを渡して画像を表示

 OneDriveのAPIを使うとJSONで任意の情報を取得できる。前回に任意のディレクトリの子アイテム一覧をJSONで取得したので、今回はブラウザでそのJSONを受け取って、JSONに含まれているURLから画像ファイルを表示する…というJavaScript。

(function () {

document.getElementById("imageButton").addEventListener("click", function () {
var xhr = new XMLHttpRequest();
xhr.open("get", "/Master/OneDrive/Get");
xhr.responseType = "json";
xhr.addEventListener("load", function () {
var obj = JSON.parse(xhr.response);
var values = obj["value"];
for (var v in values) {
(function () {
var img = new Image();
img.src = values[v]["@@content.downloadUrl"];
img.width = 250;
document.getElementById("images").appendChild(img);
})();
}
});
xhr.send();
});
})();
comment: 0

OneDrive APIについて

前回

 前回にOneDriveでトークンの取得までをやったので、今回はそれを使ったディレクトリやファイルの取得までをちょっとつついておく。

 基本的な形は下記。
https://api.onedrive.com/{api-version}/drive/root/children?access_token={access token}

 ぼくは任意のディレクトリに入っているアイテム一覧がほしいので下記のようにカスタマイズ。https://api.onedrive.com/{api-version}/drive/items/{id}/children?access_token={access token}
https://dev.onedrive.com/resources/item.htm
 ディレクトリのIDは自分でブラウザを使ってOneDriveにログインして、IDを知りたいディレクトリに入ればURLのクエリにそれを確認することができる。

 あとはパラメータでオーダーやフィルターが使える。
https://api.onedrive.com/{api-version}/drive/items/{id}/children?access_token={access token}&orderby=name%20desc
https://dev.onedrive.com/odata/optional-query-parameters.htm
comment: 0

C#: ASP.NET Core MVCのアプリでOneDriveのOAuthを使う

 ASP.NET Core MVCアプリでOneDriveのAPIを使いたいので、OAuthでトークンを取ってくるという使い始めの部分までをまとめる。

 まずアプリをOneDriveのDevCenterに登録する。
https://apps.dev.microsoft.com/

 サインインするとその先の登録アプリ一覧画面の右上にアプリ追加がある。



 必要情報の入力と取得。ClienIDとClientSecret(PasswordとPrivateKeyがあるがPasswordのほう)、入力したリダイレクトURIをメモ。認証コード取得時にリダイレクトURIも渡さないといけないのだが、それが間違っているとコードが降りてこない。


 DevCenterへのアプリ登録ができたらあとはC#コード。OneDriveでアプリの仕様を許諾して認証コードを持って帰ってきたユーザの処理。
[Route("OAuth")]

public async Task<string> AuthUserAsync()
{
var client_id = xxx;
var redirect_uri = xxx;
var client_secret = xxx;
var code = Request.Query["code"];

var httpClient = new System.Net.Http.HttpClient();

// まず持って帰ってきた認証コードを使ってトークンを取得する
var content = new FormUrlEncodedContent(new Dictionary<string, string>
{
{ "client_id", client_id },
// ↓スラッシュとか入ってるだろうけどエスケープせずに入れてOK
{ "redirect_uri", redirect_uri },
{ "client_secret", client_secret },
{ "code", code },
{ "grant_type", "authorization_code" },
});
var codeResponse = await httpClient.PostAsync("https://login.live.com/oauth20_token.srf", content);
var codeResponseBody = await codeResponse.Content.ReadAsStringAsync();
var jsonObj = JsonConvert.DeserializeObject<Dictionary<string, string>>(codeResponseBody);
var token = jsonObj["access_token"];

// 取得したトークンを使ってOneDriveにユーザ情報を要求する
var uri = $"https://api.onedrive.com/v1.0/drive?access_token={token}";
var tokenResponse = await httpClient.GetAsync(uri);
var tokenResponseBody = await tokenResponse.Content.ReadAsStringAsync();

// ユーザを確認できる情報が得られたのでごにょごにょする
// Foo(tokenResponseBody);

// return tokenResponseBody;

}
comment: 0