Google Apps Script(GAS)でTwitter API v2の非公開統計情報を取得する
こんにちは。
リケイのオコジョです。
はじめに
Google Apps ScriptでTwitter API v2の非公開統計情報を取得する方法をまとめます。
「非公開統計情報」 と書くとなんだかイケナイ雰囲気がありますが、Twitterアナリティクスのインプレッションやエンゲージメントなど、non_public_metrics
を取得するというお話です。
「うわっ…私のインプレッション、低すぎ…?」
Twitter API v2について
従来、non_public_metrics
の取得はOAuth 1.0aというハードルを越える必要がありました。
Twitter API v2ではOAuth 2.0 User Context authenticationという、それなりに一般的な方式でもnon_public_metrics
を取得することができるようになりました。
今回はGoogle Apps Scriptから試してみましょう。
Twitterの設定
まずはTwitter側の設定をDeveloper Dashboardから行います。
認証の設定からOAuth2.0
をON
にし、Type of App
としてWeb App
を選択することでConfidential Client
としてAPIを利用する設定を行います。
Callback URI
は以下のようにスクリプトID
を含ませたURIを利用します。
スクリプトID
はGoogle Apps Scriptのプロジェクトの設定
画面から確認できます。
https://script.google.com/macros/d/<スクリプトID>/usercallback
後ほどGoogle Apps Scriptのスクリプトプロパティに登録するOAuth 2.0 Client ID and Client Secret
を取得しておきます。
Google Apps Scriptの設定
Google Apps Scriptの初期設定や基本的な使い方は以下の記事にまとめています。
今回、TwitterのAPIを利用するため、libraryとしてOAuth2
と、Google Apps Script自体のScopeとしてexternal_request
を設定する必要があります。
{
"timeZone": "Asia/Tokyo",
"dependencies": {
"libraries": [
{
"userSymbol": "OAuth2",
"version": "41",
"libraryId": "1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF"
}
]
},
"oauthScopes": [
"https://www.googleapis.com/auth/script.external_request"
],
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}
スクリプトプロパティに先ほど取得したCLIENT_ID
とCLIENT_SECRET
を設定しておきます。
いつの間にかスクリプトプロパティが新UIからも設定できるようになりましたね。
Google Apps ScriptからTwitter API v2を利用する
まずはOAuth 2.0 Authorization Code Flow with PKCEでアクセストークンを取得します。
function getService() {
pkceChallengeVerifier();
const userProps = PropertiesService.getUserProperties();
const scriptProps = PropertiesService.getScriptProperties();
const clientId = scriptProps.getProperty('CLIENT_ID');
const clientSecret = scriptProps.getProperty('CLIENT_SECRET');
return OAuth2.createService('twitter')
.setAuthorizationBaseUrl('https://twitter.com/i/oauth2/authorize')
.setTokenUrl('https://api.twitter.com/2/oauth2/token?code_verifier=' + userProps.getProperty("code_verifier"))
.setClientId(clientId)
.setClientSecret(clientSecret)
.setCallbackFunction('authCallback')
.setPropertyStore(userProps)
.setScope('users.read tweet.read offline.access')
.setParam('response_type', 'code')
.setParam('code_challenge_method', 'S256')
.setParam('code_challenge', userProps.getProperty("code_challenge"))
.setTokenHeaders({
'Authorization': 'Basic ' + Utilities.base64Encode(clientId + ':' + clientSecret),
'Content-Type': 'application/x-www-form-urlencoded'
})
}
function authCallback(request) {
const service = getService();
const authorized = service.handleCallback(request);
if (authorized) {
return HtmlService.createHtmlOutput('Success!');
} else {
return HtmlService.createHtmlOutput('Denied.');
}
}
function pkceChallengeVerifier() {
var userProps = PropertiesService.getUserProperties();
if (!userProps.getProperty("code_verifier")) {
var verifier = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
for (var i = 0; i < 128; i++) {
verifier += possible.charAt(Math.floor(Math.random() * possible.length));
}
var sha256Hash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, verifier)
var challenge = Utilities.base64Encode(sha256Hash)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '')
userProps.setProperty("code_verifier", verifier)
userProps.setProperty("code_challenge", challenge)
}
}
OAuth2.createService('twitter')
で以下のような認可リクエストを作成しています。
https://twitter.com/i/oauth2/authorize?client_id=<CLIENT ID>&response_type=code&redirect_uri=<https://script.google.com/macros/d/<スクリプトID>/usercallback>&state=<STATE>&scope=<SCOPE>&code_challenge_method=S256&code_challenge=<CODE CHALLENGE>
各パラメータについては以下の記事が詳しいです。
-
state
.setParam
でstate
を指定していませんが、OAuth2ライブラリが自動で生成/検証してくれるようです。 -
scope
ドキュメントにある通りGET /2/tweets/:id
にはtweet.read users.read
が必要です。 -
code_verifierとcode_challenge
PKCE(Proof Key for Code Exchange)の仕様はrfc7636です。
Google Apps ScriptでTwitter API v2の非公開統計情報を取得する
.hasAccess()
でアクセストークンの状態を確認できます。
Authorizationヘッダー
にアクセストークンをのせ/2/tweets/:id
に対し?tweet.fields=non_public_metrics
のクエリパラメータを付与しGETリクエストします。
function main() {
const service = getService();
if (service.hasAccess()) {
const url = 'https://api.twitter.com/2/tweets/<TWEET ID>?tweet.fields=public_metrics,created_at,non_public_metrics';
const response = UrlFetchApp.fetch(url, {
headers: {
Authorization: 'Bearer ' + service.getAccessToken()
},
muteHttpExceptions: true
});
const result = JSON.parse(response.getContentText());
Logger.log(JSON.stringify(result, null, 2));
} else {
const authorizationUrl = service.getAuthorizationUrl();
Logger.log('Open the following URL and re-run the script: %s', authorizationUrl);
}
}
結果は以下のような感じです。
{
"data": {
"non_public_metrics": {
"impression_count": 157,
"url_link_clicks": 32,
"user_profile_clicks": 1
}
}
}
「うわっ…私のインプレッション、低すぎ…?」
はい。ぜひフォローしてください。
まとめ
Google Apps ScriptでTwitter API v2の非公開統計情報を取得する方法をまとめました。
定期実行し、Google Sheetsに書き出したりなど活用シーンが広がりそうですね。
参考
Discussion