[GAS]自動いいねをしよう

タイトル通りツイッターで自動いいねをできる方法を紹介していきます。
Google Apps Scriptを使って開発をしていこうと思います。

最初に言っておきますが、僕自身プログラミング歴が1年程度であるため、よくわかっていないがとりあえず使っている部分が多いです。

勉強をするときに"わかる"より"できる"を優先することは良くあると思います。
そして、最初はわからなくてもできる状態になることでわかることがありますので、とりあえずできるようになりましょう。
成功経験を収めましょう。

逆に言えば、プログラミング歴1年でこれは作れます。
なんなら、コピペの能力さえあればできるようになります。
うまくいかないところがあったら質問するか検索するかしてください。

最初に言った通り、自分はまだまだ学習中なので、新しく理解できたらその都度更新していく予定です。

ではでは。


TwitterAPIへの登録

まずはTwitterAPIに登録しましょう。

上記のサイトを見ながらやっていただければ、登録できます。申請がすぐ通るとは限らないので、興味がある人は先に申請することをお勧めします。

英語なので、少々めんどくさいですが、Google翻訳と一緒に頑張ってください。


Google Apps Scriptの使い方

今回使う言語は、Google Apps Scriptです。
名前が長いので、「GAS」と略します。

僕はこのサイトを見ながら使い方を覚えました。今回の本題ではないので、詳しく説明はしません。
僕の中では、「Googleが提供しているJava Script」だと思っています。

環境開発せずに使えるので、プログラミング学習の最初にもってこいの言語だと思います。


[コードの実装] ライブラリ

GASにはライブラリってのがあります。これを使うと、TwitterAPIの処理を簡単に行えます。
では実装していきましょう。

GASを開くと上の方に「リソース」→「ライブラリ」の順で開きます。

そしてその中のライブラリをクリックすると、

これが出てきます。上の画像の赤く囲まれている部分に

OAuth1
「Mb2Vpd5nfD3Pz-_a-39Q4VfxhMjh3Sh48」
TwitterWebService
「MFE2ytR_vQqYfZ9VodecRE0qO0XQ_ydfb」

を入力して追加してください。

バージョンはそれぞれ7と1です。

これでライブラリの追加は完了です。


[コード実装] GASでTwitterをいじるためのコード

// OAuth1認証用インスタンス
var twitter = TwitterWebService.getInstance(
  '①',
  '②'
);

// 認証を行う(必須)
function authorize() {
  twitter.authorize();
}

// 認証をリセット
function reset() {
  twitter.reset();
}

// 認証後のコールバック(必須)
function authCallback(request) {
  return twitter.authCallback(request);
}

TwitterAPIに登録するときに参考にしていただいたサイト
①「Consumer API Key」
②「Consumer API secret Key」
を上のコードの①②にコピペしてください。

authorize()という関数を実行することで、認証が完了します。

実行する前にすることがあるので、それを行いましょう。
「Consumer API Key」「Consumer API secret Key」を取得した時のページを開き「App details」を開いてください。一部を編集していきます。

「Callback URLs」の部分に

https://script.google.com/macros/d/[プロジェクトキー]/usercallback

と打ち込んで保存してください。

プロジェクトキーは、メニュー「ファイル」→「プロジェクトのプロパティ」で見ることができます。

プロジェクトキーの登録が完了したら、authorize()を実行してきましょう。

このサイトのTwitterアプリの認証を行うの部分を見れば認証の仕方がわかると思います。


次にこのコードを先ほどのコードに続けます。

// 最初にこの関数を実行し、ログに出力されたURLにアクセスしてOAuth認証する
function twitterAuthorizeUrl() {
  Twitter.oauth.showUrl();
}

// OAuth認証成功後のコールバック関数
function twitterAuthorizeCallback(request) {
  return Twitter.oauth.callback(request);
}

// OAuth認証のキャッシュをを削除する場合はこれを実行(実行後は再度認証が必要)
function twitterAuthorizeClear() {
  Twitter.oauth.clear();
}

