GoogleAppsScriptを使ってTwitter APIを叩いていたものがあったのですが、7/7に動作しなかったことがあったため、原因と対応した時のメモを残します。
経緯
6月中旬にGoogleよりこんな感じのメールが来ていました。
件名:対応のお願い: ご使用の Google Apps アカウントの Apps スクリプトで、廃止された OAuthConfig プロトコルが使われています - 移行が必要です 本文: 管理者の皆様 OAuth1 は 2012 年にサポートを終了し、2015 年 4 月に無効になりました。OAuthConfig for Apps Script は、2015 年 3 月 4 日にお知らせしたとおり、サポートを終了しました。ご使用の Google Apps ドメインでは、クラス OAuthConfig を介して OAuth1 呼び出しがまだ行われているようなので、ご連絡いたしました。 2015 年 7 月 6 日をもって OAuthConfig は無効になるため、ユーザーにはエラーが表示されることが予想されます。サービスの中断を避けるために、できるだけ早く以下の対応を取ることを強くおすすめします。 ドメインの Apps スクリプトのオーナーおよびユーザーに、OAuthConfig(Apps スクリプト アプリケーションの OAuthConfig API で使用)が 2015 年 7 月 6 日以降は動作しなくなることを連絡してください。 正常な動作を維持するには、Apps スクリプトのオーナーはこちらの移行手順に沿って、最新のオープン ソース ライブラリに移行する必要があります。
特に問題ないだろうと放置していたところ、7/7に動かないTwitterアプリがありました。デバッグ実行をしてみたところ、
スクリプトでサポートが終了した OAuthConfig を使用しています。詳しくは http://goo.gl/IwCSaV をご覧ください。
というエラーメッセージが出て、動作しませんでした。
そこで調べてみたところ、以下の記事の通り、2015/7/6に機能がシャットダウンされていました。
Changes to OAuth in Apps Script - Google Apps Developer Blog
また、マイグレーションガイドによれば、今までと同様にOAuth1系を使おうとすると、自分で実装するか、Google製のライブラリを使えば良さそうでした。
Migrating from OAuthConfig to the OAuth1 library | Apps Script | Google Developers
一方、そもそもOAuth1版のTwitter APIが必要なのかと思い調べてみたところ、OAuth2版(Application-only authentication)のTwitter APIがあり、こちらでも十分なことが分かりました。
Application-only authentication | Twitter Developers
ただ、OAuth2版にもGoogle製のライブラリがあったものの、ソースコードを読んでみたところ、リダイレクトURLの指定があるなど、Twitter API向けのものではなさそうでした。
googlesamples/apps-script-oauth2
そこで、以下を参考に、Application-only authentication用のコードを自分で実装することにしました。
TwitterのApplication-only authenticationを試してみた - (゚∀゚)ktkr!
悩んだところ
Consumer KeyとConsumer Secret のURIエンコード方法
GoogleAppsScriptで用意されている、Utilities.base64EncodeWebSafe()
を使うことにしました。
Class Utilities - base64EncodeWebSafe(data) | Apps Script | Google Developers
JSONのパース
今まで使っていたUtilities.jsonParse
は既に廃止されていたため、以下のガイドラインに従いJSON.parse
を使うことにしました。
- External APIs | Apps Script | Google Developers
- GoogleAppsScript - Google Apps Script でjsonデータの読み込み - Qiita
Twitter のアプリ登録のCallback URLについて
Application-only authenticationでは、今までとは異なりCallback URL
の設定が不要でした。
実装コード
以上を踏まえて実装したのが以下のコードです。
Consumer KeyとConsumer Secretを変更した上で、以下のコードをWebアプリケーションとして公開することで、動作を確認できます。
TWITTER_CONSUMER_KEY = '<your key>'; TWITTER_CONSUMER_SECRET = '<your secret>'; function doGet(e) { // アクセストークンの取得 var tokenUrl = "https://api.twitter.com/oauth2/token"; var tokenCredential = Utilities.base64EncodeWebSafe(TWITTER_CONSUMER_KEY + ":" + TWITTER_CONSUMER_SECRET); var tokenOptions = { headers : { Authorization: "Basic " + tokenCredential, "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" }, method: "post", payload: "grant_type=client_credentials" }; var responseToken = UrlFetchApp.fetch(tokenUrl, tokenOptions); var parsedToken = JSON.parse(responseToken); var token = parsedToken.access_token; // Application-only authenticationでTwitter APIの利用 var apiUrl = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=twitterjp&count=2"; var apiOptions = { headers : { Authorization: 'Bearer ' + token }, "method" : "get" }; var responseApi = UrlFetchApp.fetch(apiUrl, apiOptions); // バリデーション if (responseApi.getResponseCode() !== 200) return ""; var tweets = JSON.parse(responseApi.getContentText()); if (!tweets) return ""; // 結果を表示 var result = ""; for (var i = 0; i < tweets.length; i++) { var tweet = tweets[i].text; var date = new Date(tweets[i].created_at); result += "[" + date.toUTCString() + "]" + tweet + " / "; } return ContentService.createTextOutput(result); }
GitHub上にもソースコードを上げておきました。
thinkAmi-sandbox/GAS-TwitterOAuth2-sample