GAS(Google Apps Script)でTwitterへの定期自動投稿
WEBサービスを運用していく上で、重要になってくるのが集客です。いろいろな手段があると思いますが、無料でできる集客としてはTwitterへの投稿があります。
今回は、Twitterへの自動投稿をGAS(Google Apps Script)を使って行う方法を、実際に運用で使っているソースをもとに説明したいと思います。
はじめに
前提条件としては、ご自身のGoogleアカウントをもっており、以下の図に示すようにGoogle Apps Scriptを立ち上げられることです。(中身は、記事の中で作成していきます。)

全体像
まずは全体の構成について記載します。大きくは3ステップです。
- トリガー設定(下記図の①~③)
- 記事の作成(下記図の④、⑤)
- 記事の投稿(下記図の⑥、⑥’)
それぞれ、①~⑥について簡単に概要を記載します。

- ① 毎日、決まった時間に実行するトリガーです。これはGoogle Apps Scriptの機能として提供されています。ただし、 毎日8時のような指定をした場合、実行は時間ぴったりではなく8時から9時の間というアバウトな 実行になります。
- ② アバウトな実行では困るため、正確(8:00に実行)させるために、スクリプト内でトリガーを設定します。①のトリガーは、大体6~7時に実行されます。そこで②を呼び出して、8:00ぴったりに実行するトリガーを設定します。
- ③ 8:00ぴったりに実行されるトリガーです。このトリガーで実行される関数(myFunction)を設定しています。
- ④ 8:00に呼び出される関数(myFunction)です。記事作成と記事投稿を行います。
- ⑤ 記事作成の関数です。140文字を超えないようにするなど、Twitterに合わせた記事を作成します。
- ⑥ 記事投稿の関数です。内部では「 TwitterWebService 」(後述)を使っています。
- ⑥’ Twitterへの認証を関数にして、⑥で実行しています。
①~⑥をソースをもとに具体的に解説
①毎日実行されるトリガー(1時間の誤差あり)
トリガーはGoogle Apps Script(GAS)の標準機能として提供されているため、簡単に設定可能です。
プロジェクトの「編集」をクリックすると「現在のプロジェクトのトリガー」と表示されます。それをクリックするとトリガーを設定するプロジェクト画面に移動します。

このトリガー画面の右下にある「トリガーを追加」ボタンをおすと、トリガーを追加できます。

ただし、 毎日8時のような指定をした場合、実行は時間ぴったりではなく8時から9時の間というアバウトな 実行になります。
それでは困るため、一工夫します。
このトリガーは6時~7時に実行するようにします。そして、正確な実行時間のトリガーを登録する関数(以下②の「setTrigger」)を呼び出すトリガーとします。
②正確なトリガーを登録するための関数
①で呼び出される「setTrigger」関数の定義です。 この関数では、8:00に「myFunction」関数を実行するトリガーを登録しています。 またトリガーは登録したままですと増えるばかりで、トリガー画面が見づらくなるため「delTrigger」で不要な過去分のトリガーを削除しています。
//--------------------------
//TWITTER用トリガー設定
//毎日、定時実行するトリガーを作成する
//--------------------------
function setTrigger(){
//過去分を削除
delTrigger();
//当日分を作成
var setTime = new Date();
setTime.setHours(08);
setTime.setMinutes(00);
ScriptApp.newTrigger('myFunction').timeBased().at(setTime).create();
}
//--------------------------
//TWITTER用トリガー削除
//毎日、定時実行するトリガーを削除する
//--------------------------
function delTrigger() {
var triggers = ScriptApp.getProjectTriggers();
for(var i=0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() == "myFunction") {
//ScriptApp.deleteTrigger(triggers[i]);
Logger.log(triggers[i]);
}
}
}
③正確なトリガー(分単位の精度あり)
②が6時~7時に呼び出されると、以下の③が8:00ぴったりに実行される関数として登録されます。実行時には「myFunction」が呼び出され実行されます。

④トリガーで呼び出すメイン関数
8:00に実行されるメイン関数(myFunction)です。なかでは⑤「記事作成」の関数、⑥「記事投稿」の関数が呼ばれています。
//--------------------------
//トリガー実行されるメイン処理
//--------------------------
function myFunction() {
//今日のお得
var today_maitoku_message = today_maitoku(today,entries,app_url);//⑤
weet(today_maitoku_message);//⑥
}
⑤記事作成の関数
ここは、投稿する内容によって、独自に作成する個所になります。そのため、以下はあくまでも例として載せておきます。
1点、注意事項として、同じ内容を連続して投稿するとTwitterからエラーが返されてしまいます。おそらくボット的な使い方をするユーザが増えたことによる措置だと思います。
関数について、簡単に説明します。以下の関数は、3つの引数をもとに、1つの投稿記事を作成しています。
引数は
- (1) today:MM/DD の日付
- (2) お得な店舗のリスト
- (3) Twitterユーザに来てほしいサービスのURL
となっています。
また、Twitterは1つの投稿で140文字の制限があるため、店舗リストをどこまで載せれるかを「店舗情報組み立て」の中で判定しています。出来るだけ情報は載せたいので、140文字ギリギリのところまで攻めたら、記事をかえします。
//今日のお得情報
function today_maitoku(today,entries,url){
//件数
var count = entries.length;
//投稿用メッセージ
var part1 = "\本日" + today + "のお得なお店/\r\n\r\n";
var part2 = "";
var part2_tmp = "";
var part3 = "など\r\n\r\n▽ほかのお得な日もチェック" + url;
var message = "";
//文字数チェック用
var max_length = 140 - part1.length - part3.length
//投稿メッセージ 店舗情報組み立て
for(var i=0; i<count; i++){
//店舗情報のリスト
part2_tmp = part2 + "・ #" + entries[i].store_name + " は" + entries[i].merit + "\r\n";
//メッセージの長さ140文字以下かチェック
if(part2_tmp.length <= max_length){
part2=part2_tmp;
}
}
//投稿メッセージを返す
return part1 + part2 + part3;
}
⑥Twitterへの記事投稿の関数
次に記事投稿の関数です。ここでは⑤で作成した投稿記事(msg)を引数にしています。ポイントは、関数の1行目で作成されるtwetterインスタンス「TwitterWebService」です。
//--------------------------
//TWITTERへの投稿関数
//--------------------------
function tweet(msg){
var service = twitter.getService(); //TwitterWebServiceのインスタンス
var message = msg;
var response = service.fetch("https://api.twitter.com/1.1/statuses/update.json", {
method: "post",
payload: { status: message }
});
}
⑥’外部ライブラリ「TwitterWebService」で時短
1からTwitter投稿用の関数を自作してもよいのですが、すでに先人が開いた道が用意されているので、ここはありがたく利用させていただきました。
Google Apps Script(GAS)でライブラリを登録するのはとても簡単です。まず「リソース」をクリックして「ライブラリ」をクリックします。

