Slackbot Actor

In this section, we will create an actor that sends a message to a Slack Channel using a webhook provided by Slack. A pre-requisite requirement is an active webhook for your Slack workspace.

Writing Customized Actors

Recall that Tapis Actors are essentially bits of code wrapped in lightweight environments called containers. When we deployed the hello-world Actor in the previous section, we used a pre-built Docker container (tacc/hello-world:1.0). However, a more common use case is to write custom code that runs whenever the Actor executes. To do this, we must first build a Docker image using our custom actor.py, push the Docker image to a public image registry (DockerHub), and instruct Tapis to use our custom image when executing the container.

If you are interested in learning more about Docker containers, please attend our deep dive Docker container session tomorrow (Friday Sept. 24th), where we will cover custom image creation, common use cases, and more. The documentation for this session can be found here .

Initialize a New Actor slackbot-actor

$ mkdir slackbot_actor
$ cd slackbot_actor
$ touch Dockerfile actor.py
$ find -L .
.
./Dockerfile
./actor.py

Edit the Actor Source Code in actor.py

An example of a functional actor that says sends a slack message is:

# actor.py
"""Forward message from Actor inbox to Slack"""

from agavepy.actors import get_context
import requests
import os
import simplejson as json


def post_to_slack(message: str):
   """Forward string type `message` to Slack channel"""

   webhook_url = os.environ.get('SLACK_WEBHOOK')
   print("Actor sending message to Slack: {0}".format(message))

   response_from_slack = requests.post(
      webhook_url, data=json.dumps({'text': message}),
      headers={"Content-type": "application/json"})
   print("Response from Slack:")
   print(response_from_slack)


def main():
   """Main entrypoint"""
   context = get_context()
   message = context['raw_message']
   post_to_slack(message)


if __name__ == '__main__':
   main()

Here inject the necessary environment variable SLACK_WEBHOOK set from tapis actors create command. How do we get the webhook into our Actor? We don’t. Instead of embedding it in the underlying container, it is defined as an environment variable in the Actor. We must set SLACK_WEBHOOK while creating the actor. This can be done using Tapis CLI. In the tapis actors create command, we can pass it as an environment variables via the -e flag.

Write the Dockerfile

The first step to building our customized Actor is to build a customized Docker image. To do this, we write a Dockerfile, which is a list of instructions for building our customized environment. The below Dockerfile constructs an image containing a Python3 runtime environment, Python package dependencies installed by pip, and our actor.py script. The pip-installed requirements are agavepy, requests simplejson python libraries, which are available through PyPi.

# pull base image, which provides a Python3 runtime
FROM python:3.6

# install package dependencies using pip
RUN pip3 install agavepy simplejson requests

# add our custom Python script
ADD actor.py /actor.py

# command to run the python script
CMD ["python", "/actor.py"]

Build Docker Container

We can now use our Dockerfile to build a custom Docker image:

Note

In the below command, make sure to replace taccuser with your DockerHub username.

# Build and tag the image
$ docker build -t taccuser/slackbot-actor:1.1 .
Sending build context to Docker daemon  4.096kB
Step 1/5 : FROM python:3.6
...
Successfully built b0a76425e8b3
Successfully tagged taccuser/slackbot-actor:1.1

# Push the tagged image to Docker Hub
$ docker push taccuser/slackbot-actor:1.1
The push refers to repository [docker.io/taccuser/slackbot-actor]
...
1.1: digest: sha256:67cc6f6f00589d9ae83b99d779e4893a25e103d07e4f660c14d9a0ee06a9ddaf size: 1995

Create the Actor

We pass the SLACK_WEBHOOK as an environment variable during the time of actor creation.

$ tapis actors create --repo taccuser/slackbot-actor:1.1 \
                      -n slackbot-actor \
                      -d "Send a message containing text to Slack channel" \
                      -e SLACK_WEBHOOK="https://hooks.slack.com/services/${XXXsecretXtokenXXX}"


+----------------+----------------------------+
| Field          | Value                      |
+----------------+----------------------------+
| id             | ww15Ex5oLxJ6b              |
| name           | slackbot-actor             |
| owner          | taccuser                   |
| image          | taccuser/slackbot-actor:1.1|
| lastUpdateTime | 2021-08-24T14:31:58.248860 |
| status         | SUBMITTED                  |
+----------------+----------------------------+
$ tapis actors show ww15Ex5oLxJ6b
+-----------------+-------------------------------------------------+
| Field           | Value                                           |
+-----------------+-------------------------------------------------+
| id              | ww15Ex5oLxJ6b                                   |
| name            | slackbot-actor                                  |
| description     | Send a message containing text to Slack channel |
| owner           | taccuser                                        |
| image           | taccuser/slackbot-actor:1.1                     |
| createTime      | 2021-09-21T20:27:05.613Z                        |
| lastUpdateTime  | 2021-09-21T20:27:05.613Z                        |
| gid             | 859336                                          |
| link            |                                                 |
| privileged      | False                                           |
| queue           | default                                         |
| stateless       | True                                            |
| status          | READY                                           |
| statusMessage   |                                                 |
| token           | True                                            |
| uid             | 859336                                          |
| useContainerUid | False                                           |
| webhook         |                                                 |
| cronOn          | False                                           |
| cronSchedule    | None                                            |
+-----------------+-------------------------------------------------+

we can see the “status” of the actor is “READY”, meaning it is ready to receive and act on messages.

Finally, you can list all actors visible to you with:

$ tapis actors list

+---------------+---------------+----------+-----------------------------+----------------------------+--------+
| ww15Ex5oLxJ6b | slackbot-actor| taccuser | taccuser/slackbot-actor:1.1 | 2021-08-25T14:04:42.819Z   | READY  |
+---------------+---------------+----------+-----------------------------+----------------------------+--------+

Submit a Message to the Actor

# Submit the message to the actor
$ tapis actors submit -m "Hello, Slack!" ww15Ex5oLxJ6b
+-------------+---------------+
|  Field      | Value         |
+-------------+---------------+
| executionId | EjO6yw03GKRmR |
| msg         | Hello, Slack  |
+-------------+---------------+

Let us grab the executionId from here to track the progress of the actor.

List Executions of Actor

The above execution has already completed. Show detailed information for the execution with:

$ tapis actors execs show ww15Ex5oLxJ6b EjO6yw03GKRmR
+-----------+-----------------------------+
| Field     | Value                       |
+-----------+-----------------------------+
| actorId   | ww15Ex5oLxJ6b               |
| apiServer | https://api.tacc.utexas.edu |
| id        | EjO6yw03GKRmR               |
| status    | COMPLETE                    |
| workerId  | EbQByMAXeMVPa               |
+-----------+-----------------------------+

Check the Logs for an Execution

In our slackbot-actor, we expect the actor to print the message passed to it and notify on the slack channel.

$ tapis actors execs logs ww15Ex5oLxJ6b EjO6yw03GKRmR
Logs for execution EjO6yw03GKRmR
 Actor sending message to Slack: Hello, Slack!

Finally check your Slack channel to find your message!