Slack is one of the most widely used messaging platforms in modern workplaces. It’s a great tool for communication, collaboration and teamwork. As with any software, Slack can also have outages and issues that may impact user productivity. Therefore, it’s important to stay informed about Slack’s status to prevent any productivity loss. One way to stay informed is to check Slack’s status page, but this can be a tedious and time-consuming task.

In this blog post, we will explore how to automate the notification process of Slack’s status using Python. We will write Python code to check Slack’s status page and send notifications to specified email addresses if there are any issues.

Requirements

requirements.txt file contains a list of dependencies required by the script. The pip command uses this file to install the required dependencies.

python-dotenv
Jinja2
feedparser

Configuration

config.py file contains configuration variables used by the script. It also loads environment variables using the python-dotenv package.

from dotenv import find_dotenv, load_dotenv
from os import environ as env

# Load environment variables
ENV_FILE = find_dotenv()
if ENV_FILE:
    load_dotenv(ENV_FILE)

# Configuration variables
SLACK_FEED_URL = 'https://status.slack.com/feed/atom'
SMTP_SERVER = 'smtp.gmail.com'
SMTP_PORT = 587
SMTP_USERNAME = env.get('SMTP_USERNAME')
SMTP_PASSWORD = env.get('SMTP_PASSWORD')
EMAIL_FROM = env.get('SMTP_USERNAME')
EMAIL_TO = env.get('SMTP_EMAIL_TO')

Jinja2 Email Template

email_template.j2 template uses Jinja2 syntax to render the email body dynamically based on the latest Slack status update. When an incident or outage occurs, the email will contain the status update details, including the issue status, issue title, issue summary, and a link to more information about the issue. The template also includes a message asking the recipient to check the Slack status page for more information and updates.

email_template.png

Main Script(main.py)

Parsing the Slack Status RSS Feed

The first step in automating Slack’s status notification process is to parse Slack’s RSS feed. Slack provides an Atom feed that contains all the latest updates on the status of their platform. We can use the Feedparser package to parse the Slack RSS feed and extract the latest status update.

import feedparser
import datetime
from config import *

class SlackChecker:
    def __init__(self):
        self.feed = feedparser.parse(SLACK_FEED_URL)
        self.current_date = datetime.date.today()

    def get_current_entries(self):
        entries = []
        for entry in self.feed.entries:
            entry_date = datetime.datetime.strptime(entry.published, '%Y-%m-%dT%H:%M:%S%z').date()
            if entry_date == self.current_date:
                issueStatus = entry.title.split(":")[0].strip()
                issueTitle = entry.title.split(":", 1)[1].strip()
                issueLink = entry.link
                issueSummary = entry.summary
                if any(issueStatus.startswith(s) for s in ["Incident", "Notice", "Outage", "Maintenance"]):
                    entries.append({
                        "issueTitle": issueTitle,
                        "entry_date": entry_date,
                        "issueStatus": issueStatus,
                        "issueSummary": issueSummary,
                        "issueLink": issueLink
                    })
        return entries

This code parses the Slack RSS feed and checks for the latest status update. If there is an issue with the Slack platform, the code return out the entries.

Rendering an Email Template using Jinja2

The next step is to render an email template using Jinja2. We will use a pre-defined email template that contains placeholders for the Slack status update. We can use Jinja2 to render the email template with the latest Slack status update.

import smtplib
from email.mime.text import MIMEText
from config import *

class EmailSender:
    def __init__(self):
        self.smtp_server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
        self.smtp_server.starttls()
        self.smtp_server.login(SMTP_USERNAME, SMTP_PASSWORD)

    def send_email(self, subject, body):
        message = MIMEText(body, 'html')
        message['Subject'] = subject
        message['From'] = EMAIL_FROM
        message['To'] = EMAIL_TO

        self.smtp_server.sendmail(EMAIL_FROM, [EMAIL_TO], message.as_string())
        self.smtp_server.close()

Execution

This is the main script that checks the Slack status feed and sends an email notification if there is an incident.

if __name__ == "__main__":
    slack_checker = SlackChecker()
    email_sender = EmailSender()
    entries = slack_checker.get_current_entries()
    if entries:
        template_loader = jinja2.FileSystemLoader(searchpath="./")
        template_env = jinja2.Environment(loader=template_loader)
        template = template_env.get_template("email_template.j2")
        email_subject = f"Slack: {slack_checker.current_date} - {entries[0]['issueTitle']}"
        email_body = template.render(entries=entries)
        email_sender.send_email(email_subject, email_body)

Jenkinsfile and a Pipeline job

To use a Jenkinsfile and a Pipeline job to schedule the execution of the Python code from a Git repository, you can follow these steps:

  • Create a new Pipeline job in Jenkins by navigating to Jenkins homepage and selecting “New Item” from the left-hand menu. Give the job a name and select “Pipeline” as the job type.
  • In the Pipeline section of the job configuration page, select “Pipeline script from SCM” as the Definition.
  • Choose the Git SCM and provide the URL for the Git repository containing the Python code.
  • Specify the branch name, if different from the default branch.
  • In the Script Path field, enter the path to the Jenkinsfile in the Git repository.
  • In the Jenkinsfile, you can define a pipeline that runs the Python code. Here is an example of what the pipeline might look like:
pipeline {
    agent any
    environment {
        SMTP_EMAIL_TO = credentials('SMTP_EMAIL_TO_ID')
    }
    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }
        stage('Execute') {
            steps {
                withCredentials([[
                    $class: 'UsernamePasswordMultiBinding',
                    credentialsId: 'SMTP_CREDENTIALS_ID',
                    usernameVariable: 'SMTP_USERNAME',
                    passwordVariable: 'SMTP_PASSWORD'
                ]]) {
                    sh '''
                    python3 -m venv .venv
                    bash -c "source .venv/bin/activate && pip3 install -r requirements.txt && python3 main.py"
                '''
                }
            }
        }
    }
}
  • This pipeline checks out the code from the Git repository and executes the Python script. The withCredentials amd credentials are used to securely retrieve the SMTP server credentials and SMTP_EMAIL_TO_ID secure text from a Jenkins global credential.
  • Save the Pipeline job and run it to ensure that it executes as expected.
  • Finally, you can schedule the Pipeline job to run on a regular basis by configuring the trigger in the Pipeline section of the job configuration page. You can modify the schedule to fit your needs.

jenkins_job.png

emailoutput.png

Wrap-Up

In this blog post, we have discussed how to automate the notification process of Slack’s status using Python. We have written Python code to check Slack’s status page and send notifications to specified email addresses if there are any issues. The automation is accomplished using Python packages like feedparser, jinja2, smtplib, and python-dotenv. We have also provided a Jenkinsfile and a Pipeline job that can be used to schedule the execution of the Python code from a Git repository. This automation ensures that teams are promptly notified of any issues with Slack and can take appropriate action to mitigate any productivity loss.