すると、以下のように登録画面が表示されるので、
プロジェクトキー: 1rgo8rXsxi1DxI_5Xgo_t3irTw1Y5cxl2mGSkbozKsSXf2E_KBBPC3xTF
を入力して、「追加」を押すとライブラリを追加できます。

TwitterWebServiceの利用設定
TwitterWebServiceを利用するための設定です。「認証用のインスタンス」に記載の「***************」の個所には、ご自身のTwitterの ‘Consumer Key (API Key)’, ‘Consumer Secret (API Secret)’ になります。
//--------------------------
//TWITTER認証用(変更不可)
//--------------------------
// 認証用のインスタンス
var twitter = TwitterWebService.getInstance(
"*************Consumer Key", //変更が必要です!!
"*************Consumer Secret " //変更が必要です!!
);
// 認証
function authorize(){
twitter.authorize();
}
// 認証解除
function reset(){
twitter.reset();
}
// 認証後のコールバック
function authCallback(request){
return twitter.authCallback(request);
}
最後に全スクリプトを載せておきます。
//--------------------------
//TWITTER認証用(変更不可)
//--------------------------
// 認証用のインスタンス
var twitter = TwitterWebService.getInstance(
"*************Consumer Key", //変更が必要です!!
"*************Consumer Secret " //変更が必要です!!
);
// 認証
function authorize(){
twitter.authorize();
}
// 認証解除
function reset(){
twitter.reset();
}
// 認証後のコールバック
function authCallback(request){
return twitter.authCallback(request);
}
//--------------------------
//TWITTER用トリガー設定
//毎日、定時実行するトリガーを作成する
//--------------------------
function setTrigger(){
//過去分を削除
delTrigger();
//当日分を作成
var setTime = new Date();
setTime.setHours(08);
setTime.setMinutes(00);
ScriptApp.newTrigger('myFunction').timeBased().at(setTime).create();
}
//--------------------------
//TWITTER用トリガー削除
//毎日、定時実行するトリガーを削除する
//--------------------------
function delTrigger() {
var triggers = ScriptApp.getProjectTriggers();
for(var i=0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() == "myFunction") {
//ScriptApp.deleteTrigger(triggers[i]);
Logger.log(triggers[i]);
}
}
}
//--------------------------
//トリガー実行されるメイン処理
//--------------------------
function myFunction() {
var app_url="https://******.info/app";
var day = new Date();
var y = day.getFullYear();
var m = day.getMonth() + 1;
var d = day.getDate();
var api_call_day = y + "-" + m + "-" + d
var today = m + "月" + d +"日"
//maitoku info
var entries = gatMaitokuEntry(api_call_day); //ここはご自身の記事にあわせて変更
//今日のお得
var today_maitoku_message = today_maitoku(today,entries,app_url);//⑤
weet(today_maitoku_message);//⑥
}
//今日のお得情報
function today_maitoku(today,entries,url){
//件数
var count = entries.length;
//投稿用メッセージ
var part1 = "\本日" + today + "のお得なお店/\r\n\r\n";
var part2 = "";
var part2_tmp = "";
var part3 = "など\r\n\r\n▽ほかのお得な日もチェック" + url;
var message = "";
//文字数チェック用
var max_length = 140 - part1.length - part3.length
//投稿メッセージ 店舗情報組み立て
for(var i=0; i<count; i++){
//店舗情報のリスト
part2_tmp = part2 + "・ #" + entries[i].store_name + " は" + entries[i].merit + "\r\n";
//メッセージの長さ140文字以下かチェック
if(part2_tmp.length <= max_length){
part2=part2_tmp;
}
}
//投稿メッセージを返す
return part1 + part2 + part3;
}
//--------------------------
//TWITTERへの投稿関数
//--------------------------
function tweet(msg){
var service = twitter.getService(); //TwitterWebServiceのインスタンス
var message = msg;
var response = service.fetch("https://api.twitter.com/1.1/statuses/update.json", {
method: "post",
payload: { status: message }
});
}
まとめ
サービスの運用は大切ですが、できるだけ自動化を行い、機能やコンテンツの拡充にあてるリソースを確保することが、利用してい頂くユーザにとってもプラスであると考えています。
詳解! GoogleAppsScript完全入門 ~GoogleApps & G Suiteの最新プログラミングガイド~