In this workshop, we will be making a Twitter bot written in Javascript using Node.js. What are these words I am saying??
A Twitter bot is a typically an application that you write that listens for something to happen on twitter and than does something in response. In our case, we'll be listening for someone to tweet with a certain hashtag and then tweet something when that happens.
Javascript is an awesome programming language. That's not my opinion. That's a fact. Why? Because of "Atwood's Law": any application that can be written in JavaScript, will eventually be written in JavaScript. People are writing complex front-end frameworks like Angular.js and React.js, to complete operating systems in Javascript. Not only is the web powered by Javascript, but it's used to make mobile apps, desktop apps, EVERYTHING. Learn Javascript and you'll go far.
Node.js isn't actually a language. What it is, is a "runtime environment" that allows javascript code to be run on pretty much every platform (Windows, OS X, Linux, etc). This means that now we can use Javascript to write a webserver, native applications, or a Twitter bot ;)
brew install nodejs
. Otherwise, visit https://nodejs.org/en/ and download the v5.5.0 stable version.You will need a registered Twitter account. Although I included it as a requirement at the top of this page, this is the part where you will need it. Before you can continue, make sure you have a Twitter account!
If you have not added your phone number to your Twitter account, add one here before continuing.
After logging into your account on its website, proceed to https://apps.twitter.com. This is where you will register your app, get your API information, and control how your application works.
Click on the “Create New App” button to start the process of creating a new app and registering it with Twitter.
For each required field, “Name”, “Description” and “Website”, make sure you fill out the information. You can fill these out with dummy values now and change them later:
Note, too, that the “Name” will be how this application is known to other services. While you can using something simple like "TwitterbotDemo" for this example, it might be worthwhile to find a name you like and is not already in use for more advanced projects.
Before you can finalize creating a Twitter application, you must agree to the Developer Agreement.
Take the time right now to read through it and become aware of how Twitter expects an application to act and what rights you have as a developer through this agreement. If you want to, of course.
Once done, click on “Create your Twitter application”.
With your application now created, you can change the default permissions from “Read-only” (the application can only read your tweets) to “Read and Write” (the application can read and write tweets).
To do that, click on the “Permissions” tab.
From the choices, select “Read and Write” and then click on the “Update Settings” button.
Now that the permissions have been changed and your application will be allowed write tweets in the future.
Now we need to find the API key information and create an access token. This means that we will be grabbing and creating some unique tokens that will be used to identify our app. Think of this as the "username and passwords of applications". Since they are basically passwords... Don't share them with anyone!
Let's proceed. Click on the “Keys and Access Tokens” tab.
There are 4 tokens we will need:
The first two, Twitter generates for us. However, it doesn't automatically create an Access Token for your application. To do that, scroll down the page to find that section.
To generate an Access Token at your current permission levels (“Read and Write”) for your application, click on the “Create my access token” button.
Once generated, you should now have a Consumer Key, Consumer Secret, Access Token, and Access Token Secret. All four will be needed to use the basic Twitter bot successfully!
TIME TO ACTUALLY CODE SOMETHING!
The javascript hello world is actually only 1 line of code but let's go ahead and get set up.
cd
and then navigate to the directory of your choice. (i.e. cd Desktop
)mkdir twitterbot
cd twitterbot/
NOTE: Don't close the terminal! We'll need it later!
Now it's time to actually make our javascript file and write our Hello World!
app.js
and save it in our twitterbot
folder we made previously.console.log("Hello World!");
. This is similar to System.out.println
in Java and printf
in C. That's all the code we need to write for now!node app.js
in the terminal and hit enter! You should see "Hello World!" printed out after. You just used Node.js!I won't go too deep in to javascript's syntax. But it resembles C in some ways so I'm sure you'll pick it up. If you have any trouble, just ask or Google it!
npm
which stands for "Node Package Manager" is something that is installed by default with Node.js. It allows you to install packages that you can use in your Node.js code so you don't have to reinvent the wheel everytime! It's awesome.
For this workshop, we're going to install the twitter
package which we will use to interact with Twitter's API. Twitter's API allows us to interact with Twitter via code. In our case, we'll use javascript!
In order to install it, type npm install twitter
in the terminal while still in the twitterbot
folder.
Wait a minute and if you look inside the folder, you'll see a folder called node_modules
. This houses all the packages you add to your project.
Now open up the app.js
file again in the text editor.
twitter
packageTo see all the documentation on how to use this package, take a look at: https://www.npmjs.com/package/twitter. DOCUMENTATION IS YOUR FRIEND. I cannot stress that enough.
As we can see, first we need to require
the twitter package we installed moments ago:
var TwitterPackage = require('twitter');```
The `require` function is kind of similar to a C or Java `include` or `import`. What this line does is load the twitter package and allows you to access all the functions and properties from the variable `TwitterPackage`.
Now, remember those 4 tokens we got above? It's time to use those.
```javascript
var secret = {
consumer_key: 'PUT YOURS',
consumer_secret: 'PUT YOURS',
access_token_key: 'PUT YOURS',
access_token_secret: 'PUT YOURS'
}
var Twitter = new TwitterPackage(secret);
What this code is doing, is creating a javascript Object with our tokens in them, and creating a new Twitter Object with those tokens and are storing that new object in the variable Twitter
. This will allows us to tell Twitter that we are who we are and that they should let us access Twitter's API.
NOTE: As mentioned before, those tokens are like passwords. If you plan on putting this code on GitHub or somewhere else, make sure you take out your tokens. If anyone got ahold of them, they could do some serious damage.
Twitter has a REST API that allows us to do different things. One of the things it can do is allow us to "POST" a tweet.
Looking back at that documentation page, we can see how to do that. For us, it looks like this:
Twitter.post('statuses/update', {status: 'I Love Tech Knights!'}, function(error, tweet, response){
if(error){
console.log(error);
}
console.log(tweet); // Tweet body.
console.log(response); // Raw response object.
});
There are several things happening here:
Twitter.post
means that we are calling the post function in the Twitter object. This is similar in Java.{status: 'I Love Tech Knights'}
is a javascript object that we are passing in to this function where we set the status of the tweet being sent out.As mentioned, we're passing in this function. In the Twitter.post
function, you're expected to pass a function in that will be run AFTER twitter tries to post the tweet. This is what we call a "callback function." In that function, you'll notice 3 parameters:
In our code, we'll just post our tweet and then print it out in the console.
Go ahead and comment out the "Hello World" line. We don't need it anymore. In javascript, commenting is just like in C or Java. //
or /**/
.
Now, save that code, open up your terminal again and run:
node app.js
If you go to Twitter, you should see your tweet "I Love Tech Knights!" posted!
Congratulations! You just posted to Twitter via code!
Twitter has a very cool API called the Streaming API which gives us information about Tweets in real-time. In other words, when some one tweets something that we care about, we get all the data about that tweet.
First thing's first, let's go back to that documentation. There, we can see an example of the Streaming API. Modifying it for our use case, it looks something like this:
Twitter.stream('statuses/filter', {track: '#TechKnightsDemo'}, function(stream) {
stream.on('data', function(tweet) {
console.log(tweet.text);
});
stream.on('error', function(error) {
console.log(error);
});
});
Alright, let's break this down.
The Twitter.stream
function takes in 3 parameters:
track
which lets us define a word, hashtag or phrase that we care to listen for. For this, we will be tracking when some one tweets with the hashtag "TechKnightsDemo".stream.on('data', function(tweet) {
console.log(tweet.text);
});
So, using the stream object, it calls the on
function. Now with the on
function, you pass in a string and a function. This says, "when a get data (a tweet), call this function with that data." For now, we just print out tweet.text
which is how you access the actual text of the tweet that was received that used "#TechKnightsDemo".
Let's go ahead and comment the Twitter.post
code so we don't post the same tweet twice. Then, if we save that, and call node app.js
in the terminal, you'll notice that the terminal no longer shows you a prompt. This is because it's running and listening for some sort of data to come in from that stream. If you need to stop it, press CTRL-C a few times to return to the prompt.
Now, to test this, go ahead and go to Twitter and tweet something with "#TechKnightsDemo", then check your running terminal and you should see the text of your tweet, printed out.
Congratulations! You just listened for tweets!
Now you're probably wondering what's next. Well, let's recap so far:
There's only one more step left and that's to bring those ideas together! I've given you all the tools (and code) you need to make a very basic Twitter bot, now it's time for you to put those pieces together.
If you get it working, how about extending it further? There are so many possibilities. Here are some ideas:
I recommend changing the hashtag you're listening to as you might get others using the same hashtag. Try to make it unique.
Math.random()
returns a random double between 0 and 1['AN','ARRAY','OF','STRINGS','LOOKS','LIKE','THIS']
['This', 'is','a','string']
in the following example)var myString = "This is a string";
var stringArray = myString.split(" ");
One of the things you might want to do is reply to the person who tweeted with your hashtag. To do this, you need to "mention" them.
You can access the username of the person who tweeted with your hashtag by doing:
tweet.user.screen_name
In order to mention them, concatenate an "@" symbol at the beginning by doing:
var mentionString = "@" + tweet.user.screen_name;
then just concatenate that to the string you want to tweet out and boom, you're now replying to the person who tweeted at you.
Those are some hints, but like in most programming conundrums: Google it! There are resources online at your disposal that give you the answer you're looking for. StackOverflow is a great website for answers to small questions like "How do I do X in javascript". You can also ask someone walking around.
These are all of the solutions for the example project ideas, along with the basic "reply" example. They are also in the repo.
This code shows you how to reply to someone that used a certain hashtag.
var TwitterPackage = require('twitter');
// importing my secret.json file
var secret = require("./secret");
// my secret.json file looks like this:
// {
// "consumer_key": "...",
// "consumer_secret": "...",
// "access_token_key": "...",
// "access_token_secret": "..."
// }
//make a new Twitter object
var Twitter = new TwitterPackage(secret);
// Call the stream function and pass in 'statuses/filter', our filter object, and our callback
Twitter.stream('statuses/filter', {track: '#TechKnightsDemo'}, function(stream) {
// ... when we get tweet data...
stream.on('data', function(tweet) {
// print out the text of the tweet that came in
console.log(tweet.text);
//build our reply object
var statusObj = {status: "Hi @" + tweet.user.screen_name + ", How are you?"}
//call the post function to tweet something
Twitter.post('statuses/update', statusObj, function(error, tweetReply, response){
//if we get an error print it out
if(error){
console.log(error);
}
//print the text of the tweet we sent out
console.log(tweetReply.text);
});
});
// ... when we get an error...
stream.on('error', function(error) {
//print out the error
console.log(error);
});
});
This solution shows you how to make a tip calculator by tweeting:
<decimal percentage to tip> <check amount> #TechKnightsDemoTip
for example:
.233 100 #TechKnightsDemoTip
would respond with:
Hi @TylerLeonhardt, 23.3% of $100.00 is $23.30. That's a total of: $123.30!
Here's the code:
var TwitterPackage = require('twitter');
// importing my secret.json file
var secret = require("./secret");
// my secret.json file looks like this:
// {
// "consumer_key": "...",
// "consumer_secret": "...",
// "access_token_key": "...",
// "access_token_secret": "..."
// }
//make a new Twitter object
var Twitter = new TwitterPackage(secret);
// Call the stream function and pass in 'statuses/filter', our filter object, and our callback
Twitter.stream('statuses/filter', {track: '#TechKnightsDemoTip'}, function(stream) {
// ... when we get tweet data...
stream.on('data', function(tweet) {
// print out the text of the tweet that came in
console.log(tweet.text);
//split up the tweet's text
var tipArr = tweet.text.split(" ");
// turn those Strings in to a floats
var percent = parseFloat(tipArr[0]);
var amount = parseFloat(tipArr[1]);
// calculate the tip amount
var tipAmount = percent * amount;
//build our reply string
var reply = "Hi @" + tweet.user.screen_name + ", " + (percent*100) + "% of $" + amount.toFixed(2) + " is $" + tipAmount.toFixed(2) + ". That's a total of: $" + (tipAmount+amount).toFixed(2) +"!";
//call the post function to tweet something
Twitter.post('statuses/update', {status: reply}, function(error, tweetReply, response){
//if we get an error print it out
if(error){
console.log(error);
}
//print the text of the tweet we sent out
console.log(tweetReply.text);
});
});
// ... when we get an error...
stream.on('error', function(error) {
//print out the error
console.log(error);
});
});
This solution shows you how to make a random number generator by tweeting:
<lower bound> <upper bound> #TechKnightsDemoRandom
for example:
0 100 #TechKnightsDemoRandom
would respond with:
Hi @TylerLeonhardt, a random number between 0 and 100 is 42!
Here's the code:
var TwitterPackage = require('twitter');
// importing my secret.json file
var secret = require("./secret");
// my secret.json file looks like this:
// {
// "consumer_key": "...",
// "consumer_secret": "...",
// "access_token_key": "...",
// "access_token_secret": "..."
// }
//make a new Twitter object
var Twitter = new TwitterPackage(secret);
// Call the stream function and pass in 'statuses/filter', our filter object, and our callback
Twitter.stream('statuses/filter', {track: '#TechKnightsDemoRandom'}, function(stream) {
// ... when we get tweet data...
stream.on('data', function(tweet) {
// print out the text of the tweet that came in
console.log(tweet.text);
//split up the tweet's text
var tipArr = tweet.text.split(" ");
// turn those Strings in to a floats
var lowerBound = parseInt(tipArr[0]);
var upperBound = parseInt(tipArr[1]);
// calculate the random number (Math.random returns a double between 0 and 1)
var randomNum = Math.random() * (upperBound - lowerBound) + lowerBound;
//build our reply string
var reply = "Hi @" + tweet.user.screen_name + ", a random number between " + tipArr[0] + " and " + tipArr[1] + " is " + Math.round(randomNum) + "!";
//call the post function to tweet something
Twitter.post('statuses/update', {status: reply}, function(error, tweetReply, response){
//if we get an error print it out
if(error){
console.log(error);
}
//print the text of the tweet we sent out
console.log(tweetReply.text);
});
});
// ... when we get an error...
stream.on('error', function(error) {
//print out the error
console.log(error);
});
});
This solution shows you how to make a "magic 8 ball bot" that will tweet with a random response to anything that uses the hashtag "TechKnightsDemoMagic".
Here's the code:
var TwitterPackage = require('twitter');
// importing my secret.json file
var secret = require("./secret");
// my secret.json file looks like this:
// {
// "consumer_key": "...",
// "consumer_secret": "...",
// "access_token_key": "...",
// "access_token_secret": "..."
// }
//make a new Twitter object
var Twitter = new TwitterPackage(secret);
// we will randomly pick one of these items in this array
var arrOfMagicSayings = [
"Signs point to yes.",
"Yes.",
"Reply hazy, try again.",
"Without a doubt.",
"My sources say no.",
"As I see it, yes.",
"You may rely on it.",
"Concentrate and ask again.",
"Outlook not so good.",
"It is decidedly so.",
"Better not tell you now.",
"Very doubtful.",
"Yes - definitely.",
"It is certain.",
"Cannot predict now.",
"Most likely.",
"Ask again later.",
"My reply is no.",
"Outlook good.",
"Don't count on it."
]
// Call the stream function and pass in 'statuses/filter', our filter object, and our callback
Twitter.stream('statuses/filter', {track: '#TechKnightsDemoMagic'}, function(stream) {
// ... when we get tweet data...
stream.on('data', function(tweet) {
// print out the text of the tweet that came in
console.log(tweet.text);
// calculate the random index (Math.random returns a double between 0 and 1)
var randomIndex = Math.round(Math.random() * arrOfMagicSayings.length);
//build our reply string grabbing the string in that randomIndex we've calculated
var reply = "Hi @" + tweet.user.screen_name + ", " + arrOfMagicSayings[randomIndex];
//call the post function to tweet something
Twitter.post('statuses/update', {status: reply}, function(error, tweetReply, response){
//if we get an error print it out
if(error){
console.log(error);
}
//print the text of the tweet we sent out
console.log(tweetReply.text);
});
});
// ... when we get an error...
stream.on('error', function(error) {
//print out the error
console.log(error);
});
});
Enjoy!
Check out more awesome workshops at: http://techknights.org/workshops/