Learn to Code via Tutorials on Repl.it

← Back to all posts
1
Python 3 Slack-Email Bot
DuncanSykes (3)

How to send emails from Slack by using Python 3

Okay okay, you're probably wondering how on earth did I get this idea? Well like some things in life, the answer is just one word...

Coffee..

That's right, I wrote this "bridge" between Slack and any standard SMTP server for the purpose of ordering coffee from a local coffee shop.

The tutorial?

Oh yeah, sorry. Here's how you can do this too.

PART ONE (SLACK SETUP)

First you'll need to configure your Slack server to work with the code.
First head to the slack API page and click Start Building.
A popup will appear asking you to enter some details.

Once the dashboard opens, navigate to the Bot Users tab and create a new bot user.

Go back to the basic information tab, and select Install App to Your Workspace

One the app has been authorised for your slack workspace, scroll down to the App Credentials menu. Copy down this information. You'll need it later.

PART 2 (THE SOFTWARE)

Now for the fun part....

First we need to install the required packages, in this case, all we need to install is the SlackClient library.

pip install slack-client

After the installation has finished, open a new project in your IDE (integrated development environment) of choice.

Step One:

Import the required libraries.

import re
import smtplib
import time
from slackclient import SlackClient

Step Two:

Define variables. Here we also define the verification token we saved earlier.
We also enter our usename and password for the email server.

uname = '[email protected]'
pword = '12345678Password'
count = 0

token = 'your token here'
slack_client = SlackClient(token)
starterbot_id = None

RTM_READ_DELAY = 0.5
EXAMPLE_COMMAND = ""
MENTION_REGEX = "^<@(|[WU].+?)>(.*)"

Step Three:

Now we set up the definitions that parse both the bot commands and direct mentions from slack.

def parse_bot_commands(slack_events):
    for event in slack_events:
        if event["type"] == "message" and not "subtype" in event:
            user_id, message = parse_direct_mention(event["text"])
            if user_id == starterbot_id:
                return message, event["channel"]
    return None, None

  
def parse_direct_mention(message_text):
    matches = re.search(MENTION_REGEX, message_text)
    return (matches.group(1), matches.group(2).strip()) if matches else (None, None)

Step Four:

This here is the part where the bot handles the incoming command from slack. This is also where you can add custom commands etc.

def handle_command(command, channel, uname, count, pword):
    server = smtplib.SMTP('smtp.gmail.com', 587) 
    # Standard SMTP address for Gmail
    server.starttls() 
    server.login(uname, pword) # Login to email server
    print('Login successful :)')
    
    default_response = 'Invaild Input' 
    response = None
    if command.startswith(EXAMPLE_COMMAND):    
        response = "Email Context: *{}*.".format(command)
        print('Incoming command:', response,'|',command)
        
    if command.startswith('help'):
        response ='ADD TEXT FOR HELP COMMAND HERE' 
        # Set up help command, you can also copy this if statement
        # to make more custom commands
    
    slack_client.api_call(
        "chat.postMessage",
        channel=channel,
        text=response or default_response
    ) # posts response in Slack chat
    
    text = 'Order received {}'.format(command)
    
    server.sendmail(uname, "[email protected]", text)
    # Change [email protected] to the email address you wish to send to
    print("Email sent")
    server.quit() # Close connection to email server

Step Five:

Now we write the mainloop for the bot. This is where the bot listens for an input from Slack. If something comes through, the code calls for the handle command definition.

if __name__ == "__main__":
    if slack_client.rtm_connect(with_team_state=False):
        print("SlackMail Bot online and running...")    
        starterbot_id = slack_client.api_call("auth.test")["user_id"]
        while True:
            command, channel = parse_bot_commands(slack_client.rtm_read())
            if command:
                handle_command(command, channel, uname, count, pword)
                count = count + 1
                print(count)
            time.sleep(RTM_READ_DELAY)
    else:
        print("Connection failed. Exception traceback printed above.")

Conclusion:

If you followed the tutorial correctly, and run the code. The bot should appear online on your slack server.
When you send the bot a message (@mention it), it should return a response. Check the destination email, and if everything was done correctly, you should get an email with the context of the message you sent to the bot.

Now go forth and use this knowledge for your needs (good, evil, whatever). You can now send emails from a slack chat.

One more thing:

If you want to run this bot constantly with little to no downtime, setup a VM on google cloud and something similar and install the bot you wrote, you'll need to edit the VM to execute this script on startup.

Thank you for reading. I hope this bot works the way you want it to.