Google Apps Scriptで取得する手順を書いていきます。
公式のサイトでは外部ライブラリを使っていますが、この記事ではライブラリを使わない方法でアクセストークンを取得してみます。
大きく3つのSTEPで書いていきます。
- アプリの「Client ID」「Client Secret」を取得する
- コールバックURLをGASで作成する
- 連携してアクセストークンを取得する
STEP1 アプリの「Client ID」「Client Secret」を取得する
https://app.secure.freee.co.jp/ を開いて「開発者ページ」をクリックします。
「今すぐアプリを作成」をクリックします。
①「アプリ名」を決めます
②「概要」を入力します
③「利用規約」をチェックします
④「作成」をクリックします
「Client ID」「Client Secret」が表示されます。
STEP2 コールバックURLをGASで作成する
Google Apps Scriptの新規プロジェクトを作成します。
https://script.google.com/macros/create
このような画面が表示されます。
function myFunction() {〜}は削除して、以下のコード.gsをコピーして貼り付けます。
コピーして貼り付けるコード
コード.gsvar client_id = 'Client IDを貼り付けます'; var client_secret = 'Client Secretを貼り付けます'; /************************************ 手順 1. 上部の1,2行目にアプリストアのClient ID, Client Secretを貼り付ける 2. 上部メニューの「公開」>「ウェブアプリケーションとして導入」 >「アプリケーションにアクセスできるユーザー」を全員(匿名ユーザを含む)で「更新」する 3. 「現在のウェブ アプリケーションの URL」をアプリストアの「コールバックURL」に貼り付けて「下書き保存」 4. 「Webアプリ認証用URL」をコピーしてブラウザの新規タブで開いて認証を行うとブラウザにアクセストークンが返ってくる ↓以下のコードは触らなくてOK ************************************/ function doGet(e) {// Web認証用URLを開いたときに動く処理 var response = getAccessToken(e); return ContentService.createTextOutput(response);// ブラウザに表示する } var token_url = 'https://accounts.secure.freee.co.jp/public_api/token'; function getAccessToken(e) {// 認可コードを利用してトークン情報を取得して返す var code = e['parameter']['code']; var payload = { 'grant_type': 'authorization_code', 'client_id': client_id, 'client_secret': client_secret, 'code': code, 'redirect_uri': ScriptApp.getService().getUrl() } var options = { 'method': 'post', 'contentType': 'application/x-www-form-urlencoded', 'payload': payload }; var response = UrlFetchApp.fetch(token_url, options); return response; } |
「ファイル」>「保存」を選択します。
任意の「プロジェクト名」を入力して「OK」をクリックします。
client_idに「Client ID」、client_secretに「Client Secret」の値を入れて保存します。
「公開」>「ウェブアプリケーションとして導入」をクリックします。
「アプリケーションにアクセスできるユーザー」>「全員(匿名ユーザーを含む)」>「導入」
「許可を確認」をクリックします。
自分のアカウントを選択します。
「詳細」をクリックします。
下の方にプロジェクト名のリンクが表示されるのでクリックします。
「許可」をクリックします。
「現在のウェブアプリケーションのURL」が表示されます。
STEP3 連携してアクセストークンを取得する
コールバックURLにGASで作ったウェブアプリのURLを貼り付けて「下書き保存」します。
「Webアプリ認証用URL」をコピーしてブラウザの新規タブで開きます。
「許可する」をクリックします。
ブラウザにaccess_tokenなどが表示されます。
access_tokenの有効期間は24時間です。
refresh_tokenでaccess_tokenを更新することができます。
補足
コード.gs内の
'redirect_uri': ScriptApp.getService().getUrl()
がうまく行かない場合があります。
デプロイしたWebアプリのURLを取得しているのですが、以下のようなエラーが出ます。
https://accounts.secure.freee.co.jp のリクエストに失敗しました(エラー: 401)。サーバー応答の一部: {"error":"invalid_grant","error_description":"指定された認可グラントは不正か、有効期限切れか、無効か、リダイレクトURIが異なるか、もしくは別のクライアントに適用されています。"}(応答の全文を見るには muteHttpExceptions オプションを使用してください)(行 37、ファイル「コード」、プロジェクト「無題のプロジェクト」)
これは、G suiteで使う場合に、GASのWebアプリのURLが変わるのが原因のようです。
(URLにドメインが追加される)
- 「導入」クリック後に表示されるURL
- https://script.google.com/a/macros/s/WEBアプリのID/exec
- それをブラウザで開いたときのURL
- https://script.google.com/a/macros/ドメイン/s/WEBアプリのID/exec
その場合、「現在のウェブアプリケーションのURL」を一度ブラウザで開いてみて、
アドレスバーに表示されるURLを貼り付けてみてください。
コード.gsの
'redirect_uri': ScriptApp.getService().getUrl()
を
'redirect_uri': 'アドレスバーに表示されるURL'
に変えて
「公開」>「ウェブアプリケーションとして導入」でバージョンをあげて「導入(デプロイ)」して、
freeeのアプリストアのコールバックURLの欄にも アドレスバーに表示されるURL を入れて下書き保存するとうまくいくかもしれません。
APPENDIX
/usercallbackを使うと
Who has access to the app: Only myself
Who has access to the app: Only myself
で良さそうです。
コード.gsvar client_id = 'CLIENT_ID'; var client_secret = 'CLIENT_SECRET'; var redirect_uri = getRedirectUri(); function getRedirectUri() { var appUrl = ScriptApp.getService().getUrl();// v8では末尾が/devになる→いつか/execになるかもしれない var splited = appUrl.split("/"); var tail = splited[splited.length-1];// /で分けた最後の部分を取得する→dev var last = "/" + tail;// /devにする var redirect_uri = appUrl.replace(last, "/usercallback");// appUrlの末尾の/devを/usercallbackに変更する // 単純に appUrl.replace("/dev", "/usercallback") としても今はいいけれど、/dev が /execに変わったときにエラーで動かなくなるため、その未来のバグを回避する // バグ報告は上がっている→https://stackoverflow.com/questions/60232532/scriptapp-getservice-geturl-points-to-dev-url-how-can-i-get-it-to-point-to return redirect_uri; } function doGet(e) {// Web認証用URLを開いたときに動く処理 var response = getAccessToken(e); return ContentService.createTextOutput(response);// ブラウザに表示する } var token_url = 'https://accounts.secure.freee.co.jp/public_api/token'; function getAccessToken(e) {// 認可コードを利用してトークン情報を取得して返す var code = e['parameter']['code']; var payload = { 'grant_type': 'authorization_code', 'client_id': client_id, 'client_secret': client_secret, 'code': code, 'redirect_uri': redirect_uri } var options = { 'method': 'post', 'contentType': 'application/x-www-form-urlencoded', 'payload': payload }; var response = UrlFetchApp.fetch(token_url, options); return response; } さらにstateを渡してみる
|
関連記事
freee APIでリフレッシュトークンを使いたい
参考
freee APIとは
https://support.freee.co.jp/hc/ja/articles/115000143186-freee-API%E3%81%A8%E3%81%AF
リファレンス
https://developer.freee.co.jp/docs/accounting/reference
スタートガイド
https://app.secure.freee.co.jp/developers/tutorials
Class StateTokenBuilder
stateとusercallbackの部分はこちらも参考になりました