Attendance Bot
Using EC2, S3, Cloud9, Route53, Lambda,DynamoDB and API Gateway
Hannah Chung
Lena Kwan
Prerequisites 2
Steps 3
Create a Discord Server 3
Implement Discord Bot (Discord end) 4
Create a Discord Bot 6
Creating a Server Instance 9
Create DB (DynamoDB) 13
Create Lambda Function POST 14
Create Lambda Function GET from DDB 17
Create API Gateway 19
Store Attendance 23
Get Attendance -Lambda Function 25
Connect Bot to DynamoDB Using Lambda 28
Create FrontEnd (S3) 31
Route to a domain (Route53) 33
References 37
1
Prerequisites
● Node JS installed (v8.0.0 and up).
● code editor installed
● Discord account and desktop client (obviously…)
2
Steps
1. Create a Discord Server
1) Go to Discord(https://discord.com/) and create your own account. Then
download the Discord app for your PC.
2) After downloading it, install the app and log in using the account you created
above.
3) Click this button on the left side to create a server.
4) Click Create My Own and create your own with a name you want and a
photo you want. (We use ‘discord bot playground’)
5) Once you are done, you’ll be able to see the following screen
3
2. Implement Discord Bot (Discord end)
1) Go back to your Discord desktop app. Click New Application and enter the
name of your application
2) Enter the general information about your discord bot. This is where you can
set an image for the application and copy the client ID and secrets
3) Add the bot to your server. To do this you will need to click on OAuth2, click
the checkbox for bot. This generates a URL
4
4) Paste the URL into a browser and select the server that you would like to add
the bot into.
5) The bot has now been added to your server.
6) In the bot detail, you can get the following information.
5
7) Grab the client secret token from here! We will need it at the end of Part 3!
3. Create a Discord Bot
1) Let’s create a Discord Bot using AWS Cloud9. Go to AWS Cloud9 and create
your own environment using the default settings.
2) Once this is launched, open the IDE. From the AWS Cloud9 menu, select
Preferences. Select AWS Settings and disable “AWS managed temporary
credentials”
6
3) Open the bash shell, run “aws configure” and enter your credentials.
4) First, check the node version in your Cloud9. It should be v10.23.0. If it does
not have node installed or has a lower version of node, you have to install it or
update it. The version should be v8.0.0 or more.
5) To create a project folder, open up the terminal and type in
mkdir discord-greeter-bot
6) Then go into the folder by typing in cd discord-greeter-bot and type in
npm init -y
7
Then you’ll see a package.json file that is just created. This is a manifest file,
for Node based projects where you can state dependencies to install.
7) Because we are making a Discord bot, we need to install discord.js to interact
with Discord API using the following command.
npm install --save discord.js dotenv
8) Now create a file called .env by typing in touch .env and put the following
line in the file by typing in vi .env. Do you remember that I said we need a
bot token later in this part? This is where it is! We’ll put the bot token here.
Replace ‘YOUR-BOT-TOKEN’ to the bot token you got.
DISCORD_TOKEN=YOUR-BOT-TOKEN
8
8) Let’s create our bot script now. Go back to the project folder and create a file
named bot.js and put the following code in it.
// This runs dotenv
require('dotenv').config();
const Discord = require('discord.js');
const Client = new Discord.Client();
Client.on('ready', () => {
console.log(`Now you logged in as
${Client.user.tag}`);
});
Client.on('message', msg => {
if (msg.content === 'hi') {
msg.reply('hello');
}
});
//This will retrieve the Discord token.
Client.login(process.env.DISCORD_TOKEN);
9) After saving it, run the script to see if it works well!
4. Creating a Server Instance
1) In this part, we will host the Discord bot on EC2 instance. Go to EC2 instance service
in AWS. Click ‘Launch Instance.’
9
2) Select ‘Ubuntu Server 18.04 LTS (HVM), SSD Volume Type -
ami-07ebfd5b3428b6f4d’ AMI.
3) Select t2.micro and ‘Review and Launch’.
4) Click ‘Launch’ at the next page and wait for it to be launched. This may take a few
minutes or more.
5) Let’s name this instance DiscordBot! Check the checkbox of DiscordBot and click
‘Connect’ to ssh into the instance using Cloud9.
6) Go to Cloud9, open the bash shell and ssh into ec2 using the commands from above.
7) Once you are connected to the ec2 instance, use the following commands
sudo apt-get update
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
sudo apt-get install -y nodejs
10
sudo apt-get install npm
8) Now exit out of the ec2 instance and try the following commands to zip the project
folder and transfer.
zip -r mine.zip discord-greeter-bot
scp -i yourPem.pem mine.zip ubuntu@yourPublicDns:~/
9) Ssh back into your ec2 instance and check if it’s transferred well.
10) Unzip the file and Install the npm packages.
unzip mine.zip
cd discord-greeter-bot
npm install
11) Run your bot and test it!
12) Change your bot.js to the following codes. You have to replace you_bot_id to your
bot’s id.
// Run dotenv
require('dotenv').config();
const Discord = require('discord.js');
const Client = new Discord.Client();
const lambda = new AWS.Lambda();
Client.on('ready', () => {
console.log(`Now you logged in as ${Client.user.tag}`);
});
11
Client.on('message', async msg => {
let bot_called = '';
if (msg.content.startsWith('<@&you_bot_id>')){
';
bot_called = '<@&you_bot_id>
} else if (msg.content.startsWith('<@!you_bot_id>')){
bot_called = '<@!you_bot_id> ';
} else {
return;
}
let command = msg.content.split(bot_called)[1];
if (command == 'hi') {
return msg.reply('hello');
}
else if (command.startsWith('link me to ')) {
return msg.reply('Your photo is now linked to ' +
command.split('link me to ')[1]);
}
else if (command == 'attendance'){
if (msg.member.voice.channel) {
let idList =
Array.from(msg.member.voice.channel.guild.voiceStates.cache
.keys());
let attendance = [];
for (let i = 0; i < idList.length; i++){
attendance.push(Client.users.cache.get(idList[i]).username
+ '#' + Client.users.cache.get(idList[i]).discriminator);
}
return msg.channel.send('Attendance: ' + attendance);
} else {
return msg.reply('Please stay in the channel where
you want to take attendances.');
}
}
});
//This will retrieve the Discord token.
Client.login(process.env.DISCORD_TOKEN);
13) Upload the updated discord-greeter-bot project to your ec2 following how we did
above. Don’t forget to run node bot.js
14) Play around your bot and find what the bot can do! The hint is in the new codes.
12
5. Create DB (DynamoDB)
1) Navigate to DynamoDB
2) Click Create Table
3) Name the table and add userID as the primary key. We will be using the
discord IDs of users to identify them as they are unique. Click Create.
4) Create an item with a test user and a test link. I used my own discord ID for
the purpose of this lab. For the test link I picked a random image url off of
google. Click Save.
13
6. Create Lambda Function POST
1) Create Lambda Function without a template, accept defaults and make sure
to label that the function is for posting to DDB
2) Create the Role with default execution role. Click Create Function
3) Click Permissions and click on the Role that was created
14
4) Click Attach Policies, add DynamoDBFullAccess
5) Go back to configuration.
6) Attach the following code to the function code, if you want to, you can also
save the tableName as an environment variable.
15
7) Configure the Test Event and click Test.
16
9) Refresh and check your dynamoDB, the test event should be there.
7. Create Lambda Function GET from DDB
1) Create Lambda Function without a template, accept defaults and make sure
to label that the function is for retrieving from DDB
2) You can use the same role as the previous Lambda function. Click Create
Function.
17
4) Enter the following code into index.js
5) Configure the Test Event with the same ID that you used for the previous
lambda function. Click Create.
6) Click Test, if successful you will see the url in the CloudWatch Logs.
18
8. Create API Gateway
1) Go to aws API Gateway, scroll down to REST API and click Build
2) Select NewAPI and fill in the API name and Description. Click Create API
3) Create a Resource and label it userdetails
4) Create a new lambda function to retrieve all the information from the
database.
19
5) Make sure to use the same role as the previous lambda functions so that it
will be able to read/write from DynamoDB.
6) The code is as following:
7) Configure a test event for the lambda function.
8) Test the lambda function. It should return an Item from the DynamoDB table
created earlier.
9) Create a get method using the lambda function that we created earlier above.
20
10) Configure the integration request. Under Mapping Template add
Content-Type “application/json”. In Generate Template, select Method
Request Passthrough.
21
11) Click on Method Request. From here you want to add a URL Query String
Parameter. Add userID.
12) Click the Test button with the lightning bolt. Under Query Strings, input
userID=”DiscordUser#Number” that is within the DynamoDB table. Click Test.
It will return a response body with the contents of the Item from DynamoDB.
13) Deploy the API, give it a name and a description.
14) Enable CORS
22
15) Generate the SDK from the testing stage.
16) Open up apigClient.js to copy the line that lets you retrieve information from
the API.
9. Store Attendance
1) Create a New Function
23
2) The new function will need to have the same permission role as the previous lambda
functions. Fill in the information like the following and click Create Function
3) Configure the test case. It should take an array of users.
4) Paste the code for the lambda function into the handler function. We are parsing the
date time so that it will show the date as “Day of Week - Month - Day - Year - Time”
on the lambda side. When the bot checks attendance it will save the date and time as
the key.
24
5) Click Deploy and then click Test. The lambda function should display “Success” in
the Cloud watch Logs.
6) Check the DynamoDB, the users and timestamps should now be saved.
10. Get Attendance -Lambda Function
1) Navigate to AWS Lambda, click Create Function
2) Create the Function with an existing permission role. This permission role
should be the same one as the previous functions. (Full Access to DDB)
25
3) Click Create Function
4) Configure a test event, the values can be the default, name it test.
5) Enter the code into index.js handler.
6) Click Test
7) The results show display objects within the DDB
8) Navigate back to the API Gateway
9) Click Create Resource. Name it attendance.
10) Create a GET Method.
26
11) Click Integration Request. Click mapping templates. Add application/json to
the mapping templates. Choose from the templates, Method Request
Passthrough. Click Save.
12) Click Test with the Lightning bolt. It should show all the attendances done.
27
13) Redeploy the API
14) Generate the SDK again
11. Connect Bot to DynamoDB Using Lambda
1) Go to your Cloud9 and open the bash shell.
2) Type npm install aws-sdk to install aws-sdk to run the code
28
3) Update your bot.js like below. Bolded lines are newly added here. Don’t forget
to change your_bot_id!
// Run dotenv
require('dotenv').config();
var AWS = require('aws-sdk');
AWS.config.apiVersions = {lambda: '2015-03-31'};
const Discord = require('discord.js');
const Client = new Discord.Client();
const lambda = new AWS.Lambda({apiVersion: '2015-03-31',
region: 'us-west-2'});
Client.on('ready', () => {
console.log(`Now you logged in as ${Client.user.tag}`);
});
Client.on('message',msg => {
let bot_called = '';
if (msg.content.startsWith('<@&you_bot_id>')){
bot_called = '<@&you_bot_id> ';
')){
} else if (msg.content.startsWith('<@!you_bot_id>
bot_called = '<@!you_bot_id6> ';
} else {
return;
}
let command = msg.content.split(bot_called)[1];
if (command == 'hi') {
return msg.reply('hello');
}
else if (command.startsWith('link me to ')) {
lambda.invoke({
FunctionName: 'storeUrl',
Payload: '{"Id": "' + msg.author.username + '#' +
msg.author.discriminator +'","Url":"' + command.split('link
me to ')[1] + '"}'
}, function(err, data) {
if (err) {
console.log(err, err.stack);
} else {
console.log(JSON.parse(data.Payload));
}
});
return msg.reply('Your photo is now linked to ' +
command.split('link me to ')[1]);
}
else if (command == 'attendance'){
if (msg.member.voice.channel) {
let idList =
Array.from(msg.member.voice.channel.guild.voiceStates.cache
29
.keys());
let attendance = [];
for (let i = 0; i < idList.length; i++){
attendance.push(Client.users.cache.get(idList[i]).username
+ '#' + Client.users.cache.get(idList[i]).discriminator);
}
lambda.invoke({
FunctionName: 'storeAttendance',
Payload: '{"users": ' + JSON.stringify(attendance) +
'}'
}, function(err, data) {
if (err) {
console.log(err, err.stack);
} else {
console.log(JSON.parse(data.Payload));
}
});
return msg.channel.send('Attendance: ' + attendance);
} else {
return msg.reply('Please stay in the channel where
you want to take attendances.');
}
}
});
//This will retrieve the Discord token.
Client.login(process.env.DISCORD_TOKEN);
4) Update your bot.js in the ec2 as well!
5) Ssh into your ec2 and run the following command.
sudo apt install awscli
6) Configure your AWS credentials here too.
7) Let’s run it now!
8) Check out what your bot can do!
30
12. Create FrontEnd (S3)
1) Create an S3 bucket and name it discord users, we will be using this to host
our front end
2) Make a front end page (HTML file) and use the apiGatewayClient call from
above to retrieve data from the api that we created above.
3) Upload the HTML file into the S3 Bucket
4) Navigate to Properties, from here click on Edit static website hosting
31
5) Enable Static website hosting.
6) Make the html file public
7) Check out your website now!
32
13. Route to a domain (Route53)
1) First, you have to have your own domain.
2) Go to Route 53 in AWS and click on Hosted Zones.
3) Click on Create hosted zone
4) Put your domain in the Domain name, leave other default settings and click Create.
33
5) Then the zone is created and you would see the following screen.
6) Change the NS and SOA setting as your domain admin indicates.
7) Click on Create Record, leave the Routing Policy as Simple Routing and click on
Next
34
8) Click on Define simple record
35
9) You can leave the Record name empty or put discord as I did. For Value/Route traffic
to, choose Alias to S3 website endpoint. Choose the region where you made the S3
bucket and choose the bucket. Then, click on Define simple record.
10) If you see yours on the list, it’s all done!
11) Check out your website now
36
References
https://medium.com/davao-js/2019-tutorial-creating-your-first-simple-discord-bot-47fc836a17
0b
https://discordjs.guide/
37