Google Apps Scriptだけで、Twitterのbotを作れないかなと思案してたら、作れてしまったので、記載
どんなbotか
なんてことはない、好きなサイトの更新してる記事をランダムでつぶやいてくれるbot
こういうbotが欲しいと思った経緯としては、
- feedlyで記事の更新を全て取り込んでも、結局一括で削除しちゃって読まない
- Twitterを見ている時に、ふとつぶやかれている記事なら読んじゃう
- じゃあ、Twitterで適当に記事が目につく状況作れば、読んじゃうじゃないか
実際のスクリプト
今回作ったものは、「RSSをスクレイピングして、スプレッドシートに記事のリンクをExportして、そのリンクを定期的につぶやく」という仕組みです。
この仕組みは3つの役割から構成されています。
1.スプレッドシートのデータを削除する
2.RSSをスクレイピングし、スプレッドシートにExportする
3.スプレッドシートの値をランダムに取得し、それをツイートする
それでは、それぞれについて説明します。
1.スプレッドシートのデータを削除する
こちらは、すでにスプレッドシートに記事のURLがある場合、それを削除するためのスクリプトです。
これを用意する意図としては、過去の記事URLを全て削除することで、スプレッドシートには常に最新記事のURLが存在する状態を作り出すためです。
実際のクエリ
function clear() {
# シートを扱う準備
var myActiveSpreadSheet = SpreadsheetApp.getActiveSpreadsheet();
var myActiveSheet = myActiveSpreadSheet.getSheets()[0];
# 取得したurlを全てクリアする
myActiveSheet.clear();
}
2.RSSをスクレイピングし、スプレッドシートにExportする
こちらは、RSSをスクレイピングし、スプレッドシートに取得してきた記事URLをExportするためのスクリプトです。
実際のクエリ
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を取得し、それをランダムに取得し、定期的にツイートするためのスクリプトです。
実際のクエリ
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回行う