GASでTwitterAPIを叩いてみる

はじめに

はじめまして。TechDivの森川です。
今回はGAS(Google Apps Script)を使ってTwitterAPIを使用する方法について書いていきたいと思います。

なぜGASとTwitter(API)を使うのか

私がAPIの勉強をする際に最初に選択したのがGASとTwitterでした。
・知名度がある
・日本語の記事が多い
・無料
・ブラウザさえあればいいので個人の環境に影響されにくい
 …etc
こういった点から、非常にとっつきやすいと感じました。
また、GASに関しては他のGoogleの機能(Gmailやスプレッドシート)、Twitterに関しては他の媒体(アプリやブログ等)との連携が容易に行えることから、拡張性の高さもポイントの一つです。
今回はそんなGASとTwitterを使い、定番のおみくじBotを作るところまでやっていこうと思います。

APIを叩くまでの流れ

実際にAPI叩くまでの流れはざっくりと以下の通りです。
1.GoogleのアカウントとTwitterのアカウントを用意する
2.Twitterアカウントに開発者権限を付与
3.2のアカウントでキーとトークン(認証情報)を発行
4.3の情報を元にGASで認証を行う
5.簡単なプログラム書いて実際にAPI 叩いてみる

今回は3から説明していきます。
1,2は調べればいろいろと出てきますので、事前に「google アカウント 作成」や「twitter 開発者 申請」で検索して作成してください。

認証情報を発行する

というわけで、アカウントに開発者権限付与が完了したところから解説していきます。
認証情報の発行は、Twitter開発者アカウントでアプリを作成する必要があります。
(ここでいうアプリとはプログラミングをして作るようなものではなく、「アプリの情報」位の認識でOKです。)

まずは作成していただいたTwitterの開発者アカウントにログインにします。
https://developer.twitter.com/
ログインすると右上に「Create an app」というボタンがあるのでそれを選択します。

選択後アプリ情報の記入を求められるので、必須項目は下記の通り入力し、それ以外の項目は初期値のままにしておいてください。
入力が完了したら「Create」を選択します。
※基本的には英語で入力しますが、Google翻訳レベルで問題ありません。

アプリ名:自由に入力してください。ただし、ユニークである必要があります。
アプリの説明:取得した認証情報を使うアプリの機能について記入してください。
ウェブサイトのURL:自分のブログで使いたい場合などは、そのブログのURLを入力してください。
          今回は無いので、アカウントのホームのURLを指定してください。
          例:https://twitter.com/アカウントID
コールバックURL:Twitterの認証が通った後に飛ばされる画面のURLです。
         今回はあとで入れることになるので、一旦空白で大丈夫です。
アプリの使い方:アプリの使い方について説明します。
        アプリの説明に記入した内容と同じでもかまいません。

アプリ作成後、下記のような画面になるので上部の「Keys and tokens」を選択します。

すると下記のような画面になるので、画面右側の「Regenerate」および「Generate」で認証情報を作成します。

GASで認証を行う(設定編)

認証情報が取得できたので次はGASを使って認証を行っていきますが、長くなりそうなので設定と実装で分割します。
設定編ではGASのライブラリや認証情報発行で後回しにしたコールバックURLの設定を行います。

まずはGoogleのドライブから「新規」⇒「その他」⇒「Google Apps Script」を選択します。
メニューバーの「リソース」⇒「ライブラリ」を選択すると下記の画面が出てくるので、テキストボックスに次の2つのコードを入力、追加してください。(バージョンは最新のものでOK)1CXDCY5sqT9ph64fFwSzVtXnbjpSfWdRymafDrtIZ7Z_hwysTY7IIhi7s
1rgo8rXsxi1DxI_5Xgo_t3irTw1Y5cxl2mGSkbozKsSXf2E_KBBPC3xTF

次はコールバックURLを設定します。
GASのメニューバーから「ファイル」⇒「プロジェクトのプロパティ」⇒「情報」タブにスクリプトIDがあるので、これを以下の形式にして設定します。
https://script.google.com/macros/d/スクリプトID/usercallback

以上で設定は完了です。

GASで認証を行う(実装編)

設定が完了したら認証のためのソースを記述します。

まず、GASのエディタからスクリプトのプロパティの設定を行います。
「ファイル」⇒「プロジェクトのプロパティ」⇒「スクリプトのプロパティ」⇒「+行を追加」を選択し、以下の2項目を設定し保存します。
プロパティ:CONSUMER_API_KEY、CONSUMER_API_SECRET
値:それぞれ発行した認証情報を入力

上記設定後、以下のソースをコード.gsに張り付けます。

