Systems Library / Operations & Admin / How to Automate Internal Announcements Across Channels
Operations & Admin communication

How to Automate Internal Announcements Across Channels

Push announcements to Slack, email, and intranet simultaneously.

Jay Banlasan

Jay Banlasan

The AI Systems Guy

Internal announcements that only go to one channel get missed. I built a system to automate internal announcements across multiple channels simultaneously. Write it once, and it goes to Slack, email, and your intranet at the same time with proper formatting for each platform.

One input. Multiple outputs. Nobody misses the message.

What You Need Before Starting

Step 1: Define the Announcement Structure

from datetime import datetime

class Announcement:
    def __init__(self, title, body, priority="normal", departments=None, author=""):
        self.title = title
        self.body = body
        self.priority = priority
        self.departments = departments or ["all"]
        self.author = author
        self.created_at = datetime.now()
        self.id = f"ann-{self.created_at.strftime('%Y%m%d%H%M%S')}"

Step 2: Format for Each Channel

def format_for_slack(announcement):
    emoji = {"urgent": ":rotating_light:", "normal": ":mega:", "info": ":information_source:"}
    icon = emoji.get(announcement.priority, ":mega:")

    return {
        "blocks": [
            {"type": "header", "text": {"type": "plain_text", "text": f"{icon} {announcement.title}"}},
            {"type": "section", "text": {"type": "mrkdwn", "text": announcement.body}},
            {"type": "context", "elements": [
                {"type": "mrkdwn", "text": f"Posted by {announcement.author} | {announcement.created_at.strftime('%B %d, %Y %I:%M %p')}"}
            ]}
        ]
    }

def format_for_email(announcement):
    subject_prefix = "[URGENT] " if announcement.priority == "urgent" else ""
    return {
        "subject": f"{subject_prefix}{announcement.title}",
        "body": f"{announcement.body}\n\n---\nPosted by {announcement.author} on {announcement.created_at.strftime('%B %d, %Y')}"
    }

def format_for_intranet(announcement):
    return {
        "title": announcement.title,
        "content": announcement.body,
        "author": announcement.author,
        "date": announcement.created_at.isoformat(),
        "priority": announcement.priority,
        "departments": announcement.departments
    }

Step 3: Send to All Channels

import requests
import smtplib
from email.mime.text import MIMEText
import json
from pathlib import Path

def send_to_slack(formatted, channel, slack_token):
    requests.post(
        "https://slack.com/api/chat.postMessage",
        headers={"Authorization": f"Bearer {slack_token}"},
        json={"channel": channel, "blocks": formatted["blocks"]}
    )

def send_to_email(formatted, recipients, smtp_config):
    msg = MIMEText(formatted["body"])
    msg["Subject"] = formatted["subject"]
    msg["To"] = ", ".join(recipients)

    with smtplib.SMTP(smtp_config["host"], smtp_config["port"]) as server:
        server.starttls()
        server.login(smtp_config["user"], smtp_config["password"])
        server.send_message(msg)

def save_to_intranet(formatted, intranet_dir="announcements"):
    Path(intranet_dir).mkdir(exist_ok=True)
    filename = f"{formatted['date'][:10]}-{formatted['title'][:50].replace(' ', '-').lower()}.json"
    Path(intranet_dir, filename).write_text(json.dumps(formatted, indent=2))

Step 4: Route by Department

DEPARTMENT_CHANNELS = {
    "all": {"slack": "#general", "email_list": "[email protected]"},
    "engineering": {"slack": "#engineering", "email_list": "[email protected]"},
    "marketing": {"slack": "#marketing", "email_list": "[email protected]"},
    "sales": {"slack": "#sales", "email_list": "[email protected]"}
}

def distribute_announcement(announcement, slack_token, smtp_config):
    slack_formatted = format_for_slack(announcement)
    email_formatted = format_for_email(announcement)
    intranet_formatted = format_for_intranet(announcement)

    for dept in announcement.departments:
        config = DEPARTMENT_CHANNELS.get(dept, DEPARTMENT_CHANNELS["all"])
        send_to_slack(slack_formatted, config["slack"], slack_token)
        send_to_email(email_formatted, [config["email_list"]], smtp_config)

    save_to_intranet(intranet_formatted)
    print(f"Announcement distributed to {len(announcement.departments)} department(s)")

Step 5: Track Read Receipts

import sqlite3

def init_tracking_db(db_path="announcements.db"):
    conn = sqlite3.connect(db_path)
    conn.execute("""
        CREATE TABLE IF NOT EXISTS announcement_reads (
            announcement_id TEXT,
            reader TEXT,
            channel TEXT,
            read_at TEXT
        )
    """)
    conn.commit()
    return conn

def read_rate(conn, announcement_id):
    reads = conn.execute(
        "SELECT COUNT(DISTINCT reader) FROM announcement_reads WHERE announcement_id=?",
        (announcement_id,)
    ).fetchone()[0]
    return reads

What to Build Next

Add scheduled announcements that queue up and send at a specific time. Monday morning announcements should not land at 2am. Add read receipts tracking to know which announcements actually reach people.

Related Reading

Want this system built for your business?

Get a free assessment. We will map every system your business needs and show you the ROI.

Get Your Free Assessment

Related Systems