GASでTwitter APIを使ってみた

Twitterで APIキーを取得するには事前に「デベロッパー申請」が必要です(英語で申請目的などを書く必要があります💧)

  1. ベアラートークンを取得して保存します
  2. ベアラートークンを使ってエンドポイントにリクエストを送ります
目次
  1. トークンを取得
  2. リクエストを送る

トークンを取得

TwitterAPIへのリクエスト用のOAuth 2.0ベアラートークンを取得します
エンドポイント:https://api.twitter.com/oauth2/token
Basic認証:HTTPヘッダでは特殊記号を使用できないのでユーザー名とパスワードをコロン「 :」で区切ってBase64エンコードした文字列(アルファベットと数字と一部の記号だけにする)を使います

function setupToken() {
  const API_KEY = encodeURIComponent('ここにAPI key')
  const SECRET_KEY = encodeURIComponent('ここにAPI secret key')  
  const bt = Utilities.base64Encode(`${API_KEY}:${SECRET_KEY}`);
  const params = {
    "method" : "POST",
    "headers" : {
      "Authorization" : "Basic " +bt,
      "Content-Type" : "application/x-www-form-urlencoded;charset=UTF-8",
      "Accept-Encoding" : "gzip"
    },
    "payload" : {
      "grant_type" : "client_credentials"
    }
  };
  const response = UrlFetchApp.fetch('https://api.twitter.com/oauth2/token', params);
  const data = JSON.parse(response.getContentText());
  console.log(data)
}

// { token_type: 'bearer',
//   access_token: 'AAAAAAAAA...' }

GASのPropertiesServiceクラスを利用してトークンを保存します(Key-Value形式のデータを保存できます)
例として:別の関数(getToken)から保存したトークンを呼び出します

function setupToken() {
 //省略
  const data = JSON.parse(response.getContentText());
 // console.log(data)
 if(data.access_token){
    PropertiesService.getScriptProperties().setProperty("TOKEN", data.access_token);
  } 
}

function getToken(){
  const token =  PropertiesService.getScriptProperties().getProperty("TOKEN");
  console.log(token);
}

リクエストを送る

検索キーワードからツイートを取得する例

function search() {
  const token =  PropertiesService.getScriptProperties().getProperty("TOKEN");
  if(token === null){
    token = setupToken();
  }  
//エンドポイント
  const url = `https://api.twitter.com/1.1/search/tweets.json?q=${検索ワード}&count=1`;
  const params = {
    "method" : "GET",
    "headers" : {
      "Authorization" : "Bearer " +token  ,
      "Content-Type" : "application/x-www-form-urlencoded;charset=UTF-8",
      "Accept-Encoding" : "gzip"
    },
   // "followRedirects" : true,
   // "muteHttpExceptions" : true
  };
  const response = UrlFetchApp.fetch(url, params);
  const data = JSON.parse(response.getContentText());
  const tweet = data.statuses;
  console.log(tweet);  
}

備考

  • Content-Type:”application/x-www-form-urlencoded;charset=UTF-8″
    キーと値が ‘=’ で挟まれ ‘&’ で区切られてエンコードされる
  • ContentType :”application/json”
    JSON形式で{“a”:1,”b”:2}で送る:JSON.stringify(params)

Accept-Encodingはサポートしている圧縮方式を伝えてその方式で返却してもらう

  • muteHttpExceptions:true
    404などエラーの場合でもレスポンスを返します
  • validateHttpsCertificates:true
    true : SSL証明書エラーが発生した場合でも処理を継続します。
  • followRedirects:true
    参照先にてリダイレクトが発生した場合、リダイレクト先を参照します

複数のアカウントの固定ツイートを取得して、シートに書き出したかったので
*IDはhttps://tweeterid.com/で検索
*パラメータにexpansions=pinned_tweet_idを追加すると固定ツイートがあれば取得できます
https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users#requests

//固定ツイート本文にURLがあればリンクにするため
function AutoLink(str) {
    var regexp_url = /((h?)(ttps?:\/\/[a-zA-Z0-9.\-_@:/~?%&;=+#',()*!]+))/g; // ']))/;
    var regexp_makeLink = function(all, url, h, href) {
	  return '<a href="h' + href + '">' + url + '</a>';
    }
    return str.replace(regexp_url, regexp_makeLink);
}

function createData() {
  const data =[]
  const token =  PropertiesService.getScriptProperties().getProperty("TOKEN");
  if(token === null){
    token = setupToken();
  }  
//エンドポイント
  const url = 'https://api.twitter.com/2/users?ids=1つ目のID,2つ目のID,3つ目のID,...&expansions=pinned_tweet_id';
  const params = {
    "method" : "GET",
    "headers" : {
      "Authorization" : "Bearer " +token,
      "Content-Type" : "application/x-www-form-urlencoded;charset=UTF-8",
      "Accept-Encoding" : "gzip"
    },
  };
  const response = UrlFetchApp.fetch(url, params);
  const res = JSON.parse(response.getContentText());
  //console.log(res)
  const contents = res.includes.tweets

 contents.forEach((content)=>{
//必要な場合 HTMLタグの整形
    let text = content.text.replace(/\n/g, '<br>')
    text = AutoLink(text)
    data.push([text])
   })
  //シートに書き込む
  const ss = SpreadsheetApp.openById('シートのID');
  const sheet = ss.getSheetByName('data');
  let row = data.length;
  let col = data[0].length;
  let range = sheet.getRange(1, 1, row, col);
  range.setValues(data);
}