Slack in Python

Send Slack messages to channels, people and groups from Python services.

Your services send Slack messages to channels, people and groups through self.slack.send.

The connections are send-only - they are for delivering notifications, alerts and updates from your integrations to the people who need them.

Get a bot token from Slack

A connection authenticates with a bot token of a Slack app installed in your workspace:

  1. Go to api.slack.com/apps and click Create New App
  2. Choose From scratch, name the app, e.g. Zato, and pick your workspace
  3. In the left menu, click OAuth and Permissions
  4. Under Scopes > Bot Token Scopes, add chat:write
  5. Add chat:write.public too if the bot should be able to post to public channels without being invited to them first
  6. Click Install to Workspace and approve the app
  7. Copy the Bot User OAuth Token - it starts with xoxb- and it is what the connection needs

To message a private channel or group, invite the bot to it first, e.g. with /invite @Zato.

Create a connection

To create a connection, go to Connections > Chat > Slack in the Dashboard, click Create a new connection and fill in the form:

  1. Name: My Slack
  2. Token: the bot token from the previous step
  3. Click OK

The same connections can also be created with enmasse, using the slack key:

slack:
  - name: My Slack
    token: Zato_Enmasse_Env.SlackToken

Use Ping on the connection's page to confirm that the token works - it invokes Slack's auth.test method.

Send messages

To send a message, call self.slack.send with the connection's name, the target and the text:

from zato.server.service import Service

class NotifyOnboardingComplete(Service):

    def handle(self):
        self.slack.send('My Slack', channel='#onboarding', text='All accounts for Jane Doe are ready')

The target can be:

  • A channel, e.g. #alerts
  • A person, using their member ID, e.g. U0123456789
  • A group conversation, using its ID

Rich text

The text uses Slack's own formatting (mrkdwn), so messages can be formatted inline:

from zato.server.service import Service

class NotifyDeploymentDone(Service):

    def handle(self):
        text = '*Deployment finished* - details are _in the audit log_'
        self.slack.send('My Slack', channel='#deployments', text=text)

For fully structured messages, pass Block Kit blocks too - the text then becomes the fallback shown in notifications:

from zato.server.service import Service

class NotifyInvoiceReceived(Service):

    def handle(self):

        data = self.request.payload

        blocks = [
            {
                'type': 'section',
                'text': {
                    'type': 'mrkdwn',
                    'text': '*New invoice received*'
                }
            },
            {
                'type': 'section',
                'fields': [
                    {'type': 'mrkdwn', 'text': '*Supplier:*\n' + data['supplier']},
                    {'type': 'mrkdwn', 'text': '*Amount:*\n' + data['amount']},
                ]
            }
        ]

        self.slack.send('My Slack', channel='#invoices', text='New invoice received', blocks=blocks)

Call other Slack methods

The client behind each connection can invoke any Slack Web API method directly, when you need more than sending messages:

from zato.server.service import Service

class ListSlackChannels(Service):

    def handle(self):

        # The underlying client, with its token and HTTP session
        client = self.slack['My Slack']

        # Invoke any Slack Web API method by its name
        response = client.invoke('conversations.list')

        for channel in response['channels']:
            self.logger.info('Channel: %s', channel['name'])

See also

FeatureWhat it does
Microsoft TeamsSend messages to Teams channels, people and groups
SchedulerSend notifications on an interval or at a specific time
EnmasseDefine Slack connections in YAML for automated deployments

Learn more