Using 3rd party APIs
The serverless cloud function fun stuff begins now. You're going to talk to a 3rd party API and send a text message.
You can use the same approach to work with any 3rd party API.
This sort of glue code is the bread and butter of cloud functions. An event happens in your system, a 3rd party calls your function, a user clicks something, and your function talks to another API to do work.
Call an API
Twilio lets you send and receive SMS messages and calls. They have a great node.js library that does the hard work for you.
Most serious API providers have a library you can use. For others I like to install isomorphic-fetch
and use the fetch
method.
Exercise
Move into exercise-3
from the serverless-workshop-exercises GitHub repository.
Export a handler
function from src/send-sms.ts
and send a text to your phone number. Try getting the text from the body payload and the to:
phone number from query params.
Use a POST request.
Here's how you send text with Twilio:
const client = twilio(accountSid, accountToken)const msg = await client.messages.create({body: "hello from lambda",to: "<phone number>",from: "+13162519852", // a valid twilio phone number})
You can use my accountSid AC1c1db52be590e54e507969ae5c0b800a
. I'll give you the secret token on chat.
Try your function
Leave payload empty for GET requests, valid JSON for POST.
Solution
Use .env vars
Hardcoding secret keys in your code is insecure. A step up in security is using a .env
file.
Exercise
Install the serverless-dotenv-plugin
and enable it in serverless.yml.
# serverless.ymlplugins:- serverless-dotenv-plugin
Create a .env
file with secret variables. I recommend prefixing with the service name. Learned that lesson the hard way 😇
// .envTWILIO_ACCOUNT_SID=AC1c1db52be590e54e507969ae5c0b800aTWILIO_ACCOUNT_TOKEN=...
Access them in your code with process.env.X
Try your function
Leave payload empty for GET requests, valid JSON for POST.
Solution
Use AWS secrets manager
This is the most secure. It encrypts values at rest and ensures engineers don't keep secrets on their machines. Makes it easy to rotate as well.
Due to the secure nature of secrets, you have to configure this manually.
Exercise
Go to the AWS Secrets Manager console. Create a new secret.
Choose other type of secrets
and add values from your .env
file. I recommend keeping the same name.
Install the aws-sdk
and @types/aws-sdk
, then access your secrets with code like this:
import { SecretsManager } from "aws-sdk"const ssm = new SecretsManager({region: "us-east-1", // make sure this matches your region})const secret = await ssm.getSecretValue({ SecretId: "<your secret name>" }).promise()const { TWILIO_ACCOUNT_SID, ... } = JSON.parse(secret?.SecretString)
I recommend creating a function.
Add IAM permissions to secrets manager for your project
provider:# ...iamRoleStatements:- Effect: "Allow"Action:- "secretsmanager:GetSecretValue"Resource: "arn:aws:secretsmanager:${self:provider.region}:*"
The serverless-iam-roles-per-function
lets you add permissions to specific Lambda functions.
Try your function
Leave payload empty for GET requests, valid JSON for POST.