Google Apps ScriptとMicrosoft Graph APIの連携 - 準備編【GAS】
G Suiteには、Google Driveというクラウドストレージサービスがあるので、通常は他のオフィスサービス(Microsoft365)と連携する必要がありませんが、G Suiteをアプリケーションの環境、通常はMicrosoft365を使って、Excelのファイル類などについては、OneDriveやSharepointを利用している事もあるでしょう。
そんな時にGAS側からMicrosoft365とりわけExcelファイルの読み書きができたら非常に便利になると思います。今回はGoogle Apps Scriptにて、Microsoft365側のExcelファイルへアクセスする手順を残しておきたいと思います。
目次
準備するもの・使用するファイル
- 連携用Googleスプレッドシート
- Microsoft365側のExcelファイル
- Microsoft Graph API
- OAuth2 for Apps Script ライブラリ
- Application Registration Portal
事前準備
今回のスクリプトはOAuth2.0認証が必要となるため、その為の簡単設定ライブラリとして、OAuth2 for Apps Scriptライブラリを利用させていただきます。また、Microsoft365側では、Application Registration Portalにてアプリの作成を登録し、アプリケーションIDとアプリケーションシークレット等の情報を入手する必要があります。
GAS側の事前準備
ライブラリの追加
以下の手順でOAuth2 for Apps Scriptライブラリを追加しましょう。
- スクリプトエディタを開きます。
- メニューより「リソース」⇒「ライブラリ」を開きます。
- ライブラリを追加欄に「1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF」を追加します。
- 現時点ではバージョンは30が最新ですので、それを選択しておきます。
- 保存ボタンを押して完了
これで、OAuth2.0認証にまつわる様々な関数を手軽に利用できるようになります。
図:ライブラリを追加した様子
コールバックURLを取得する
コールバックURLとは、認証を完了しAccess Tokenを取得したら戻るべきURLを指定するものです。これは、スクリプトIDをもとに作られているので、スクリプトIDを取得して組み立てます。
- スクリプトエディタのメニューより「ファイル」⇒「プロジェクトのプロパティ」を開く
- 情報の中にある「スクリプトID」を控えておく。
- https://script.google.com/macros/d/スクリプトID/usercallback として組み立てる。これがコールバックURLとなる。
図:スクリプトIDはファイル毎に異なるのです。
Microsoft365側の事前準備
続いて、Microsoft365側での処理を行います。ここでは、アプリケーションの作成を行い、アプリケーションIDとアプリケーションシークレット等を生成します。
- Application Registration Portalにログインする。
- アプリの追加ボタンを押す。
- Application Nameを入力しCreateボタンを押します。アルファベット以外も使えますよ。
- この段階でアプリケーションIDはすでに生成されているので、控えて置きます。
- アプリケーションシークレットにて、「新しいパスワードを生成」をクリックし、パスワードを発行します(このパスワードはこの時の1回しか表示されません)。
- 「プラットフォームの追加」にて、追加ボタンを押し、Webを選択。
- ここで、GAS側で取得したコールバックURLをリダイレクトURLに入力します。
- Microsoft Graphのアクセス許可では、スコープを設定します。User.Read、Files.ReadWrite、offline_accessを追加します。offline_accessを入れないと「リフレッシュトークン」が取得できないので、注意。
- 保存ボタンを押して完了です。
図:スコープの設定で許可するアクションを選びます。
認証を行う処理を作成する
OAuth2 for Apps Scriptのページの「Create the OAuth2 Service」にあるコードを元に、Google Apps Script側で構築をします。この時、Microsoft365側で取得したアプリケーションIDやシークレットを使います。
GAS側コード
//メニューを構築する
function onOpen(e) {
var ui = SpreadsheetApp.getUi();
ui.createMenu('▶OAuth認証')
.addItem('認証の実行', 'startoauth')
.addSeparator()
.addItem('ログアウト', 'reset')
.addToUi();
}
//認証用の各種変数
var appid = 'ここにアプリケーションIDを入れます';
var appsecret='ここにアプリケーションシークレットを入れます。';
var scope = "User.Read Files.ReadWrite offline_access"
var endpoint = "https://graph.microsoft.com/v1.0"
var targetfile = "ここにターゲットとなるxlsxファイル名を入れます。"
var tokenurl = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
var authurl = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"
function startoauth(){
//UIを取得する
var ui = SpreadsheetApp.getUi();
//認証済みかチェックする
var service = checkOAuth();
if (!service.hasAccess()) {
//認証画面を出力
var output = HtmlService.createHtmlOutputFromFile('template').setHeight(310).setWidth(500).setSandboxMode(HtmlService.SandboxMode.IFRAME);
ui.showModalDialog(output, 'OAuth2.0認証');
} else {
//認証済みなので終了する
ui.alert("すでに認証済みです。");
}
}
//アクセストークンURLを含んだHTMLを返す関数
function authpage(){
var service = checkOAuth();
var authorizationUrl = service.getAuthorizationUrl();
var html = "<center><b><a href='" + authorizationUrl + "' target='_blank' onclick='closeMe();'>アクセス承認</a></b></center>"
return html;
}
//認証チェック
function checkOAuth() {
return OAuth2.createService("Microsoft Graph")
.setAuthorizationBaseUrl(authurl)
.setTokenUrl(tokenurl)
.setClientId(appid)
.setClientSecret(appsecret)
.setScope(scope)
.setCallbackFunction("authCallback") //認証を受けたら受け取る関数を指定する
.setPropertyStore(PropertiesService.getScriptProperties()) //スクリプトプロパティに保存する
.setParam("response_type", "code");
}
//認証コールバック
function authCallback(request) {
var service = checkOAuth();
Logger.log(request);
var isAuthorized = service.handleCallback(request);
if (isAuthorized) {
return HtmlService.createHtmlOutput("認証に成功しました。ページを閉じてください。");
} else {
return HtmlService.createHtmlOutput("認証に失敗しました。");
}
}
//ログアウト
function reset() {
checkOAuth().reset();
SpreadsheetApp.getUi().alert("ログアウトしました。")
}
HTML側コード
template.htmlというダイアログ用のファイルを用意します。ここでアクセス承認を実行し、ログインをすると、アクセストークンその他が取得可能になります。
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
<script type="text/javascript" src="https://apis.google.com/js/api.js"></script>
<script>
google.script.run.withSuccessHandler(onSuccess).authpage();
function onSuccess(data){
document.getElementById("kinoko").innerHTML = data;
}
</script>
<style type="text/css">
/* --- ボックス --- */
div.section {
width: 480px; /* ボックスの幅 */
background-color: #ffffff; /* ボックスの背景色 */
border: 1px #c0c0c0 solid; /* ボックスの境界線 */
font-size: 100%; /* ボックスの文字サイズ */
}
/* --- 見出し --- */
div.section h3 {
margin: 0; /* 見出しのマージン */
padding: 6px 10px; /* 見出しのパディング(上下、左右) */
background-color: #f5f5f5; /* 見出しの背景色 */
border-bottom: 1px #c0c0c0 solid; /* 見出しの下境界線 */
font-size: 120%; /* 見出しの文字サイズ */
}
/* --- ボックス内の段落 --- */
div.section p {
margin: 1em 10px; /* 段落のマージン(上下、左右) */
}
</style>
<div class='section'>
<img border="0" src="http://blog.movereem.nl/images/oauth.png" alt="oauth2">
<h3 id='header'>OAuth認証の許可が必要です。</h3>
<hr>
<div id="info">
<p>
このスクリプトは、Microsoft Graph APIにアクセスするために、特別なログイン処理を利用しています。<br>
既に特別なログインに関する設定はなされており、承認がされるとプログラムを実行することが出来ます。この承認がなされない場合、プログラムの実行に制限が掛かり、
処理が続行できません。<br><br>
<div id="kinoko"></div>
</div>
<p>
<script>
function closeMe(){
if(google && google.script && google.script.host){
google.script.host.close();
} else if(window && window.close){
window.close();
}
}
</script>
</div>
- 実際にこれらのコードで、startoauthを実行すると、スプレッドシート上で認証用のダイアログが出ます。
- 認証でMicrosoft365アカウントにログインします。
- 取得したAccess Tokenほかはスクリプトプロパティのoauth2.Microsoft Graphという項目にガッツリ値が格納されます。ここにはAccess Token, Refresh Token, expire_inのタイムなどが入っています。
- reset関数はログアウトされて、再度認証ができるようになります。
図:Microsoft側でのOAuth認証画面





