Make a Twitter Auto Reply Bot with Google Scripts
Use this Google Script to setup Out of Office auto-replies in Twitter. The script reads all the Twitter @mentions and sends them a tweet with a custom status message.
/* O U T O F O F F I C E F O R T W I T T E R */
/* - - - - - - - - - - - - - - - - - - - - - */
/* Written by Amit Agarwal http://labnol.org?p=27911 */
/* For help, email amit@labnol.org or tweet @labnol */
function start() {
// Please enter dates in YYYY-MM-DD HH:MM format
var OUTOFOFFICE_START_DATE = "03/11/2013 18:13";
var OUTOFOFFICE_END_DATE = "03/11/2013 19:00";
// This is your Out-Of-Office reply. Keep it less than 120 characters.
var OUTOFOFFICE_TEXT = "I am currently out of the office,
with limited access to Twitter. Thanks!";
// Get your Twitter keys from dev.twitter.com
var CONSUMER_KEY = "AAA";
var CONSUMER_SECRET = "BBB";
// Change this with your Twitter handle
var TWITTER_HANDLE = "labnol";
// DO NOT MODIFY ANYTHING AFTER THIS LINE
storeKeys ( CONSUMER_KEY, CONSUMER_SECRET,
OUTOFOFFICE_TEXT, TWITTER_HANDLE );
initialize ( OUTOFOFFICE_START_DATE, OUTOFOFFICE_END_DATE );
// Make sure that Twitter oAuth is working
doTwitter();
}
// Delete exiting Apps Script triggers, if any
function removeTriggers() {
var triggers = ScriptApp.getScriptTriggers();
for(var i=0; i < triggers.length; i++) {
ScriptApp.deleteTrigger(triggers[i]);
}
clearDatabase();
}
function storeKeys(key, secret, text, handle) {
ScriptProperties.setProperty("TWITTER_CONSUMER_KEY", key);
ScriptProperties.setProperty("TWITTER_CONSUMER_SECRET", secret);
ScriptProperties.setProperty("OUTOFOFFICE_TEXT", text);
ScriptProperties.setProperty("MAX_TWITTER_ID", 0);
ScriptProperties.setProperty("TWITTER_HANDLE", handle);
}
// Clean and Initialize the ScriptDB database
function clearDatabase() {
var db = ScriptDb.getMyDb();
while (true) {
var result = db.query({});
if (result.getSize() == 0) {
break;
}
while (result.hasNext()) {
db.remove(result.next());
}
}
}
// Setup triggers for the START and END dates
function initialize(start, end) {
var startDate = new Date(start);
var endDate = new Date(end);
removeTriggers();
ScriptApp.newTrigger("autoReply")
.timeBased()
.at(startDate)
.create();
ScriptApp.newTrigger("removeTriggers")
.timeBased()
.at(endDate)
.create();
}
function autoReply() {
clearDatabase();
ScriptApp.newTrigger("outOfOffice")
.timeBased()
.everyMinutes(5)
.create();
}
function oAuth() {
var oauthConfig = UrlFetchApp.addOAuthService("twitter");
oauthConfig.setAccessTokenUrl("https://api.twitter.com/oauth/access_token");
oauthConfig.setRequestTokenUrl("https://api.twitter.com/oauth/request_token");
oauthConfig.setAuthorizationUrl("https://api.twitter.com/oauth/authorize");
oauthConfig.setConsumerKey(
ScriptProperties.getProperty("TWITTER_CONSUMER_KEY"));
oauthConfig.setConsumerSecret(
ScriptProperties.getProperty("TWITTER_CONSUMER_SECRET"));
}
// This function will poll twitter every 5 minutes for any @mentions
function outOfOffice() {
oAuth();
var twitter_handle = ScriptProperties.getProperty("TWITTER_HANDLE");
var phrase = "to:" + twitter_handle;
var search = "https://api.twitter.com/1.1/search/tweets.json?count=10"
+ "&include_entities=false&result_type=recent&q="
+ encodeString(phrase) + "&since_id="
+ ScriptProperties.getProperty("MAX_TWITTER_ID");
var options =
{
"method": "get",
"oAuthServiceName":"twitter",
"oAuthUseToken":"always"
};
try {
var result = UrlFetchApp.fetch(search, options);
if (result.getResponseCode() === 200) {
var data = Utilities.jsonParse(result.getContentText());
if (data) {
var tweets = data.statuses;
if (tweets.length) {
var db = ScriptDb.getMyDb();
var reply = ScriptProperties.getProperty("OUTOFOFFICE_TEXT");
for (var i=tweets.length-1; i>=0; i--) {
var sender = tweets[i].user.screen_name;
var found = db.query({user: sender});
if ( ! found.hasNext() ) {
db.save({user:sender});
sendTweet(sender, tweets[i].id_str, reply);
}
}
}
}
}
} catch (e) {
Logger.log(e.toString());
}
}
// If an @mention is found, send an Out of Office tweet to that user.
function sendTweet(user, reply_id, tweet) {
var options =
{
"method": "POST",
"oAuthServiceName":"twitter",
"oAuthUseToken":"always"
};
var text = "@" + user + " " + tweet;
text = encodeString(text.substr(0, 140));
var status = "https://api.twitter.com/1.1/statuses/update.json"
+ "?status=" + text + "&in_reply_to_status_id=" + reply_id;
try {
var result = UrlFetchApp.fetch(status, options);
ScriptProperties.setProperty("MAX_TWITTER_ID", reply_id);
}
catch (e) {
Logger.log(e.toString());
}
}
function doTwitter() {
oAuth();
var req = "https://api.twitter.com/1.1/application/rate_limit_status.json";
var options =
{
"method": "get",
"oAuthServiceName":"twitter",
"oAuthUseToken":"always"
};
try {
var result = UrlFetchApp.fetch(req, options);
} catch (e) {
Logger.log(e.toString());
}
}
function encodeString (q) {
var str = encodeURIComponent(q);
str = str.replace(/!/g,'%21');
str = str.replace(/\*/g,'%2A');
str = str.replace(/\(/g,'%28');
str = str.replace(/\)/g,'%29');
str = str.replace(/\'/g,'%27');
return str;
}
Amit Agarwal
Google Developer Expert, Google Cloud Champion
Amit Agarwal is a Google Developer Expert in Google Workspace and Google Apps Script. He holds an engineering degree in Computer Science (I.I.T.) and is the first professional blogger in India.
Amit has developed several popular Google add-ons including Mail Merge for Gmail and Document Studio. Read more on Lifehacker and YourStory