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;
}