![]() |
VOOZH | about |
dotnet add package Ananke.Platforms.Slack --version 0.8.5
NuGet\Install-Package Ananke.Platforms.Slack -Version 0.8.5
<PackageReference Include="Ananke.Platforms.Slack" Version="0.8.5" />
<PackageVersion Include="Ananke.Platforms.Slack" Version="0.8.5" />Directory.Packages.props
<PackageReference Include="Ananke.Platforms.Slack" />Project file
paket add Ananke.Platforms.Slack --version 0.8.5
#r "nuget: Ananke.Platforms.Slack, 0.8.5"
#:package Ananke.Platforms.Slack@0.8.5
#addin nuget:?package=Ananke.Platforms.Slack&version=0.8.5Install as a Cake Addin
#tool nuget:?package=Ananke.Platforms.Slack&version=0.8.5Install as a Cake Tool
Slack adapter for Ananke - bridges Slack Bot events (Socket Mode and Events API) to Ananke agent workflows via IMessagePlatformAdapter. Supports streaming chat responses using the post-then-edit pattern with automatic debouncing.
dotnet add package Ananke.Platforms.Slack
xapp-…)message.channels, message.groups, message.im, message.mpimxoxb-…)using Ananke.Platforms;
using Ananke.Platforms.Slack;
services.AddAnankeSlack(options =>
{
options.BotToken = config["Slack:BotToken"]!;
options.AppToken = config["Slack:AppToken"]!;
options.UseSocketMode = true;
});
services.AddSingleton<IPlatformMessageHandler, MyAgentHandler>();
| Service | Implementation |
|---|---|
IMessagePlatformAdapter |
SlackAdapter — Socket Mode (WebSocket) or Events API (HTTP), dispatches incoming messages |
IPlatformResponseSink |
SlackResponseSink — chat.postMessage / chat.update / reactions.add via Slack Web API |
IHostedService |
SlackHostedService — starts/stops the adapter with the application host |
| Mode | Config | Public URL required | Best for |
|---|---|---|---|
| Socket Mode | UseSocketMode = true + AppToken |
No | Development, internal bots |
| Events API | UseSocketMode = false + SigningSecret |
Yes | Production, high-traffic |
Enable with SlackAdapterOptions.EnableSlashCommands = true (requires SigningSecret).
Incoming payloads are normalised to PlatformSlashCommand and dispatched via
IPlatformMessageHandler.OnSlashCommandAsync(...).
services.AddAnankeSlack(options =>
{
options.EnableSlashCommands = true;
options.SigningSecret = config["Slack:SigningSecret"]!;
});
Map the endpoint (Events API mode only):
app.MapAnankeSlackEvents(); // registers /slack/events, /slack/commands, /slack/interactivity
Enable with SlackAdapterOptions.EnableInteractivity = true.
Payloads are normalised to PlatformInteractionEvent (ActionId, Value, TriggerId,
UserId, ChannelId, ThreadId) and dispatched via
IPlatformMessageHandler.OnInteractionAsync(...).
Use SlackApprovalBlocks to render Approve / Revise / Reject buttons, and
SlackApprovalCallback (from Ananke.Roles.Slack) to bridge the interaction to a
CallbackWorkReviewGate.
Enable with SlackAdapterOptions.EnableAssistant = true.
assistant_thread_started and assistant_thread_context_changed events are normalised
to PlatformAssistantThreadEvent and dispatched via
IPlatformMessageHandler.OnAssistantThreadAsync(...).
options.EnableAssistant = true;
options.AssistantStatusLabel = "thinking…"; // default
The response sink exposes two Assistant-specific helpers:
await sink.SetAssistantStatusAsync(channelId, threadTs, "loading context…", ct);
await sink.SetSuggestedPromptsAsync(channelId, threadTs,
new[] { "Summarise the backlog", "What needs review?" }, ct);
var slackSink = (ISlackResponseSink)responseSink;
await slackSink.OpenViewAsync(triggerId, modalView, ct);
await slackSink.UpdateViewAsync(viewId, modalView, ct);
Attach traceability metadata on chat.postMessage:
await slackSink.SendBlocksWithMetadataAsync(channelId, blocks,
metadata: new SlackMessageMetadata { EventType = "ananke_review", Payload = ... }, ct);
SlackApprovalBlocks.Build(workItem) returns a Block Kit layout with Approve / Revise /
Reject buttons wired to the canonical action ids (ananke_approve, ananke_revise,
ananke_reject). Post the blocks, then use SlackApprovalCallback on the
OnInteractionAsync path to resolve the pending IWorkReviewGate decision.
Control how large files are uploaded via SlackAdapterOptions.UploadMode:
| Value | Behaviour |
|---|---|
ExternalUrlV2 (default) |
Uses files.getUploadURLExternal + files.completeUploadExternal. Retries automatically on expired_url. |
LegacyFilesUpload |
Falls back to the deprecated files.upload API for compatibility. |
| Scope | Required for |
|---|---|
app_mentions:read |
Receiving app_mention events |
assistant:write |
Setting Assistant pane status and suggested prompts |
chat:write |
Posting messages |
chat:write.public |
Posting in channels the bot hasn't joined |
commands |
Receiving slash commands |
files:write |
Uploading files |
reactions:write |
Adding emoji reactions |
reactions:read |
Receiving reaction_added events |
channels:history |
Reading channel message history |
groups:history |
Reading private channel history |
im:history |
Reading DM history |
metadata.message:read |
Reading message metadata payloads |
Slack does not support server-push streaming into a message. The adapter uses the post-then-edit pattern:
…) is postedchat.update (debounced at 300 ms)Slack threads are handled automatically. Messages with a thread_ts are routed with PlatformMessage.ThreadId set, and responses are posted back into the same thread.
Unlike Discord, where slash commands can be registered programmatically at runtime, Slack slash commands have significant limitations that prevent automatic ToolKit → /command bridging:
| Limitation | Detail |
|---|---|
| No programmatic registration | Slack requires slash commands to be manually configured in the App dashboard (api.slack.com/apps → Slash Commands). There is no API to create, update, or remove commands at runtime. Every tool must be added by hand. |
| No structured parameters | Slack slash commands accept a single free-text string after the command name (e.g., /echo hello world). There are no typed parameters, no autocomplete, and no validation. The handler must parse the text manually. |
| 3-second response timeout | Slack's HTTP request must be acknowledged within 3 seconds. For tools that take longer, you must send an immediate acknowledgment and post the result later via response_url or chat.postMessage. |
| No parameter autocomplete | Discord shows parameter names, types, and descriptions in the command picker. Slack provides nothing — just a text input box. |
| Separate handler registration | SlackNet uses ISlashCommandHandler for slash commands, which is a different registration path from the IEventHandler<MessageEvent> used for messages. Commands and chat messages don't share a handler pipeline. |
Slack chat messages (DMs and channel messages) flow through SlackAdapter → IPlatformMessageHandler → StreamingChatWorkflow with full streaming and tool support. The LLM invokes tools naturally during conversation — this covers the primary use case.
If Slack introduces a richer command model (or if demand justifies the manual-registration workflow), a future version could provide:
SlackSlashCommandHandler that maps incoming /command text to ToolKit.Tools[name].ExecuteAsyncToolKit manifestresponse_url-based async responses for long-running toolsFor now, the recommendation is to use Discord for slash-command-style tool invocation and Slack for conversational agent workflows.
Full docs, demos, and architecture: github.com/sevensamurai/Ananke
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
Showing the top 1 NuGet packages that depend on Ananke.Platforms.Slack:
| Package | Downloads |
|---|---|
|
Ananke.Roles
Role catalog, manifest generation, and studio host wiring for persona-driven Ananke applications. |
This package is not used by any popular GitHub repositories.