GAS(Google Apps Script)で毎日決まった時間(9時)にツイートするコードのサンプルです。
Twitter APIもいつか使えなくなると思うのですが、一応メモということで。
Twitter APIとかの登録関係は別のサイトを見てください。(適当)
シート
シートでは以下のような準備をしました。
- A列:投稿済かどうかをチェックするためのチェックボックス
- B列:ツイートする内容
- C列:長さ(=LEN(B列のセル)で文字数をカウントしてますが、正確ではないので目安です)
コード
CreateTweet.gs
function getTwitterService(serviceName) { return OAuth1.createService(serviceName) .setAccessTokenUrl('https://api.twitter.com/oauth/access_token') .setRequestTokenUrl('https://api.twitter.com/oauth/request_token') .setAuthorizationUrl('https://api.twitter.com/oauth/authorize') .setConsumerKey("自分用に変更") // API Key .setConsumerSecret("自分用に変更") // API Key Secret .setCallbackFunction('authCallback') .setPropertyStore(PropertiesService.getUserProperties()); } function authCallback(request) { let twitterService = getTwitterService(request.parameter.serviceName); let isAuthorized = twitterService.handleCallback(request); if (isAuthorized) { return HtmlService.createHtmlOutput('認証が正常に終了しました。'); } else { return HtmlService.createHtmlOutput('認証がキャンセルされました。'); } } function doGet(e) { let twitterService = getTwitterService(e.parameter.screenName); let template; if (!twitterService.hasAccess()) { let authorizationUrl = twitterService.authorize(); template = HtmlService.createTemplateFromFile("index"); template.authorizationUrl = authorizationUrl; } else { template = HtmlService.createTemplateFromFile("completed"); } return template.evaluate(); } // v1.1のため使用しない // function postTweet() { // let twitterService = getTwitterService("Twitterのユーザー名"); // let options = { // "method": "post", // "payload": { // status: 'This is a tweet from GAS. This tweet is a test tweet by Twitter API.' // } // }; // let response = JSON.parse(twitterService.fetch('https://api.twitter.com/1.1/statuses/update.json', options)); // } function getTweetContent() { const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); const range = sheet.getRange('A:B'); const values = range.getValues(); for (let i = 0; i < values.length; i++) { if (values[i][0] === true) { // console.log('true === ' + i); // console.log(values[i][1]); } else { // console.log('false === ' + i); // console.log(values[i][1]); if (i !== 0 && values[i][1].length !== 0) { sheet.getRange(i + 1, 1).setValue(true); // console.log('message === ' + values[i][1]); return values[i][1]; } } } } function postTweet() { const service = getTwitterService("Twitterのユーザー名"); const tweetContent = getTweetContent(); // undefined(戻り値なし)の場合は、==nullで判定して強制終了させる if (tweetContent == null) { console.log('強制終了'); return false; } const options = { "method": "post", "muteHttpExceptions": true, 'contentType': 'application/json', 'payload': JSON.stringify({ text: tweetContent }) } try { const response = JSON.parse(service.fetch("https://api.twitter.com/2/tweets", options)); // console.log(response); } catch (e) { const address = 'XXX@gmail.com'; const subject = 'Twitter自動投稿アプリでエラーが発生しました。'; const body = e.fileName + ': ' + e.lineNumber + '\n' + e.name + ': ' + e.message + '\n' + e.stack; const mailOptions = { noReply: true, name: 'GASアプリエラー検知システム' }; GmailApp.sendEmail(address, subject, body, mailOptions); //チェックボックスのfalseをこれから実装する(まだしてないw) } finally { // 翌日のトリガーをセット setTrigger(); } } // 次回のトリガーをセット function setTrigger() { const triggers = ScriptApp.getProjectTriggers(); for (const trigger of triggers) { ScriptApp.deleteTrigger(trigger); } let setTime = new Date(); setTime.setDate(setTime.getDate() + 1) setTime.setHours(Number('09')); setTime.setMinutes(Number('00')); ScriptApp.newTrigger('postTweet').timeBased().at(setTime).create(); }
index.html
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <a href="<?= authorizationUrl ?>" target="_blank">Twitterの認証を行う</a> </body> </html>
completed.html
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> Twitterの認証は完了しています。 </body> </html>