Mail from Slack by OpenFaaS

Amir Movahedi
Red Gold
Published in
7 min readAug 31, 2019

In this tutorial I want to show you how I built a function to send emails from a Slack command which running on OpenFaaS.

OpenFaaS

OpenFaaS (Function as a service) is a framework for creating serverless functions on Kubernetes or Docker. It made serverless functions simple. You can run OpenFaaS anywhere on your laptop, your own premise hardware or create a cluster in the cloud. OpenFaaS supporting any language such as GO, Java, Python, C#, Ruby , ASP.NET Core or anything else.

If you are new with OpenFaaS workshop is a great place to start.To learn more about OpenFaaS please checkout the project documentation.

Pre-requisites

Scenario

  1. Using Slash Command in Slack to send message to an API.
  2. Use OpenFaaS function as API to receive message from Slack.
  3. Verifying Slack message HMAC.
  4. Extract the message.
  5. Convert message body from Markdown to HTML.
  6. Send email using nodemailer.
  7. Send back appropriate message to Slack.

Get Started

Source Code

You can find project source code here.

Create Slash Command

  1. Go to Slack api page.
  2. Click on Create New App Button.
  3. Write you app name (in my case openfaas).
  4. Choose your development workspace ( You can create your own workspace to test your app).

5. It should be like picture above then click on Create App button.

6. After creating new app, it will navigate you to your page app settings.

7. From left side menu click on Slash Command. In Slash Command page click on Create New Command button.

8. Write command name in Command field (in my case is mail).

9. For Request URL field you should set as

https://[your-domain]/function/[function-name]

10. You can write a short description about your app in Short Description field.

11. Now click on Save button to create the Command.

12. Next click on Install App from menu left side, then click on Install App Workspace button. Click on Allow button to all your app using the work space.

To find out more about slash command please check Slack Documentation.

Create OpenFaaS Function

With OpenFaaS you can implement your function in any programming language. OpenFaaS also provided templates which makes our life much easier.

To test our Slack App I will use nodejs to build a function receiving message from Slack and send data back to Slack.

  1. Follow commands below to create your function.

In result in your root directory you should have directory name slack-mail which contains your app files and handler.js file. The stack.yml file which keep all configuration for your function.

2. Slash Command documentation mentioned that timeout for API call is maximum 3 seconds, meaning if your API do not response to Slack API call within 3 seconds you will see timeout error on your slack.

By default OpenFaaS function scale from zero meaning your function will have cold start the receive a request. However you can disable this feature and make a warm start for your function. With warm start your function will start in milliseconds!!!

To do that we need to add com.openfaas.scale.zero: false label in stack.yml file.

3. Then add bellow code in handler.js file from slack-mail directory. Here we just send a Json data in the format slack receive to show the message.

It is time to run our function 😍.

To do that run commands below.

$ git init
$ git add .
$ git commit -sm 'Init'
# Build/push/deploy
$ faas up --tag=sha

After less than one minute your OpenFaaS API is ready.

Let’s test OpenFaaS API

To do that run command bellow.

Before running the command replace red-gold username with you community cluster username.

# Call OpenFaaS API$ curl https://my-domain.example.com/function/slack-mail

After that you should see this result :

{“text”:”This is a test!”,”attachments”:[{“text”:”Hello Slack from OpenFaaS!”}]}

Let’s try on our Slack APP

Go back to Slack and open the work space you have you app installed on.

Then type /mail you should see something like bellow image. Then Enter to send the command.

After that you will receive below message.

Yes!!! Everything work well between Slack and OpenFaaS.

But why we receive the everything in Json string instead of appropriate displaying message. It is because Slack can process our response if the content-type in header is application/json by that we need to set content type header response for our function. You can do it easily by adding environment variable content_type: “application/json” in slack.yml file.

Commit your code and push.

git add . && git commit -sm “add env content-type” && git push

When the function is ready, try /mail command in Slack again.

Now everything looks good. Next step implement our scenario.

First we need to install some node module packages:

  • markdown-it to be able using markdown pattern in our message and change the body of our mail to html.
  • markdown-it-emoji use emoji in email.
  • nodemailer is a module for Node.js to send email.
  • qs parse query string from slack.

Follow commands blow to install all packages.

Create a file name util.js in $HOME/mail-of-slack/slack-mail directory and add blow code.

Add following code in your handler.js file.

Let’s together check the changes in handler.js file.

First line in handler function we use qs module to parse the income data from Slack which includes:

commandThe command that was typed in to trigger this request. This value can be useful if you want to use a single Request URL to service multiple Slash Commands, as it lets you tell them apart.

textThis is the part of the Slash Command after the command itself, and it can contain absolutely anything that the user might decide to type. It is common to use this text parameter to provide extra context for the command.

user_nameThe plain text name of the user who triggered the command.

And other fields. For more please check Slash Command Document

In our case we only work with text.

Next syntax is signVerification(data) which verify if the message coming from the right source (our Slack App). To do that should use signed secrets functionality of Slack. Later we need to add Slack Signing Secret to our function secrets.

As you know the text field from slack request containes anything we write front of our command like :

/mail **anything front of our command**

So the text field here will be **anything front of our command**.

I use {emails} | {email subject} | {email body} pattern to differentiate each part of the email we need. Then I will extract this text using uprocessCommandText(data.text) to the fields emails, subject, body as an object. As a result the command in Slack will be something like this:

/mail example1@email.com,example2@email.com |subject | Hello dear

After extracting email body we use markdownToHtml(emailInfo.body) to convert email body from markdown to html.

Next we write email callback to handle send email response and send back an appropriate message to Slack.

The send email function using nodemailer module to send email and the call emailCallback() function to handle the result.

For last step we need to set some secrets for our function which I used in utils.js file.

From Slack admin panel choose your app and find the field Signing Secret.

Image from Slack document.

Click on show button and copy the Signing Secret.

Following blow code replace password , email, and signing secret with yours then execute command.

In the case using Gmail follow nodemailer instruction enabling access to email from your your function.

$ faas-cli secret create secrets \ 
--literal gmail-pass="{your_gmail_password}" --literal gmail="{your_gmail}" --literal sign-secret="{your_sign-secretl}"

Now we need to add the secret in our function. To do that go to your stack.yml file and add the secret name following bellow file.

Commit your code and push.

$ git add .
$ git commit -sm 'add secrets'
$ faas up --tag=sha

Come back to slack and try below command in your Slack workspace. Change amir.gholzam@live.com to another email which you want to send email to.

/mail amir.gholzam@live.com | Send email from Slack using OpenFaaS | 
### Hello :wave:

![OpenFaaS Logo](https://blog.alexellis.io/content/images/2017/08/faas_side.png)

This is working
Yeahhhh :+1:

You should see below message in slack.

Now you check the email inbox you send email to.

Here it is. We are done.

Sure you have many ideas you can implement easily by OpenFaaS. So start from now and it is OpenFaaS community would be a great place to share and get support.

References

--

--

Amir Movahedi
Red Gold

Full-Stack, Cloud, Kubernetes, IoT lover, distributed system and clean architecture. (every click is valuable!) https://amir.telar.dev