28
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[GAS] GoogleAppsScriptでTwitterbotを作る

Last updated at Posted at 2019-03-13

動機

毎日自動でTwitterの名前を変えたかった。

要件

  • ある1ユーザーのTwitterの名前を毎日0時に自動で変更したい

前提知識

  • TwitterAPIはOAuth認証を用いる
  • OAuthは現在主に用いられているバージョンとして1.0a2.0の2つがある
    • 単なるバージョン違いという訳ではなく、認証の仕組みから違うため、別物である(互換性がない)
  • TwitterAPIではOAuth2.0での認証は一部のAPIしか対応していないため、1.0aを使う

TwitterAPIの利用準備

TwitterAPIを用いるには開発者申請が必要。
Twitter API 登録 (アカウント申請方法) から承認されるまでの手順まとめ ※2018年9月時点の情報 - Qiita

GASでTwitterAPIを使う方法

公式でGASでOAuth1.0a認証をやるためのライブラリがあるのでそれを使う。
https://github.com/gsuitedevs/apps-script-oauth1

ちなみにOAuth2.0用のライブラリも存在するが、そもそもの認証の仕組みが違うので、1.0aには使えないため注意。

1. ライブラリを導入する

README.mdに書かれている通りに進める。
GASのメニューから「リソース」->「ライブラリ」を選択し、以下のプロジェクトキーを入力し「追加」を押す。
1CXDCY5sqT9ph64fFwSzVtXnbjpSfWdRymafDrtIZ7Z_hwysTY7IIhi7s

バージョンはとりあえず最新のものを選んでおけば良さそう。

2. TwitterのAppにリダイレクトURLを設定する

リダイレクトURLはhttps://script.google.com/macros/d/{SCRIPT ID}/usercallbackという形式になる。
スクリプトIDはGASのメニューから「ファイル」->「プロジェクトのプロパティ」で確認できる。

TwitterのAppの設定を開き、CallbackURLに設定する。

3. 対象ユーザーのアクセストークンを取得する

まず以下のようなスクリプトを用意する。

// Twitter AppのConsumer Api Key
var CONSUMER_KEY = "*****";
var CONSUMER_SECRET = "************";

// 認証URLを取得しログに出力する
function logAuthorizeUri() {
  var twitterService = getTwitterService();
  Logger.log(twitterService.authorize());
}

// OAuth認証をよしなにしてくれるサービスクラスのインスタンスを生成・取得する
function getTwitterService() {
  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/authenticate')
      .setConsumerKey(CONSUMER_KEY)
      .setConsumerSecret(CONSUMER_SECRET)
      // リダイレクト時に実行されるコールバック関数を指定する
      .setCallbackFunction('authCallback')
      // アクセストークンを保存するPropertyStoreを指定する
      .setPropertyStore(PropertiesService.getUserProperties());
}

// リダイレクト時に実行されるコールバック関数
function authCallback(request) {
  var twitterService = getTwitterService();
  // ここで認証成功時にアクセストークンがPropertyStoreに保存される
  var isAuthorized = twitterService.handleCallback(request);
  if (isAuthorized) {
    return HtmlService.createHtmlOutput('Success');
  } else {
    return HtmlService.createHtmlOutput('Denied');
  }
}

CONSUMER_KEY,CONSUMER_SECRETはTwitterAppの設定画面から確認できる。

image.png

認証手順

logAuthorizeUriを実行し、認証URLを取得する。

ログにURLが出力されているので、メニューの「表示」->「ログ」からログを表示し、URLをコピーしてアドレスバーに貼って直接アクセスする。
(普通のTwitterアプリだと自動で移動するが、GASのstandalone scriptだとそれができないためこういった形になる)

アクセスするとTwitterの認証画面が出るので、認証ボタンを押す。

リダイレクトされて以下のような画面が出れば成功。

一度認証を行うと、Twitter側で認証を解除しない限り同じアクセストークンが使える。
アクセストークンはPropertyStore上に保持されているため、認証が解除されない限りこの手順をもう一度行う必要は無い。

参考:GASで永続化する方法まとめ(設定や処理結果を保存・読み込みしたい時) - Qiita

4. TwitterAPIを叩く

以降はOAuthのライブラリがよしなにしてくれるので、難しいことを気にせずともAPIを叩くことができる。
例えば名前を変更したいなら以下のような感じ。makeRequestchangeNameが肝。

API:POST account/update_profile — Twitter Developers

// 名前を今日の日付に変更する
function changeTodayName()
{
  var todayName = getTodayName();
  changeName(todayName);
}

// 今日の名前を取得する
function getTodayName()
{
  // TODO: 日によってちゃんと変わるように実装する
  return "テスト";
}

// Twitterに名前変更のリクエストを送る
// name: 変更したい名前
function changeName(name)
{
  makeRequest("account/update_profile.json", {"name": name});
}

// TwitterにAPIリクエストを送る
function makeRequest(api_url, parameters) {
  var twitterService = getTwitterService();
  if (twitterService.hasAccess()) {
    var url = 'https://api.twitter.com/1.1/' + api_url;
    var response = twitterService.fetch(url, {
      method: "post",
      muteHttpExceptions: true,
      payload: parameters
    });
    var result = JSON.parse(response.getContentText());
    Logger.log(JSON.stringify(result, null, 2));
  } else {
    Logger.log(service.getLastError());
  }
}

changeTodayNameを実行すると名前が「テスト」に変わることが確認できる。

5. 毎日0時にトリガーを設定する

毎日0時に名前を変更するために、自動で実行するための設定を行う。

メニューの「編集」->「現在のプロジェクトのトリガー」から設定画面に移行し、右下の「トリガーを追加」ボタンを押す。

よしなに設定を行い、「保存」で終了。

日付ベースの設定だと分単位で指定できないので、厳密に0時0分に変更したい場合には分ベースで1分単位で実行し、スクリプト側で時間判定を行ってAPIを叩くのが良さそう。

まとめ

  • TwitterAPIはOAuth1.0aが標準であり、2.0では一部APIしか使うことができない(2019/03現在)
  • GASでOAuth認証を行うためのライブラリが公式で用意されている
  • GASにはPropertiesServiceというデータ永続化のための便利クラスがあり、そこにアクセストークンを保持することで認証状態を保持できる

OAuth1.0aと2.0で情報が錯綜しているのと、GASでTwitterAPIを使うスクリプトは各所にあるものの、動作原理が解説されておらずいまいち理解できなかった(特にアクセストークンがどこに保持されるのかわからなかった)ので、少し苦労しました。
スプレッドシートと連携したりすればもっと色々できると思います。

参考資料

28
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?