// 認証用URL取得
function getOAuthURL() {
  Logger.log(getService().authorize());
}

// サービス取得
function getService() {
  return OAuth1.createService('Twitter')
      .setAccessTokenUrl('https://api.twitter.com/oauth/access_token')
      .setRequestTokenUrl('https://api.twitter.com/oauth/request_token')
      .setAuthorizationUrl('https://api.twitter.com/oauth/authorize')
      // 設定した認証情報をセット
      .setConsumerKey(PropertiesService.getScriptProperties().getProperty("CONSUMER_API_KEY"))
      .setConsumerSecret(PropertiesService.getScriptProperties().getProperty("CONSUMER_API_SECRET"))
      .setCallbackFunction('authCallback')
      // 認証情報をプロパティストアにセット(これにより認証解除するまで再認証が不要になる)
      .setPropertyStore(PropertiesService.getUserProperties());
}

//  認証成功時に呼び出される処理を定義
function authCallback(request) {
  var service = getService();
  var authorized = service.handleCallback(request);
  if (authorized) {
    return HtmlService.createHtmlOutput('success!!');
  } else {
    return HtmlService.createHtmlOutput('failed');
  }    
}

「実行」⇒「関数の実行」⇒「getOAuthURL」から関数を実行します
初めてGASを実行する場合は確認が行われるので画面の通りに進んでください。

ここまで入力したらエディタに戻ります。
ログを開く(ctrl+Enter)とURLが出力されているので、そのページを開きます。

ページを開くと下記のような画面になるので、「連携アプリを認証」を選択

認証がうまくいっていた場合は以下の画面に遷移します。
以上で認証は完了です。

APIを叩く

ここまで来たら後は実際にAPIを叩くだけです。
今回はタイムライン取得(GET)とツイート(POST)のAPIを叩いてみます。
※他にも種類は豊富なので興味のある方はぜひ叩いてみてください。
https://developer.twitter.com/en/docs/api-reference-index

まずはタイムライン取得の方から叩いてみます。
下記のソースをコード.gsに追加、もしくは新規スクリプトファイルを作成してペーストしてください。
実行は認証時と同様メニューバーの「実行」から可能です。

// タイムライン取得用のAPIを起動する関数
function getTimeLine() {
  var twitterService = getService();
  
  if (twitterService.hasAccess()) {
    // タイムライン取得
    var twMethod = { method:"GET" };
    var json = twitterService.fetch("https://api.twitter.com/1.1/statuses/home_timeline.json?count=5", twMethod);

    // json形式で返ってくるのでパース
    var array = JSON.parse(json);
    
    // パースされた形式から欲しい項目のみ取得(今回はテキスト)
    var tweets = array.map(function(tweet){
      return tweet.text;
    });
    
    // 取得した項目をログに表示
    Logger.log(tweets);
  } else {
    Logger.log(service.getLastError());
  }
}


実行するとログに取得したツイート本文が出力されているはずです。
今回は事前に「ツイート1」~ 「ツイート5」とつぶやいておいたので、以下のような出力になりました。

twitterService.fetchは、APIを使用するためのエンドポイントとHTTPメソッドを設定するとリクエストを送ってくれる関数です。
fetch関数でリクエストを送るとjson形式でレスポンスが返ってきますので、これをパースしたものをarrayに格納しています。arrayの中からtext項目のみを抜き出したものをtweetsに格納し、ログに出力したものが上の「ツイート5, ツイート4…」です。
今回はtextを抽出していますが、idやname等arrayに格納された値に存在するものであれば項目名を指定して取り出すことができます。

次にツイートの方を叩いてみます。

// ツイート用のAPIを起動する関数
function toTweet() {
  var twitterService = getService();
  
  if (twitterService.hasAccess()) {
    // 投稿
    var twMethod = { method:"POST" };
    twMethod.payload = { status: "てっくぶろぐ" };
    var response = twitterService.fetch("https://api.twitter.com/1.1/statuses/update.json", twMethod);
    
    Logger.log(response.getContentText());

  } else {
    Logger.log(service.getLastError());
  }
}


基本的なつくりはタイムライン取得とほとんど変わりません。
methodにPOSTを指定し、投稿したい内容をtwMethod.payloadでstatusに記述するくらいです。

ツイート⇒タイムライン取得の順にAPIを叩くと、タイムライン側のログで表示される内容にツイートしたものが追加されていることがわかると思います。

おみくじBotを作る

Botの機能は、特定の時間になると「MM/dd HH:mmの運勢は○○です」とツイートするものにします。

まずはスプレッドシートを新規作成し、出力内容を設定するシートとトリガーを設定するシートを作成します。

