Metadata-Version: 2.5
Name: render-lab-tasks-slack
Version: 0.1.0
Summary: Slack messaging tasks for Render Workflows
Project-URL: Repository, https://github.com/render-lab/render-tasks-python
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.12
Requires-Dist: httpx<0.29,>=0.28
Requires-Dist: render==1.0.1
Description-Content-Type: text/markdown

# render-lab-tasks-slack

Slack messaging for Render Workflows. Initial subset: `slack.postMessage`.
The other TypeScript Slack tasks and inbound webhook adapter are not yet ported.

This distribution is not yet on PyPI. From this repository:

```sh
uv pip install ./packages/tasks-slack
```

```python
from render import TaskContext, Workflows
from render_lab_tasks_slack.tasks import app as slack_app, post_message

app = Workflows.from_workflows(slack_app)


@app.task(name="example.notify")
async def notify(ctx: TaskContext):
    return await ctx.run(post_message, {"text": "Hello from Python"})
```

Call `app.start()` from the workflow entry point. `.tasks` also exports
`post_message_impl(ctx, input, deps=...)` for testing and re-registration under
your own task name. Inject `SlackDeps` with fake `SlackPort`/`SlackWebPort` objects.

## Contract

Input requires `text` and supports `title`, `context`, `markdown`, `blocks`,
`attachments`, `channel`, and `username`. Explicit `blocks` (including an empty
list) override generated blocks. Titles, context, and markdown generate Block Kit;
double-star markdown bold becomes Slack single-star bold.

Delivery matches the TypeScript task:

1. A channel plus `SLACK_BOT_TOKEN` uses `chat.postMessage` and returns
   `{delivered: true, channel, ts}`. This route sends text and blocks; legacy
   attachments and username are webhook-only, matching the TS implementation.
2. Otherwise `SLACK_WEBHOOK_URL` is used. Its destination is fixed by Slack;
   the input channel is informational and is not sent in the webhook payload.
3. Without a usable webhook, print the fallback text and return `delivered: false`.
   A bot token without a channel does not select the Web API route.

Absent optional result fields are omitted rather than serialized as null.

## Environment

| Variable | Required | Purpose |
| --- | --- | --- |
| SLACK_WEBHOOK_URL | No | Incoming webhook destination |
| SLACK_BOT_TOKEN | No | Bot token for posting to an explicit channel |

Credentials are read at execution time. HTTPX has a 30-second timeout and no
automatic retries. Render retries failures up to four times with a 1000 ms base
delay and 2x backoff. Slack Web API `ok: false` responses raise even with HTTP 200.
Slack posts are not exactly-once: a retry after an uncertain delivery can duplicate
a message. Webhook exceptions omit the credential-bearing URL.
