Configuration
Credential resolution, dependency registration, timeouts, and rate limiting
Node Type Registration
The executor class SlackNodeExecutor is registered in ExecutorRegistry under two type codes so it can be dropped onto a canvas either way:
| Registry Key | Notes |
|---|---|
slack | Canonical short name (SlackNodeExecutor.NodeTypeName). |
slack-message | Alias used by FlowStudio canvas template nodes. |
Dependency Registration
Register everything the node needs with a single call in Program.cs / Startup.cs:
builder.Services.AddSlackNodeExecutor();
AddSlackNodeExecutor() (on SlackDependency) registers, in order:
IOperationGuardviaAddOperationGuard()— required bySlackChannelServicefor rate/credit guarding.- All Slack HTTP services via
AddSlackIntegration()—ISlackChatService,SlackMessageService,SlackChannelService,SlackFileService,SlackReactionService,SlackUserService,SlackUserGroupService— each with a typedHttpClient. SlackNodeExecutoritself, scoped.- Both
ExecutorRegistryentries (slack,slack-message).
Hosts that auto-discover plugins via AddExecutorPluginsFromAssembly() do not need to call this explicitly — SlackDependency implements INodeExecutorDependency and is picked up automatically.
HTTP Client Timeouts
| Service | Timeout | Reason |
|---|---|---|
ISlackChatService | 30s | Standard Web API call. |
SlackMessageService | 30s | Standard Web API call. |
SlackChannelService | 30s | Standard Web API call. |
SlackFileService | 120s | File uploads can be large; longer window than the default. |
SlackReactionService | 30s | Standard Web API call. |
SlackUserService | 30s | Standard Web API call. |
SlackUserGroupService | 30s | Standard Web API call. |
Rate Limiting
Every typed HttpClient above has SlackRateLimitHandler attached as a DelegatingHandler. On an HTTP 429 response it reads the Retry-After header (falling back to 30 seconds if absent) and retries automatically, up to 3 attempts, before surfacing the final 429 to the caller. This is transparent to every operation on this node — no per-operation configuration is required.
Credential Resolution
Every operation DTO derives from BaseSlackOperationInfo, which carries two credential-related fields:
| Field | Config Key | Notes |
|---|---|---|
BotToken | botToken | Inline bot token (xoxb-...). Used directly when no credentialID is set. |
CredentialId | credentialID | Optional. When set, the executor resolves the bearer token from the credential vault via ICredentialResolver, overwriting BotToken before the operation runs. |
Resolution priority, implemented in SlackNodeExecutor.ApplyBotTokenAsync:
- If
credentialIDis set, resolve the bearer token from the vault. Missing resolver or missing credential both return a structured error (CREDENTIAL_RESOLVER_NOT_CONFIGURED/CREDENTIAL_NOT_FOUND). - Otherwise, use the inline
botTokenconfig value. - If neither resolves to a non-empty token, the operation fails with
MISSING_BOT_TOKEN.
message/search and user/updateProfile call Slack endpoints that reject bot tokens outright — they require a user-level OAuth token (xoxp-...), supplied via their own botToken / userToken config field. See Authentication & Setup.
Shared Config Keys
Every operation reads three keys before any operation-specific fields:
| Key | Type | Notes |
|---|---|---|
resource | string | One of message, channel, file, reaction, user, userGroup. |
operation | string | Operation name within the resource (e.g. send, getMany). |
botToken / credentialID | string / int | See Credential Resolution above. |
Output Ports
ValidateExecutorSettings() ensures every Slack node instance has both standard output ports created via GetOrCreatePortSuccessAndError(): a success port and an error port. Every operation partial writes to exactly one of the two. See Input & Output for the full result shape.