Serverless Backends With AWS Cloud: Twitter Sessions
Tags: apigateway, s3, lambda, dynamodb
Published: 2017-04-24 19:06:44

---
title: "Serverless Backends With AWS Cloud: Twitter Sessions"
published: true
description: We'll use DynamoDB, Lambda, and the API Gateway to create sessions to store our twitter info!
cover_image: 
tags: API Gateway, S3, Lambda, DynamoDB
---

_This is a part in a series on AWS serverless architecture. The original blog post series can be found both here and on my blog [J-bytes](http://robsherling.com/jbytes/index.php/2017/01/08/serverless-backends-with-aws-cloud-intro/)._

# How to make a session in DynamoDB

In this section, we're just going to save some browsing information in a session (held in DynamoDB) and redirect the user to Twitter. Once we have a callback in place, we'll use that session data to have our user follow us. We can also use that data to message that user later (we actually have the user DM themselves, explained in the next section) with some promotional news.

More specifically, we're going to save their request token in a table in DynamoDB along with some other stuff, then when they confirm our app, use their oAuth token to go get the data attached to the request token and complete the chain.

This is fairly straightforward so let's just jump right into it.

## Step 0: Make a Twitter App 

[Setup your Twitter app here](https://apps.twitter.com/). It's fast, free, and easy. You will need this to do anything cool like message users and create friendships (on Twitter, this technology is not guaranteed to create friendships in any other way), so making it now makes sense. When you set this app up, it is __super hyper critical imperative__ that you go to the permissions tab and select read, write, and access direct messages. You do this because we need to have them DM themselves later on.

## Step 1: DynamoDB Tables

You should know the drill from the last time we touched tables, so let's just rig up the rest of our tables right now. We're going to need an additional 4 tables total. We'll need staging and production tables for the session we'll create to hold our user's data while they log in to their Twitter accounts to (hopefully) authorize us, and we'll need staging and production tables to hold their data once they come back from that authorization and hit our callback.

Open the DynamoDB table and make the following tables:
```
name: staging_session -> primary key: request_token (string)
name: production_session -> primary key: request_token (string)

name: staging_twitter -> primary key: uid(Number)
name: production_twitter -> primary key: uid(Number)
```
Quick note on the uid in the Twitter tables: The uid actually will be treated as a string in our lambdas and automatically converted on storage. This is because Javascript sometimes has a problem with numbers and uids[(source)](https://dev.twitter.com/overview/api/twitter-ids-json-and-snowflake), but DynamoDB does not care at all.

## Step 2: env-config.json

Open up - or download from your S3 - your env-config.json file (you should have two, one for each environment we are creating). We'll be filling in the rest of the values, leaving only the twitter_api_callback blank for now (we'll do that in the next section). You can get your consumer_key and consumer_secret values from your Twitter app that you set up in step zero. You can find it in Keys and Access Tokens tab on your app settings.

The twitter_table_name should be `<stage>_twitter`, and the twitter_session_table_name is `<stage>_session`.

For the follow uid, you can get it from the same Keys and Access Tokens tab labelled as Owner Id. If it is _not_ your own account use [this link](https://tweeterid.com/) and put in the account that you want to follow.

Save your JSON, and re-upload to the appropriate S3 buckets.

## Step 3: Constructing the Twitter Lambda

Make a session_lambda folder on your local disk, and cd into it.

We're going to download libraries like we did before. This time, we'll need the node-twitter-api library. Observe the spacing on this command, it's a little tricky (careful when you copy):

`npm install –prefix=./ node-twitter-api`

Add the loader.js that we made before using either a hard system link or copying it into the folder, depending on your expertise. If you're copying the loader.js from the github repo for the project, remember to change the S3 bucket on line 61 to our actual bucket.

Add the [index.js](https://github.com/Rob117/serverless-twitter-email/blob/master/session_lambda/index.js) file.
Change the line on line 6 to your appropriate db region.

Read the index file for the notes, but it should be fairly straightforward. We're just going to take a POST request that will tell us if the user chose to follow us or not, hit the Twitter API to get some request tokens, save that data all together, and then redirect to the Twitter site so they can complete the authorization. If you don't need users to follow an account or track any other data in the session, feel free to make it a get request later on.

Zip the folder like we did when we made the email lambda (zip the contents of the folder, not the folder itself) and head on over to the lambda console.

Create a lambda function. Select __Blank Function__ for the blueprint.
Click Next on the Configure Triggers section that pops up to move to the next screen.
For the name of the function, use __generate_twitter_session__.
Change the Code entry type drop-down box to "upload a zip file."
Upload the zip we just made.
Under Lambda function handler and role, use __master_lambda__ in the Existing role dropdown box.
Set the Timeout to 15s
Click Next, then Create Function.
From the Actions drop-down, configure the test event.
```
{
 "body-json": "follow=true"
}
```
Click Save.
Click Actions and create two aliases. One 'staging', the other 'production'. Both should point to Version: $LATEST (you can make a version 1 if you'd like).
Click the button to the left of test (could start with either Alias or say Qualifiers) and click staging under the aliases drop-down tabs. Then click test.
If you get an error message in your logs on a line with JSON.parse that says __SyntaxError: Unexpected token u__ or something similar, check your test event again.

You should get an error message that says:
```
  "errorMessage": "Twitter.MovedPermanently : Redirecting.",
  "errorType": "https://twitter.com/oauth/authenticate?oauth_token=<SOME TOKEN STUFF HERE>"
If you do, you are in good shape and ready to move on to hooking up our API endpoint.
```
## Step 4: Making our Gateway

We're just going to hook up an API endpoint to our Twitter. This is basically a carbon-copy of the email API we made, so if you need a refresher please go read that again now.

Open the API Gateway console and click on our services-api that we made. Click on /api, and then click the Actions drop-down and select __Create Resource__. Name that resource twitter-session, and click Create Resource.

This resource is going to mimic our email resource nearly identically. Remember to have your AWS CLI ready to approve our stage variable controlled lambdas.

Click on the twitter-session resource, and click __create method__.  Change that method to post, and click the check mark.

Change the lambda region to your region, then type `generate_twitter_session:${stageVariables.alias}`. Save, and when you see that giant wall of text, put it into the AWS CLI and replace `${stageVariables.alias} `with staging. Enter, then replace it again with production. Enter again. Confirm non-error text.

Back in your lambda console, click okay. Then click on Method Response. Delete the 200, add a 301, and then edit it to include the 'location' header.

Go to the integration response. Delete the default response with a status of 200. Click __add integration response__, change the status to 301, and make the error regex, `^Twitter.MovedPermanently.*`

Edit our newly created integration response and set the value of the location header mapping to __integration.response.body.errorType__. Click the checkmark.

Lastly, go back to our Integration Request from the twitter-session post option, and add a body mapping template.  The type is __application/x-www-form-urlencoded__. Set the general template to Method Request passthrough, and the Request body passthrough to When there are no templates defined. Save it all.

Deploy to staging and production. Export. Save.

## Step 5: Postman

Click on staging under stages, then click on __/api/twitter-session__. Copy the invoke URL and paste it into Postman. Set the header to `Content-Type: application/x-www-form-urlencoded`. Set the body to `x-www-form-urlencoded`, and the data key-value to `follow : true`. Ensure that the method type is POST, and hit send. Postman should say loading for a short bit (if, for example, you are doing this from near Tokyo when your server is in California, it may be a long bit), and then come at you with something like this (you will have to click "pretty" to make it pretty):

![Postman Screenshot](http://robsherling.com/jbytes/wp-content/uploads/2017/01/api-session.png)

It works!

There is no need to go any farther than this for now. If you check your staging_session database table, you should have some data in it. That marks the completion of this section.

In the next section, we'll send confirmation tweets, actually follow an account, etc.