次にスクリプトファイルを新規作成し、以下のソースをペーストしてください。
定義ファイルの取得の「xxxxx」には、先ほど作成したスプレッドシートのURLの以下太字部分を設定してください。
https://docs.google.com/spreadsheets/d/xxxxx/edit#gid=yyyyy

// おみくじ結果を取得する関数
function fortune() {
  // 定義ファイルの取得
  var spreadsheet = SpreadsheetApp.openById('xxxxx');
  var sheet = spreadsheet.getSheetByName('おみくじ');

  // 項目数を取得
  const count = sheet.getRange('B:B').getValues().filter(String).length - 1;
  
  // 出力する運勢の一覧を取得する
  var fortuneList = sheet.getRange(2, 2, count, 1).getValues();
  var random = Math.floor(Math.random()*(count))
  
  // 取得した運勢を出力する関数へ引き渡す
  fortuneTweet(fortuneList[random]);
}

// おみくじ結果をツイートする関数
function fortuneTweet(msg) {
  var twitterService = getService();
  // 現在日時を取得
  var date = new Date();
  var formatDate = Utilities.formatDate( date, 'Asia/Tokyo', 'MM/dd HH:mm');  

  if (twitterService.hasAccess()) {
    // 投稿(「MM/dd HH:mmの運勢は○○です」と出力)
    var twMethod = { method:"POST" };
    twMethod.payload = { status: formatDate + "の運勢は" + msg + "です"};
    var response = twitterService.fetch("https://api.twitter.com/1.1/statuses/update.json", twMethod);

  } else {
    Logger.log(service.getLastError());
  }
}


続いてもう一つスクリプトファイルを新規作成し、以下ソースをペーストしてください。
こちらはトリガー設定用のスクリプトになります。

// トリガーの更新を行う関数
function UpdateTrigger(){
  // トリガーの更新
  deleteTrigger();
  setTrigger();
}

// トリガーを設定する関数
function setTrigger(){
  // 定義ファイルの取得
  var spreadsheet = SpreadsheetApp.openById('1Cknox3JmYXaHRr5QsxL87rlS7gGeOlY0VdZkgMFsy-M');
  var triggerSheet = spreadsheet.getSheetByName('起動時間設定');
  
  // 項目数を取得
  const triggerCount = triggerSheet.getRange('A:A').getValues().filter(String).length - 1;
  
  // トリガー設定対象の関数名を設定
  var functionName = "fortune";

  // 取得した項目数分トリガーを設定する
  for (var i = 0; i < triggerCount; i++) {
    // 設定する値の取得
    var hour = triggerSheet.getRange(i + 2 , 2).getValue();
    var minute = triggerSheet.getRange(i + 2 , 3).getValue();
    
    // 時分の設定とトリガーの作成
    var setTime = new Date();
    setTime.setHours(hour);
    setTime.setMinutes(minute); 
    ScriptApp.newTrigger(functionName).timeBased().at(setTime).create();
  }
}

// fortuneのトリガーを削除する関数
function deleteTrigger(){
  // fortuneのトリガーを削除
  var triggers = ScriptApp.getProjectTriggers();
  for(var i=0; i < triggers.length; i++) {
    if (triggers[i].getHandlerFunction() == "fortune") {
      ScriptApp.deleteTrigger(triggers[i]);
    }
  }
}


次にトリガーの設定を行います。
「編集」⇒「現在のプロジェクトのトリガー」を選択します。

「トリガーを追加」を選択し、以下のようにトリガーを設定する。
実行する関数を選択:UpdateTrigger
時間ベースのトリガーのタイプを選択:日付ベースのタイマー
時刻を選択:午前0時~1時

以上で準備は完了です。
後は実行せずとも、セットした「UpdateTrigger」のトリガーが毎日0~1時に起動し、自動で当日の「fortune」のトリガーをセットします。
「fortune」の起動時刻はスプレッドシートに記入したものが設定され、毎日該当の時間になるとTwitterに 「MM/dd HH:mmの運勢は○○です」 とツイートするようになります。

試しに「fortune」を手動実行したものがこちらになります。

さいごに

私自身、いろいろ調べたり教えてもらっても実際にやってみないとイメージがつかめないタイプの人間なので、こうやって簡単にAPIを試す環境ができたのは非常に勉強になりました。
今回は簡単なおみくじBotを作成しましたが、TwitterAPIもGASも便利な機能がたくさんあるので、プライベートで勉強がてらアプリを作ってみるのも面白いかなと思います。

これからAPIを触るのでちょっと勉強してみたい!という人のお役にたてたら幸いです。