LoginSignup
60
59

More than 5 years have passed since last update.

Google Apps ScriptでTwitter botを作ってみた

Last updated at Posted at 2015-10-03

Google Apps Scriptだけで、Twitterのbotを作れないかなと思案してたら、作れてしまったので、記載

どんなbotか

なんてことはない、好きなサイトの更新してる記事をランダムでつぶやいてくれるbot

こういうbotが欲しいと思った経緯としては、
- feedlyで記事の更新を全て取り込んでも、結局一括で削除しちゃって読まない
- Twitterを見ている時に、ふとつぶやかれている記事なら読んじゃう
- じゃあ、Twitterで適当に記事が目につく状況作れば、読んじゃうじゃないか

実際のスクリプト

今回作ったものは、「RSSをスクレイピングして、スプレッドシートに記事のリンクをExportして、そのリンクを定期的につぶやく」という仕組みです。

この仕組みは3つの役割から構成されています。
1.スプレッドシートのデータを削除する
2.RSSをスクレイピングし、スプレッドシートにExportする
3.スプレッドシートの値をランダムに取得し、それをツイートする

それでは、それぞれについて説明します。

1.スプレッドシートのデータを削除する

こちらは、すでにスプレッドシートに記事のURLがある場合、それを削除するためのスクリプトです。
これを用意する意図としては、過去の記事URLを全て削除することで、スプレッドシートには常に最新記事のURLが存在する状態を作り出すためです。

実際のクエリ

clear.gs
function clear() {
    # シートを扱う準備
    var myActiveSpreadSheet = SpreadsheetApp.getActiveSpreadsheet();
    var myActiveSheet = myActiveSpreadSheet.getSheets()[0];

    # 取得したurlを全てクリアする
    myActiveSheet.clear();
}

2.RSSをスクレイピングし、スプレッドシートにExportする

こちらは、RSSをスクレイピングし、スプレッドシートに取得してきた記事URLをExportするためのスクリプトです。

実際のクエリ

scraping.gs
function scraiping() {
  # シートを扱う準備
  var myActiveSpreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  var myActiveSheet = myActiveSpreadSheet.getSheets()[0];

  # RSSからscraipingでurlを取得。今回は、筆者がヨーロッパのサッカーが好きなので、ゲキサカのRSS( http://web.gekisaka.jp/rsspage )を利用させていただいております。
  var response = UrlFetchApp.fetch("http://web.gekisaka.jp/feed?category=foreign");
  var myRegexp = /<guid isPermaLink=\"true\">([\s\S]*?)<\/guid>/gi;
  var match = response.getContentText().match(myRegexp);

  # 不必要な文字を置換し、ドライブシートに貼り付け
  for(var i in match) {
    var amount = match[i]
    amount = amount.replace("<guid isPermaLink=\"true\">", "");
    amount = amount.replace("<\/guid>", "");
    myActiveSheet.getRange(myActiveSheet.getLastRow()+1, 1).setValue(amount);
  }
}

3.スプレッドシートの値をランダムに取得し、それをツイートする

こちらは、スプレッドシート内の記事URLを取得し、それをランダムに取得し、定期的にツイートするためのスクリプトです。

実際のクエリ

tweet.gs
var CONSUMER_KEY = 'Your_CONSUMER_KEY';                    # 取得したCONSUMER_KEYを入力してください
var CONSUMER_SECRET = 'Your_CONSUMER_SECRET';                 # 取得したCONSUMER_SECRETを入力してください

/**
 * Authorizes and makes a request to the Twitter API.
 */
function run(text) {                         
  var service = getService();
  if (service.hasAccess()) {
    var url = 'https://api.twitter.com/1.1/statuses/update.json';
    var payload = {
      status: text                           
    };
    payload = Object.keys(payload).map(function(key) {
      return encodeRfc3986(key) + '=' + encodeRfc3986(payload[key]);
    }).join('&');
    var response = service.fetch(url, {
      method: 'post',
      payload: payload,
      escaping: false
    });
    var result = JSON.parse(response.getContentText());
    Logger.log(JSON.stringify(result, null, 2));
  } else {
    var authorizationUrl = service.authorize();
    Logger.log('Open the following URL and re-run the script: %s',
        authorizationUrl);
  }
}

/**
 * Encodes a string using the RFC 3986 spec.
 */
function encodeRfc3986(str) {
  return encodeURIComponent(str).replace(/[!'()]/g, function(char) {
    return escape(char);
  }).replace(/\*/g, "%2A");
}

/**
 * Reset the authorization state, so that it can be re-tested.
 */
function reset() {
  var service = getService();
  service.reset();
}

/**
 * Configures the service.
 */
function getService() {
  return OAuth1.createService('Twitter')
      // 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(CONSUMER_KEY)
      .setConsumerSecret(CONSUMER_SECRET)

      // Set the name of the callback function in the script referenced
      // above that should be invoked to complete the OAuth flow.
      .setCallbackFunction('authCallback')

      // Set the property store where authorized tokens should be persisted.
      .setPropertyStore(PropertiesService.getUserProperties());
}

/**
 * Handles the OAuth2 callback.
 */
function authCallback(request) {
  var service = getService();
  var authorized = service.handleCallback(request);
  if (authorized) {
    return HtmlService.createHtmlOutput('Success!');
  } else {
    return HtmlService.createHtmlOutput('Denied');
  }
}

function bot_news_link() {
 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var sheet = ss.getSheets()[0];
 var cell = sheet.getRange("A1");

 all_urls = cell.offset(0, 0, sheet.getLastRow()-1);
 var urls = all_urls.getValues();

 # ランダム関数で取得。コンテンツのあるRowの最後までを範囲に指定
 var rand = Math.ceil(Math.random() * sheet.getLastRow() - 1);

 # ランダムurl
 var url = urls[rand][0];

 run("あなたにオススメの記事は" + url + "なんだな!!");
}

実際の運用

筆者の場合、以下のようなクローンスケジュールで設定している
1.削除は、朝の7 ~ 8時で1回行う
2.記事のURL取得は、朝の8 ~ 9時で1回行う
3.記事のツイートは、2時間おきに1回行う

参考記事

60
59
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
60
59