Skip to content

Instantly share code, notes, and snippets.

@russellbeattie
Last active January 19, 2016 00:42
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save russellbeattie/dc0587b2b60fc54fcab7 to your computer and use it in GitHub Desktop.
Save russellbeattie/dc0587b2b60fc54fcab7 to your computer and use it in GitHub Desktop.
AWS Lambda Twitter Search Bot... uses S3 for persistence and SNS to send out messages.
var querystring = require('querystring');
var https = require('https');
var aws = require('aws-sdk');
var s3 = new aws.S3();
var sns = new aws.SNS({
region: 'us-east-1'
});
var query = '#SEARCH TERM HERE';
var twitter_consumer_key = 'CONSUMER_KEY_HERE';
var twitter_consumer_secret = 'CONSUMER_SECRET_HERE';
var s3_bucket = 'S3_BUCKET_HERE';
var s3_key = 'FOLDER_NAME/tweet-ids.json';
var ids = [];
var access_token = access_token || '';
exports.handler = function(event, context) {
checkTweets(context);
};
function checkTweets(context) {
console.log('Starting process...');
getIds(function() {
getAuth(function(){
getTweets(function(tweets){
processTweets(tweets, function(){
console.log('Process complete. \n');
context.succeed('Process complete');
});
});
});
});
}
function getIds(fn) {
console.log('Getting Ids');
s3.getObject({
Bucket: s3_bucket,
Key: s3_key
}, function(err, data) {
if (err) {
console.log(err);
} else {
ids = JSON.parse(data.Body.toString());
}
fn();
});
}
function saveIds(fn) {
console.log('Saving Ids');
var body = new Buffer(JSON.stringify(ids));
s3.putObject({
Bucket: s3_bucket,
Key: s3_key,
Body: body
}, function(err, data) {
if (err) {
console.log(err);
} else {
console.log('Saved new data', data);
}
fn();
});
}
function sendMessage(message) {
console.log('Sending message', new Date(), message);
var params = {
Subject: 'New Twitter Message for ' + query,
Message: '\n\n' + message + '\n\n\n\n\n\n\n',
TopicArn: 'arn:aws:sns:us-east-1:123123123123:TwitterSearchBotNotifications'
};
sns.publish(params, function(err, data) {
if (err) {
console.log('sns error', err)
} else {
console.log('Message sent', data)
}
});
}
function getAuth(fn) {
if(access_token){
fn();
return;
}
console.log('Getting auth_token');
var b64Credentials = new Buffer(twitter_consumer_key + ':' + twitter_consumer_secret).toString('base64');
var post_data = 'grant_type=client_credentials';
var options = {
host: 'api.twitter.com',
port: '443',
path: '/oauth2/token',
method: 'POST',
headers: {
'Authorization': 'Basic ' + b64Credentials,
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'Content-Length': Buffer.byteLength(post_data)
},
};
var req = https.request(options, function(res) {
var str = '';
res.on('data', function(body) {
str += body;
});
res.on('end', function() {
var res_data = JSON.parse(str);
access_token = res_data.access_token;
fn();
});
});
req.write(post_data);
req.end();
}
function getTweets(fn) {
console.log('Getting tweets');
var options = {
host: 'api.twitter.com',
port: '443',
path: '/1.1/search/tweets.json?result-type=recent&q=' + encodeURIComponent(query),
method: 'GET',
headers: {
Authorization: 'Bearer ' + access_token
}
};
var req = https.request(options, function(res) {
var str = '';
res.on('data', function(body) {
str += body;
});
res.on('end', function() {
var res_data = JSON.parse(str);
fn(res_data);
});
});
req.end();
}
function processTweets(tweets, fn) {
console.log('Processing tweets');
var save = false;
var items = tweets.statuses;
for (var x = 0; x < items.length; x++) {
var id = items[x].id_str;
if (ids.indexOf(id) == -1 && !items[x].retweeted_status) {
var message = 'https://twitter.com/' + items[x].user.screen_name + '/status/' + id + '\n\n';
message += '@' + items[x].user.screen_name + ' ' + items[x].text;
if(items[x].entities.media){
sendMessage(message);
}
ids.push(id);
save = true;
}
}
if (save) {
saveIds(fn);
} else {
fn();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment