Deploying Drift Apps on AWS using AWS Lambda and API Gateway

One of the biggest reasons we see third party Drift apps declined during our review is either from app being A) submitted prematurely or by accident, or B) not implemented with OAuth securely. This article may not address A), but for those of you who are looking to take the next step on OAuth to create an app accessible by anyone, this article should help you.

Note that gaining experience with OAuth here may be useful for other future projects as well.

Before reading this article, I recommend going through the first article in this series (Your first drift conversation bot) for additional context. In this example, we will take the Drift app Definely from before and deploy it as an AWS serverless application rather than a server. In addition, we will implement OAuth as the authentication mechanism for publishing our app on the store.

Intro to Serverless

The concept of“serverless” applications are those that only run as they are needed (compared to server-based applications which are always running regardless of use level). Serverless has some nice benefits, particularly around being stateless and offering virtually infinite scalability without requiring a ton of dev ops experience. In the case of serverless, you don’t need to own any backend ends systems — all the host of your application does (AWS, Google Cloud, etc.) is manage behind the scenes resources to serve the new incoming requests.

Lambda is amazon’s version of enabling serverless applications, and API Gateway is how we will expose it. One of the nice things here is that we will get TLS (or SSL) around our app, and have a solution that scales fairly nicely without a lot of additional work.

Three Steps to App

I’m going to break this article into three components— the first is creating a Lambda function (which contains the actual logic of the Drift App), the second is exposing that logic using AWS API gateway, and the last is configuring the table so OAuth tokens from your users can be stored and reused.

You’ll need to create/register an app on the dev.drift panel before starting this process. This is described both in my previous article here and in our dev docs.

Making the Lambda Function

I’ve already created the base code necessary for the AWS lambda function — this is available here. Note that this is pretty similar to our original server-based app, but now exports functions for invocation rather than providing a live server.

To start, log into your AWS account and navigate to AWS Lambda:

Creating a new Lambda function

Create a new lambda function. From here, let’s use the microservice template as the base for this lambda function.

Setting the Lambda function template

Next is the configuration — you can use something similar to the following. I recommend the Simple Microservice Permission policy template and basic-lambda-role for the IAM role in order to get the necessary permissions for Dynamo and http invocation:

Filling in the lambda configuration

Scroll to the Gateway trigger section. One nice thing is that we can wire up a new API Gateway right here, and amazon will add the necessary permissions to connect to the lambda for the new API.

Creating a new Gateway from the Lambda creation wizard.

You may need to define a deployment stage for the API Gateway, I recommend using a name like “prod”, and selecting it for your build. Once this is filled out, add the trigger — you may see a dialog like the one below to confirm the connection permission.

Connecting API Gateway to your Lambda function. Hey that wasn’t too bad.

Go ahead and deploy the lambda function with the default code for now. Afterwards, select your newly-created function, compress the contents of the definely-lambda folder (from the github project if you are following along), and upload the compressed zip file to AWS lambda.

Upload your Lambda function code and any required environment variables.

While here, also confirm that your Lambda function has the appropriate access — particularly for logging and Dynamo db.

Needed permissions for the Lambda function.

Once the save completes, you’re now ready to deploy the API for the lambda function.

Defining the API Routes (API Gateway)

We’re just going to need to handle two actions for this app: one action for managing the initial authentication of new users, and the second for our drift app to listen to drift-posted conversation events.

By default, a new endpoint based on your app name should have been pre-created for us (if not, create a new endpoint resource allowing at least POST and GET requests). Click the “Actions” dropdown followed by stage and select / deploy your prod stage version.

We’ll be using the default /definely endpoint which has Lambda proxy already enabled for routing headers, body, etc. from API Gateway. All we need to do is deploy.

For this example, we’ll be using this one endpoint for both receiving events and the initial OAuth request (you may want to split into two endpoints for your app). Once the API Gateway is deployed on the “prod” stage, you should see a screen showing the live request url:

URL for deployed API

Take note of the base url for this particular deployment, return back to the dev drift panel for the app and insert as the OAuth and event callback urls.

Inserting the gateway url to be used by the messages webhook. You will also need to set the OAuth url.

Paste back the URL and add /definely to the end. This will now be triggered by incoming webhook requests. Make sure the new message event is also enabled under the event subscription section on this page as well.

Handling and Storing OAuth tokens

