Omniscope Custom Blocks › Outputs/Slack-Bot

Slack Bot

Posts one message to a Slack channel for each input record, as your Slack app's bot, optionally with a file attached.

Outputs › Slack Python

Open the demo in Omniscope Download demo.ioz Sample data: placeholder.csv Sample data: stock-alerts.csv Source on GitHub

Omniscope custom block · Outputs

Alerts computed in the workflow, posted to the team's Slack channel as they happen: one message per record, with links that work.

Python · requests, pandas · requests installed on first run if missing

The problem it solves

The workflow already knows which warehouses are below their reorder level each morning; the warehouse leads find out when someone reads the Report. A message in their Slack channel, one per warehouse with a link to the details, reaches them first.

This block posts each record's message to a channel as your Slack app's bot, turning the addresses in it into links.

How it works

What goes in

Stock alerts

Warehouse Lines below reorder level Message
Leeds 12 Leeds: 12 lines below reorder level. Details: http://127.0.0.1:24679/Operations/Stock.iox/r/Report/#Leeds
Bristol 3 Bristol: 3 lines below reorder level. Details: .../#Bristol
Glasgow 0
Norwich 7 Norwich: 7 lines below reorder level (garden & outdoor < 5 days' cover). Details: .../#Norwich

6 rows in the sample file.

The options

Option Demo setting What it does
Bot User OAuth token (an example token) The app's bot token, xoxb-....
Channel ID C0123ABCD (an example) The channel to post to.
Message field Message Each record's message.
File to attach (empty) Optional: a file attached to every message.
Attachment title My Report The title shown for the file.

What comes out

Sent

Row Action Channel Timestamp File ID
0 postMessage C0123ABCD 1741331101.004519
1 postMessage C0123ABCD 1741331101.825639
2 skip
3 postMessage C0123ABCD 1741331102.613209
4 postMessage C0123ABCD 1741331103.402871
5 postMessage C0123ABCD 1741331104.190455

The Messages output holds each message as sent: Norwich's reads (garden &amp; outdoor &lt; 5 days' cover) in Slack's format, and shows in Slack as typed. (Timestamps are invented: they come from Slack.)

Where it pays off

Operations: Exception alerts

A message per warehouse, machine or route that crossed a threshold in the latest data, with a link to the detail.

Sales: Daily numbers

Yesterday's orders and revenue per region, posted to the sales channel before the stand-up.

Data teams: Run reports

A note when a scheduled workflow has finished, with record counts and anything that failed validation.

Customer service: Queue warnings

A message when a queue's waiting time or backlog goes over its target.

Use cases describe typical scenarios and are illustrative; the sample data is invented.

Why do this in Omniscope

How it fits into an Omniscope workflow

Database (stock) → Aggregate (per warehouse) → Field Organiser (formula field: the message) → Slack Bot

Try it

  1. Open the demo project (demo.iox on the demo server, or import demo.ioz from this folder). It holds the sample alerts, the block with example settings (it needs your own Slack app to post), and a File block with placeholder.csv: what the block outputs when it posts the sample.
  2. The question: which alerts were posted, and which were skipped?
  3. Look at the placeholder records: five posted, Glasgow skipped.
  4. To post for real: set up a Slack app as the README describes, paste its bot token and your channel ID, and run the block.

Running in Omniscope

Omniscope workflow
Omniscope workflow

The demo project's workflow: the sample data, the block, and a Validate data check on its output.

Language and libraries

Python. It uses requests (Apache License 2.0) and pandas (BSD 3-Clause).

pandas is part of Omniscope's Python environment. requests is listed in the block's dependencies, so Omniscope installs it with pip on first run if it is missing.

Tested

The block is covered by automated tests that run its script against a stand-in for Omniscope's Python API and a stand-in for Slack's API with canned replies (no live calls): the sample, with every request checked (channel, text, token header); links, escaping and existing Slack markup; integer and date fields with missing values; a file attachment, with the three upload requests checked; a missing file; Slack's refusals (not in channel, bad token, a server error, no network), with the count of messages already posted; missing settings; empty input; and 2,000 messages.

Reference

Fields it reads

NameTypeWhat it does
Message fieldFieldThe field holding each record's message. Web addresses become links (a link ends at the first space, so write spaces in addresses as %20).

Options

NameTypeWhat it does
Bot User OAuth tokenPasswordFrom the app's OAuth & Permissions page in Slack; it starts with xoxb-.
Channel IDTextIn the channel's details (at the bottom of the About tab), such as C0123ABCD. The app must be in the channel.
File to attachFileOptional. A file on the machine running Omniscope, attached to every message (needs the files:write scope).
Attachment titleTextThe title Slack shows for the attached file.

Outputs

OutputWhat it holds
MessagesOne record per input record: Row, Message (as sent, in Slack's format), AttachmentPath.
SentOne record per input record: Row, Action (postMessage, upload_with_comment or skip), Channel, Timestamp (Slack's message ts), File ID.