Consuming SQS Messages with Lambda(TypeScript)
Tags: aws, typescript, lambda, sqs
Published: 2022-04-04 07:41:46

Amazon SQS(Simple Queue Service) is a fully managed message queuing service by AWS that enables you to lower the degree of coupling between services(ex. mircoservices), distributed systems, and serverless applications. 

There are a lot of ways to produce message to SQS, but in this post we will focus on consuming(receiving) these messages with a lambda function which is written in TypeScript.

Let's assume we already have our SQS ready, and we only need to write the lambda code to consume the messages in this queue.

Below are the technical stacks we will use.
* [Serverless](https://www.serverless.com/framework/docs/providers/aws/guide/intro)
* TypeScript
* [AWS Lambda](https://aws.amazon.com/lambda/)

We will go through this implementation in three sections,
* Creating IAM User for managing Lambda.
* Writing some codes.
* Deploying, and connecting with SQS!

## Creating IAM User for managing Lambda.

    We can easily deploy Lambda functions using Serverless framework. We'll see the deployment script later, but let's focus on the IAM user who will manage the Lambda function we make here.

Serverless deploys our Lambda function, which is zipped and stored to S3, and all of the logs created by the Lambda function will remain in CloudWatch.

So we need permissions for below AWS Services.
* Lambda
* S3
* CloudWatch

But since this Lambda function will receive and consume messages from SQS, this IAM user also needs a permission to receive message from SQS, which is `sqs:ReceiveMessage`.

## Writing some codes!

Let's start coding the Lambda function. 
Here, we want our Lambda function to receive message from SQS, and send that message to a specific channel in our Slack workspace.

> In case you don't know how to make slack apps, you can create a Slack App and get `OAuth Token` and `clientSecret` by following this great article [here](https://slack.com/help/articles/115005265703-Create-a-bot-for-your-workspace).

Now that you have your `OAuth Token` and `clientSecret`, let's start coding!

First we have to add dependencies below to our fresh new project.

```json
"dependencies": {
    "@slack/bolt": "^3.11.0",
    "aws-lambda": "^1.0.7",
    //...
}
``` 

Now we have to write a handler function, which will handle the event(receiving message).

```ts
const OAUTH_TOKEN = "slack app oauth token";
const SIGNING_SECRET = "slack app signing secret";
const CHANNEL = "slack channel name including #"

const consumeSqsMessage: Handler = async (event: SQSEvent) => {
  const app = new App({
    token: OAUTH_TOKEN,
    signingSecret: SIGNING_SECRET,
  });
  const message = event.Records[0]?.body;
  await sendMessageToSlack(app, message);
};

const sendMessageToSlack = async (app: App, message: string) => {
  try {
    await app.client.chat.postMessage({
      token: OAUTH_TOKEN,
      channel: CHANNEL,
      text: message,
    });
    console.log("Sent!");
  } catch (error) {
    console.log("Failed to send message. error: ", { error });
  }
};

export { consumeSqsMessage };
```

## Deploying, and connecting with SQS!

Now that we have our Lambda function ready, lets' take a look at the serverless deployment script.

```yml
service: <ServiceName>
plugins:
  - serverless-plugin-typescript

provider:
  name: aws
  runtime: nodejs14.x
  state: active
  region: <aws region>

functions:
  notifySQSMessageToSlack:
    handler: src/functions.consumeSqsMessage
    timeout: 30
```

> Note that the timeout value of Lambda functions should be lower than or equal to the visibility timeout of SQS.

Now that we have our Serverless Deployment script ready, we can deploy this to AWS Lambda using [this script] (https://github.com/serverless/github-action) with Github Actions.

Finally, all we have to do is configure SQS to handle this Lambda function whenever a new message comes in.
We can do this very easily, just go to SQS Console and find `Lambda triggers` tab below! Click `Configure Lambda function trigger`, and we'll see the Lambda function we just deployed.

That's it! We just made a lambda function which consumes messages from SQS, and sends it to a Slack channel.

Thank you for viewing this article. If you have any questions or feedbacks, please leave a comment or contact me!