Lastly, in order to make the app usable by a number of distinct users outside of our personal organization, we’ll need a table to manage the authentication tokens of other users who have signed up or added our app. Once a user authenticates for the first time, we’ll be given an access token as well as a refresh token which will need to be persisted and used for future web requests on that user’s behalf. The refresh token will be used to generate new access tokens for each org when a given access token expires. For this example, we’ll create a table in DynamoDB (other external storage mechanisms would work just as well).

The actual OAuth code should be in the app lambda function. This function will take care of storing and managing tokens in this table. You can test your OAuth flow by adding the app to your own org and disconnecting and reconnecting the app from the Drift store. We have more documentation about this in the Drift dev docs.

Once this is done, the app should be exposed and ready for use in your org. As before, navigate to the Drift Apps page, click connect, and enable it for your org.

If successful, you should see the success.html webpage render from your lambda callback.
If you get a server error here, double check your urls and make sure the routes are correctly set. Once these are confirmed, you can also inspect the logs of your lambda function for exceptions.
Screenshot of my Dynamo table — you should see a new entry in your table after authenticating.

Let’s try it out!

It works!

Photo by rawpixel on Unsplash

Your app should work identically to the one described in the previous article, but now in a state to be usable and shareable on the store for any organization to use.

The Elephant in the Room

At this point your app is completed, but I want to draw attention to this part of the source code which handles the OAuth token storing and callback for your app.

OAuth Callback section for my app

Definely was a special app that did not require any extra permissions or credentials for the end user in order to run, so all I’m doing here is showing a success message after we save thus user’s OAuth credentials. However, in most cases, if you are building a coupled integration between Drift and your product or business, you’re going to want to do a redirect to your login page — where you can have the user register, and connect his/her credential for your app and show the appropriate success message.

This redirect url is configurable here from your app panel. More details for capturing tokens from this link are described in the documentation.

Setting a custom OAuth redirect URL

In my app, I set this url to the base url of the api gateway + /definely, which is configured to accept any http requests in the API Gateway screenshot above.

Using a custom login page for the redirect is a straightforward way for you to tie items like API keys, drift user accounts, and app usage directly to your core product when the user is taking advantage of your app in drift.

For additional security, you should also look the Under App Credentials page, you’ll see a field titled Verification Token. You can use this token to verify that the data being sent to your webhook endpoint is actually from Drift.

Submitting your app to the Drift app store.

You’re not done just yet.

You’ve tested out the app in your own organization’s account, and everything works as expected. Now it’s time to submit it for review to be added to the Drift app store! This is the last step.

Drift App Store

Go back to the dev.drift app panel and navigate to the Submit to Directory panel. Fill out the fields, submit, and the app will be submitted for review. The review process will test to make sure the scopes and descriptions are reasonable, and the auth / core use functions work correctly. Don’t worry you can continue tweaking it once done to meet requirements.

Submitting the App for review

If everything checks out, we’ll approve it, send a notification, and include it in the Drift App Store in the drift settings section for all drift users to see!

Wrapping Up

This was a fairly complex tutorial that covered a lot of ground, as such some things may have not been shown in full detail. Note that the process here was described in the context of AWS services, which have the advantage of not requiring configuration of self-managed databases or server instances. The concepts here, particularly around OAuth, can be generalized to apply to your app even if you don’t use lambda.

Creating drift apps should be a fun and free process — with tons of room for creatively. Explore some of our other API routes in our dev docs and create something custom for your business. Let’s drive customers together.

We hope this gives you a good starting point to making your first public app. We’re excited to see what you build.

Joining our Dev Slack:

https://bit.ly/2lFhqDn

Drift has an active dev community and channel dedicated to helping developers get answers and get apps submitted. Join our group!

Debugging

As much as we want them to, apps may not always work on the first try. If the connection is not working as you expect. Try the following steps.

  1. Verify that your lambda function is being hit. If not, double check your gateway url/configuration and make sure there are no firewalls or permission errors in connecting.
  2. If your lambda function is being hit, check the logs to see if there are any exceptions. Ensure that lambda-proxy is enabled so that request headers are being forwarded. Your API Gateway should look similar to mine.

Lambda can be investigated by looking at your Cloudwatch logs: See here for more information on how to do this.

Revisiting the App Source code

Check out the lambda folder of this project:

https://github.com/Driftt/definely/definely-lambda

OAuth Documentation

https://devdocs.drift.com/docs/publishing-an-app

As always, ping us on slack if you have questions

Drift Slack Dev Channel

— -

Happy Drifting.

Chris

Like what you read? Give Chris Buonocore a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.