//認証するための関数
var Twitter = {
  projectKey: "③",
  
  consumerKey: "①",
  consumerSecret: "②",
  
  apiUrl: "https://api.twitter.com/1.1/",
  
  oauth: {
    name: "twitter",
    
    service: function(screen_name) {
      // 参照元:https://github.com/googlesamples/apps-script-oauth2
      
      return OAuth1.createService(this.name)
      // Set the endpoint URLs.
      .setAccessTokenUrl('https://api.twitter.com/oauth/access_token')
      .setRequestTokenUrl('https://api.twitter.com/oauth/request_token')
      .setAuthorizationUrl('https://api.twitter.com/oauth/authorize')
      
      // Set the consumer key and secret.
      .setConsumerKey(this.parent.consumerKey)
      .setConsumerSecret(this.parent.consumerSecret)
      
      // Set the project key of the script using this library.
      .setProjectKey(this.parent.projectKey)
      
      
      // Set the name of the callback function in the script referenced
      // above that should be invoked to complete the OAuth flow.
      .setCallbackFunction('twitterAuthorizeCallback')
      
      // Set the property store where authorized tokens should be persisted.
      .setPropertyStore(PropertiesService.getUserProperties());
    },
    
    showUrl: function() {
      var service = this.service();
      if (!service.hasAccess()) {
        Logger.log(service.authorize());
      } else {
        Logger.log("認証済みです");
      }
    },
    
    callback: function (request) {
      var service = this.service();
      var isAuthorized = service.handleCallback(request);
      if (isAuthorized) {
        return HtmlService.createHtmlOutput("認証に成功しました!このタブは閉じてかまいません。");
      } else {
        return HtmlService.createHtmlOutput("認証に失敗しました・・・");
      }
    },
    
    clear: function(){
      OAuth1.createService(this.name)
      .setPropertyStore(PropertiesService.getUserProperties())
      .reset();
    }
  },
  
  api: function(path, data) {
    var that = this, service = this.oauth.service();
    if (!service.hasAccess()) {
      Logger.log("先にOAuth認証してください");
      return false;
    }
    
    path = path.toLowerCase().replace(/^\//, '').replace(/\.json$/, '');
    
    var method = (
      /^statuses\/(destroy\/\d+|update|retweet\/\d+)/.test(path)
      || /^media\/upload/.test(path)
    || /^direct_messages\/(destroy|new)/.test(path)
    || /^friendships\/(create|destroy|update)/.test(path)
    || /^account\/(settings|update|remove)/.test(path)
    || /^blocks\/(create|destroy)/.test(path)
    || /^mutes\/users\/(create|destroy)/.test(path)
    || /^favorites\/(destroy|create)/.test(path)
    || /^lists\/[^\/]+\/(destroy|create|update)/.test(path)
    || /^saved_searches\/(create|destroy)/.test(path)
    || /^geo\/place/.test(path)
    || /^users\/report_spam/.test(path)
    ) ? "post" : "get";
    
    var url = this.apiUrl + path + ".json";
    var options = {
      method: method,
      muteHttpExceptions: true
    };
    
    if ("get" === method) {
      if (!this.isEmpty(data)) {
        url += '?' + Object.keys(data).map(function(key) {
          return that.encodeRfc3986(key) + '=' + that.encodeRfc3986(data[key]);
        }).join('&');
      }
    } else if ("post" == method) {
      if (!this.isEmpty(data)) {
        options.payload = Object.keys(data).map(function(key) {
          return that.encodeRfc3986(key) + '=' + that.encodeRfc3986(data[key]);
        }).join('&');
        
        if (data.media) {
          options.contentType = "multipart/form-data;charset=UTF-8";
        }
      }
    }
    
    try {
      var result = service.fetch(url, options);
      var json = JSON.parse(result.getContentText());
      if (json) {
        if (json.error) {
          throw new Error(json.error + " (" + json.request + ")");
        } else if (json.errors) {
          var err = [];
          for (var i = 0, l = json.errors.length; i < l; i++) {
            var error = json.errors[i];
            err.push(error.message + " (code: " + error.code + ")");
          }
          throw new Error(err.join("\n"));
        } else {
          return json;
        }
      }
    } catch(e) {
      this.error(e);
    }
    
    return false;
  },
  
  error: function(error) {
    var message = null;
    if ('object' === typeof error && error.message) {
      message = error.message + " ('" + error.fileName + '.gs:' + error.lineNumber +")";
    } else {
      message = error;
    }
    
    Logger.log(message);
  },
  
  isEmpty: function(obj) {
    if (obj == null) return true;
    if (obj.length > 0)    return false;
    if (obj.length === 0)  return true;
    for (var key in obj) {
      if (hasOwnProperty.call(obj, key)) return false;
    }
    return true;
  },
  
  encodeRfc3986: function(str) {
    return encodeURIComponent(str).replace(/[!'()]/g, function(char) {
      return escape(char);
    }).replace(/\*/g, "%2A");
  },
  
  init: function() {
    this.oauth.parent = this;
    return this;
  }
}.init();

①「Consumer API Key」
②「Consumer API secret Key」
③「プロジェクトキー」
の入力を忘れずに。

このコードについては、正直にいうと僕はよくわかっていません。
が、使えます。なので理解する必要はないみたいです。

このサイトを参考にしました。

下準備が終わったので、次からは自動いいねを実行させる部分を作成していきましょう。


[コード実装]自動いいね

//いいねする
Twitter.favorite = function(id){
  id = String(id);
  var data = {id: id};
  return this.api("favorites/create",date);
};

// ツイート検索
Twitter.search = function(data, count ,result_type) {
  if ("string" === typeof data) {
    data = {q: data, result_type: result_type, count: count};
  }
  
  return this.api("search/tweets", data);
};


//jsonからTweetIdのみを抽出し、いいねをする
function tweet_search_fav(){
  var sheet = ss.getSheetByName("いいね");
  var fav = sheet.getRange(1,2).getValue();
  var count = sheet.getRange(2,2).getValue();
  var result_type = "mixed"; //popular:人気のツイート recent:最新のツイート mixed:popularとrecentを合わせたもの を検索
  var res = Twitter.search(fav, count, result_type);
  var tweet = res.statuses;
  var num = tweet.length;
  for(var i = 0; i < num; i++){
    try{
      Twitter.favorite(tweet[i].id_str);
    }catch(e){
      Browser.msgBox(i + "は失敗");
    }
  }
  var date = new Date();
  var today = Utilities.formatDate(date , "JST", "yyyy/MM/dd HH:mm:ss ");
  sheet.insertRowAfter(6);
  sheet.getRange(7, 1).setValue(today);
  sheet.getRange(7, 2).setValue(fav);
  sheet.getRange(7, 3).setValue(num);
  
}

今までのところは、ググりながらやったので、参考サイトのURLを貼って省略しました。ここ以降は、自分で作成したので理解してることは、解説していこうと思います。

//いいねする
Twitter.favorite = function(id){
  id = String(id);
  var data = {id: id};
  return this.api("favorites/create",date);
};

ここは、いいねを実行するための関数です。

今回の引数
id: ツイートのID

いいねしたいツイートのIDを引数として与えれば、そのツイートをいいねしてくれる関数です。


// ツイート検索
Twitter.search = function(data, count ,result_type) {
  if ("string" === typeof data) {
    data = {q: data, result_type: result_type, count: count};
  }
  
  return this.api("search/tweets", data);
};

ここは検索するための関数です。検索して取得したツイートのIDをjsonで返してくれます。

今回の引数
data: 検索する言葉 (例) data = Python → ツイッターの検索で Python
count: 検索する時に取得するツイート数
result_type: popular:人気のツイート recent:最新のツイート 
                     mixed:popularとrecentを合わせたもの

(例) data = Python, count = 10, result_type = popular
                                             ↓
ツイッターのキーワード検索で 「Python」と検索して、話題のツイートの上から10個のツイートを取得


//jsonからTweetIdのみを抽出し、いいねをする
function tweet_search_fav(){
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName("いいね");
  var fav = sheet.getRange(1,2).getValue();
  var count = sheet.getRange(2,2).getValue();
  var result_type = "mixed"; //popular:人気のツイート recent:最新のツイート mixed:popularとrecentを合わせたもの を検索
  var res = Twitter.search(fav, count, result_type);
  var tweet = res.statuses;
  var num = tweet.length;
  for(var i = 0; i < num; i++){
    Twitter.favorite(tweet[i].id_str);
  }
}

これが、先ほどまでで作った、いいねする関数とと検索する関数を組み合わせて、特定の言葉を検索しいいねするところまでを行う関数です。

今回はスプレッドシートから実行できるようにしました。
スプレッドシートはこんな感じです。

上の空欄に検索したい言葉、下の空欄に個数を入力し、実行をクリックすると、検索→いいね が自動で実行されます。
(個数が1〜100個なのは、一度に検索できる個数が100個だったからです。)

SpreadsheetApp.getActiveSpreadsheet()
これは、GASのコードを書くページを開く際に、スプレッドシート→GAS の順で開いたと思います。そのスプレッドシートを使うよと宣言するためのものです。

getSheetByName("")
これは、シート名からどのシートにするのかを宣言するためのものです。
""の間にシート名を入れると使えます。
ちなみに僕は、シート名を「いいね」にしたのでコードの部分にはいいねと書いてあります。

他のシートの名前を公開するのが恥ずかしかったので消しました笑

getRange(列,行)
これは、どのセルを取得するか決めるためのものです。
(例)getRange(1,2) → 1Aのセル
      getRange(5,6) → 5Fのセル

getValue()
これは、セルの内容を取得するためのものです。


今回の関数の流れ
シートからツイートする単語、個数を取得

検索してツイートのIDを取得

検索したIDごとにいいね

ちなみに、検索結果はjson形式です。
詳しいことは僕自身理解していませんが、
Twitter.search()の中にstatusesという部分があり、その中にid_strというものがあります。これが、今回のツイートIDになります。

idとid_strがあり、どちらもツイートのIDですが、今回のGASではid_strの方しか使えません。


まとめ

自動いいねをGASで作成できれば、参考にしながら自動でRTやフォローもできるようになると思います。つぶやくこともできます。ぜひ、このnoteの内容を糧として、改造してください。

そのときにはTwitterAPIの公式サイトを読みながら進める必要が出てきます。
英語で書かれているので、理解が難しいと思います。
なので、日本語に訳してくれているサイトを紹介します。

このサイトを見れば理解しやすいと思います。
が、最新のものではないことが多いので、公式のサイトと並行して使うといいと思います。
Google翻訳と一緒に戦いましょう。


この記事が気に入ったら、サポートをしてみませんか?気軽にクリエイターを支援できます。

note.user.nickname || note.user.urlname

最後まで読んでいただきありがとうございます。 サポートしていただけると、泣いて喜びます。

スキありがとうございます。よければ、シェアお願いします。
3

いつき

コメントを投稿するには、 ログイン または 会員登録 をする必要があります。