(() => {
+ if (!isMergedKinds) return undefined
+
+ const labels = subBlock.credentialLabels
+ const toOption = (cred: (typeof credentials)[number]) => ({
+ label: cred.name,
+ value: cred.id,
+ iconElement: getProviderIcon((cred.provider ?? provider) as OAuthProvider),
+ })
+
+ return [
+ {
+ section: labels?.oauthGroup ?? `${getProviderName(provider)} accounts`,
+ items: [
+ ...credentials.filter((c) => c.type !== 'service_account').map(toOption),
+ {
+ label: labels?.oauthConnect ?? `Connect ${getProviderName(provider)} account`,
+ value: '__connect_account__',
+ iconElement: ,
+ },
+ ],
+ },
+ {
+ section: labels?.serviceAccountGroup ?? 'Service accounts',
+ items: [
+ ...credentials.filter((c) => c.type === 'service_account').map(toOption),
+ {
+ label: labels?.serviceAccountConnect ?? `Add ${getProviderName(provider)} key`,
+ value: '__connect_service_account__',
+ iconElement: ,
+ },
+ ],
+ },
+ ]
+ }, [
+ isMergedKinds,
+ subBlock.credentialLabels,
+ credentials,
provider,
getProviderIcon,
getProviderName,
@@ -320,9 +365,17 @@ export function CredentialSelector({
const handleComboboxChange = useCallback(
(value: string) => {
if (value === '__connect_account__') {
+ if (isMergedKinds) {
+ setShowConnectModal(true)
+ return
+ }
handleAddCredential()
return
}
+ if (value === '__connect_service_account__') {
+ setShowSetupModal(true)
+ return
+ }
const matchedCred = (
isAllCredentials ? allWorkspaceCredentials.filter((c) => c.type === 'oauth') : credentials
@@ -335,13 +388,21 @@ export function CredentialSelector({
setIsEditing(true)
setEditingValue(value)
},
- [isAllCredentials, allWorkspaceCredentials, credentials, handleAddCredential, handleSelect]
+ [
+ isAllCredentials,
+ isMergedKinds,
+ allWorkspaceCredentials,
+ credentials,
+ handleAddCredential,
+ handleSelect,
+ ]
)
return (
c.type !== 'service_account').length,
workspaceId,
requestedAt: Date.now(),
})
@@ -417,22 +480,10 @@ export function CredentialSelector({
/>
)}
- {showSlackBotModal && (
- {
- setStoreValue(newCredentialId)
- refetchCredentials()
- }}
- />
- )}
-
- {showServiceAccountModal && serviceAccountService?.serviceAccountProviderId && (
+ {showSetupModal && serviceAccountService?.serviceAccountProviderId && (
{
+ // v1 gates on authMethod (raw bot token vs OAuth); v2 has one merged
+ // credential field for actions and customBotCredential for triggers.
const authMethod = deps.authMethod as string
const oauthCredential =
authMethod === 'bot_token'
- ? String(deps.customBotCredential ?? deps.botToken ?? '')
- : String(deps.credential ?? deps.customBotCredential ?? deps.triggerCredentials ?? '')
+ ? String(deps.botToken ?? '')
+ : String(deps.credential ?? deps.customBotCredential ?? '')
return { ...context, oauthCredential }
},
}
diff --git a/apps/sim/blocks/blocks/slack.ts b/apps/sim/blocks/blocks/slack.ts
index b0a69183295..1792db96c52 100644
--- a/apps/sim/blocks/blocks/slack.ts
+++ b/apps/sim/blocks/blocks/slack.ts
@@ -2627,48 +2627,51 @@ export const SlackBlockMeta = {
],
} as const satisfies BlockMeta
-/**
- * Custom Bot picker used by slack_v2 in place of v1's raw bot-token field — a
- * canonical basic/advanced pair (dropdown + manual credential-ID paste),
- * mirroring the OAuth `credential`/`manualCredential` pair.
- */
-const SLACK_CUSTOM_BOT_SUBBLOCKS: SubBlockConfig[] = [
- {
- id: 'customBotCredential',
- title: 'Slack Bot',
- type: 'oauth-input',
- canonicalParamId: 'botCredential',
- mode: 'basic',
- serviceId: 'slack',
- credentialKind: 'custom-bot',
- requiredScopes: getScopesForService('slack'),
- placeholder: 'Select a connected bot',
- dependsOn: ['authMethod'],
- condition: { field: 'authMethod', value: 'bot_token' },
- required: true,
- },
- {
- id: 'manualCustomBotCredential',
- title: 'Bot Credential ID',
- type: 'short-input',
- canonicalParamId: 'botCredential',
- mode: 'advanced',
- placeholder: 'Enter bot credential ID',
- dependsOn: ['authMethod'],
- condition: { field: 'authMethod', value: 'bot_token' },
- required: true,
- },
-]
-
const SLACK_WEBHOOK_TRIGGER_SUBBLOCK_IDS = new Set(
getTrigger('slack_webhook').subBlocks.map((sb) => sb.id)
)
+/**
+ * Adapts a v1 subblock for slack_v2's merged credential picker: fields gated on
+ * the removed `authMethod` dropdown now depend on the single `credential` field.
+ */
+function adaptSubBlockForV2(sb: SubBlockConfig): SubBlockConfig {
+ const { dependsOn, condition, ...rest } = sb
+ if (sb.id === 'credential') {
+ return {
+ ...rest,
+ credentialKind: 'any',
+ placeholder: 'Select Slack account or bot',
+ credentialLabels: {
+ oauthGroup: 'Sim app',
+ oauthConnect: 'Connect the Sim app',
+ serviceAccountGroup: 'Custom bots',
+ serviceAccountConnect: 'Set up a custom bot',
+ },
+ }
+ }
+ if (sb.id === 'manualCredential') {
+ return { ...rest, placeholder: 'Enter credential ID' }
+ }
+ if (dependsOn && !Array.isArray(dependsOn) && dependsOn.all?.includes('authMethod')) {
+ return { ...sb, dependsOn: ['credential'] }
+ }
+ return sb
+}
+
+const {
+ authMethod: _authMethod,
+ botToken: _botToken,
+ botCredential: _botCredential,
+ ...slackV2Inputs
+} = SlackBlock.inputs
+
/**
* slack_v2 — the go-forward Slack action block. Identical operations, tools, and
- * outputs to v1 (shared by reference), but the "Custom Bot" auth method selects
- * a reusable bot credential set up once, instead of pasting a raw token. Also
- * hosts the redesigned slack_oauth trigger (v1 keeps the legacy slack_webhook).
+ * outputs to v1 (shared by reference), but auth is a single credential picker
+ * listing Sim OAuth accounts and reusable custom bots together — the credential's
+ * kind is resolved server-side, so no auth-method choice is needed. Also hosts
+ * the redesigned slack_oauth trigger (v1 keeps the legacy slack_webhook).
*/
export const SlackV2Block: BlockConfig = {
...SlackBlock,
@@ -2683,13 +2686,18 @@ export const SlackV2Block: BlockConfig = {
...SlackBlock.subBlocks.flatMap((sb) => {
// Drop the legacy paste-secret trigger config (v1 hosts slack_webhook)
// and v1's raw bot-token auth field — the trigger set includes an
- // id-colliding 'botToken', so the set check covers both.
+ // id-colliding 'botToken', so the set check covers both. The authMethod
+ // dropdown is gone: the merged credential picker covers both auth kinds.
if (SLACK_WEBHOOK_TRIGGER_SUBBLOCK_IDS.has(sb.id)) return []
- if (sb.id === 'authMethod') return [sb, ...SLACK_CUSTOM_BOT_SUBBLOCKS]
- return [sb]
+ if (sb.id === 'authMethod') return []
+ return [adaptSubBlockForV2(sb)]
}),
...getTrigger('slack_oauth').subBlocks,
],
+ inputs: {
+ ...slackV2Inputs,
+ oauthCredential: { type: 'string', description: 'Slack credential (OAuth account or bot)' },
+ },
triggers: {
enabled: true,
available: ['slack_oauth'],
diff --git a/apps/sim/blocks/types.ts b/apps/sim/blocks/types.ts
index 3ed75ecefde..1abe2b8e379 100644
--- a/apps/sim/blocks/types.ts
+++ b/apps/sim/blocks/types.ts
@@ -367,14 +367,24 @@ export interface SubBlockConfig {
serviceId?: string
requiredScopes?: string[]
/**
- * Narrows an `oauth-input` selector to a specific credential kind. `'custom-bot'`
- * lists only reusable custom Slack bot credentials (service-account type) and its
- * connect row opens the custom-bot setup modal instead of the OAuth flow.
- * `'service-account'` is the generic equivalent for a no-OAuth provider: it lists
- * only service-account credentials and its connect row opens the descriptor-driven
- * token-paste modal (`ConnectServiceAccountModal`).
+ * Narrows an `oauth-input` selector to a specific credential kind.
+ * `'service-account'` lists only service-account credentials; its connect row
+ * opens the provider's setup modal (resolved from the service-account setup
+ * registry — a bespoke wizard when registered, the generic token-paste modal
+ * otherwise). `'any'` lists OAuth accounts and service accounts together in a
+ * grouped dropdown with a connect action for each kind.
*/
- credentialKind?: 'custom-bot' | 'service-account'
+ credentialKind?: 'service-account' | 'any'
+ /**
+ * Overrides the credential picker's section and connect-row copy. Unset keys
+ * fall back to generic provider-derived labels.
+ */
+ credentialLabels?: {
+ oauthGroup?: string
+ oauthConnect?: string
+ serviceAccountGroup?: string
+ serviceAccountConnect?: string
+ }
/**
* Opts a trigger-mode `oauth-input` selector into listing service-account
* credentials, which are otherwise excluded in trigger mode. Set only when the
diff --git a/apps/sim/lib/webhooks/deploy.test.ts b/apps/sim/lib/webhooks/deploy.test.ts
index c5a96499b86..8409705850d 100644
--- a/apps/sim/lib/webhooks/deploy.test.ts
+++ b/apps/sim/lib/webhooks/deploy.test.ts
@@ -62,6 +62,23 @@ const tableTrigger = trigger([
{ id: 'manualTableId', mode: 'trigger-advanced', canonicalParamId: 'tableId', required: true },
])
+const slackTrigger = trigger([
+ { id: 'eventType', mode: 'trigger', required: true },
+ {
+ id: 'customBotCredential',
+ mode: 'trigger',
+ canonicalParamId: 'botCredential',
+ serviceId: 'slack',
+ required: true,
+ },
+ {
+ id: 'manualBotCredential',
+ mode: 'trigger-advanced',
+ canonicalParamId: 'botCredential',
+ required: true,
+ },
+])
+
function makeBlock(
type: string,
subBlockValues: Record,
@@ -155,6 +172,28 @@ describe('buildProviderConfig canonical collapse', () => {
const { providerConfig } = buildProviderConfig(block, 'table_new_row', tableTrigger)
expect(providerConfig.tableId).toBe('ACTIVE')
})
+
+ it('collapses the slack bot credential pair under botCredential for the routing branch', () => {
+ const block = makeBlock('slack_v2', {
+ eventType: 'message',
+ customBotCredential: 'cred_bot_1',
+ })
+ const result = buildProviderConfig(block, 'slack_oauth', slackTrigger)
+
+ expect(result.providerConfig.botCredential).toBe('cred_bot_1')
+ expect(result.providerConfig.eventType).toBe('message')
+ // The slack trigger has no generic triggerCredentials field — the routing
+ // branch resolves botCredential itself.
+ expect(result.credentialReference).toBeUndefined()
+ expect(result.credentialServiceId).toBeUndefined()
+ })
+
+ it('reports a missing required slack bot credential as a missing field', () => {
+ const block = makeBlock('slack_v2', { eventType: 'message' })
+ const result = buildProviderConfig(block, 'slack_oauth', slackTrigger)
+
+ expect(result.missingFields.length).toBeGreaterThan(0)
+ })
})
describe('resolveTriggerCredentialId', () => {
diff --git a/apps/sim/lib/webhooks/deploy.ts b/apps/sim/lib/webhooks/deploy.ts
index d667f0391d5..1678159e2f7 100644
--- a/apps/sim/lib/webhooks/deploy.ts
+++ b/apps/sim/lib/webhooks/deploy.ts
@@ -1,5 +1,5 @@
import { db } from '@sim/db'
-import { account, credential, webhook, workflowDeploymentVersion } from '@sim/db/schema'
+import { credential, webhook, workflowDeploymentVersion } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { generateShortId } from '@sim/utils/id'
@@ -15,7 +15,6 @@ import {
projectDesiredWebhookProviderConfig,
} from '@/lib/webhooks/provider-subscriptions'
import { getProviderHandler } from '@/lib/webhooks/providers'
-import { fetchSlackTeamId } from '@/lib/webhooks/providers/slack'
import {
prepareStableWebhookRegistrations,
type StableDesiredWebhookRegistration,
@@ -27,17 +26,12 @@ import {
isCanonicalPair,
resolveActiveCanonicalValue,
} from '@/lib/workflows/subblocks/visibility'
-import {
- getSlackBotCredential,
- refreshAccessTokenIfNeeded,
- resolveOAuthAccountId,
-} from '@/app/api/auth/oauth/utils'
+import { getSlackBotCredential } from '@/app/api/auth/oauth/utils'
import { getBlock } from '@/blocks'
import type { SubBlockConfig } from '@/blocks/types'
import type { BlockState } from '@/stores/workflows/workflow/types'
import { getTrigger, isTriggerValid } from '@/triggers'
import { SYSTEM_SUBBLOCK_IDS } from '@/triggers/constants'
-import { SIM_SUBSCRIBED_EVENTS } from '@/triggers/slack/shared'
const logger = createLogger('DeployWebhookSync')
@@ -431,106 +425,43 @@ async function resolveWebhookConfigForBlock(input: {
let effectivePath: string | null = triggerPath
let routingKey: string | null = null
if (triggerId === 'slack_oauth') {
- const appType = typeof providerConfig.appType === 'string' ? providerConfig.appType : 'custom'
- if (appType === 'sim') {
- const eventType =
- typeof providerConfig.eventType === 'string' ? providerConfig.eventType : null
- if (eventType && !SIM_SUBSCRIBED_EVENTS.includes(eventType)) {
- return {
- success: false,
- error: {
- message:
- 'This event is not available on the Sim Slack app. Use a custom app or choose a supported event.',
- status: 400,
- },
- }
- }
- if (!credentialId) {
- return {
- success: false,
- error: { message: 'Select a Slack account for the trigger.', status: 400 },
- }
- }
-
- let tokenOwnerUserId = input.userId
- const resolvedAccount = await resolveOAuthAccountId(credentialId)
- if (resolvedAccount?.accountId) {
- const [owner] = await db
- .select({ userId: account.userId })
- .from(account)
- .where(eq(account.id, resolvedAccount.accountId))
- .limit(1)
- if (owner?.userId) tokenOwnerUserId = owner.userId
- }
- const botToken = await refreshAccessTokenIfNeeded(
- credentialId,
- tokenOwnerUserId,
- input.requestId
- )
- if (!botToken) {
- return {
- success: false,
- error: {
- message: 'Could not access the connected Slack account. Reconnect it and try again.',
- status: 400,
- },
- }
- }
- try {
- const { teamId, userId: botUserId } = await fetchSlackTeamId(botToken)
- routingKey = teamId
- if (botUserId) providerConfig.bot_user_id = botUserId
- } catch (error: unknown) {
- logger.error(
- `[${input.requestId}] Slack team_id resolution failed for ${input.block.id}`,
- error
- )
- return {
- success: false,
- error: {
- message: 'Could not verify the connected Slack workspace. Reconnect it and try again.',
- status: 400,
- },
- }
- }
- effectiveProvider = 'slack_app'
- effectivePath = null
- } else {
- const botCredentialId =
- typeof providerConfig.botCredential === 'string' ? providerConfig.botCredential : undefined
- if (!botCredentialId) {
- return {
- success: false,
- error: { message: 'Select a Slack bot credential for the trigger.', status: 400 },
- }
+ // Custom-bot only: events route by the bot credential to one shared ingest
+ // URL verified with the bot's own signing secret. The native Sim-app path
+ // (team_id routing via the official app) is intentionally not supported yet.
+ const botCredentialId =
+ typeof providerConfig.botCredential === 'string' ? providerConfig.botCredential : undefined
+ if (!botCredentialId) {
+ return {
+ success: false,
+ error: { message: 'Select a Slack bot credential for the trigger.', status: 400 },
}
- const botCredential = await getSlackBotCredential(botCredentialId)
- if (!botCredential) {
- return {
- success: false,
- error: {
- message: 'The selected Slack bot credential is missing or invalid. Reconnect it.',
- status: 400,
- },
- }
+ }
+ const botCredential = await getSlackBotCredential(botCredentialId)
+ if (!botCredential) {
+ return {
+ success: false,
+ error: {
+ message: 'The selected Slack bot credential is missing or invalid. Reconnect it.',
+ status: 400,
+ },
}
- const workflowWorkspace =
- typeof input.workflow.workspaceId === 'string' ? input.workflow.workspaceId : undefined
- if (!workflowWorkspace || botCredential.workspaceId !== workflowWorkspace) {
- return {
- success: false,
- error: {
- message: 'The selected Slack bot credential is not available in this workspace.',
- status: 400,
- },
- }
+ }
+ const workflowWorkspace =
+ typeof input.workflow.workspaceId === 'string' ? input.workflow.workspaceId : undefined
+ if (!workflowWorkspace || botCredential.workspaceId !== workflowWorkspace) {
+ return {
+ success: false,
+ error: {
+ message: 'The selected Slack bot credential is not available in this workspace.',
+ status: 400,
+ },
}
- effectiveProvider = 'slack'
- effectivePath = null
- routingKey = botCredentialId
- providerConfig.credentialId = botCredentialId
- if (botCredential.botUserId) providerConfig.bot_user_id = botCredential.botUserId
}
+ effectiveProvider = 'slack'
+ effectivePath = null
+ routingKey = botCredentialId
+ providerConfig.credentialId = botCredentialId
+ if (botCredential.botUserId) providerConfig.bot_user_id = botCredential.botUserId
}
return {
diff --git a/apps/sim/lib/workflows/persistence/utils.ts b/apps/sim/lib/workflows/persistence/utils.ts
index 1de604a8d80..f762108e528 100644
--- a/apps/sim/lib/workflows/persistence/utils.ts
+++ b/apps/sim/lib/workflows/persistence/utils.ts
@@ -356,6 +356,8 @@ export const CREDENTIAL_SUBBLOCK_IDS = new Set([
'credential',
'manualCredential',
'triggerCredentials',
+ 'customBotCredential',
+ 'manualBotCredential',
])
async function migrateCredentialIds(
diff --git a/apps/sim/triggers/slack/oauth.ts b/apps/sim/triggers/slack/oauth.ts
index 1591889831b..368b4128dc5 100644
--- a/apps/sim/triggers/slack/oauth.ts
+++ b/apps/sim/triggers/slack/oauth.ts
@@ -1,9 +1,7 @@
import { SlackIcon } from '@/components/icons'
import { getScopesForService } from '@/lib/oauth/utils'
-import { useSubBlockStore } from '@/stores/workflows/subblock/store'
import {
SLACK_ALL_EVENT_OPTIONS,
- SLACK_SIM_EVENT_OPTIONS,
SLACK_SOURCE_OPTIONS,
SLACK_THREAD_OPTIONS,
SLACK_TRIGGER_OUTPUTS,
@@ -25,14 +23,11 @@ const BOT_FILTER_EVENTS = ['message', 'app_mention']
const OWN_MESSAGE_EVENTS = ['message', 'app_mention', 'reaction_added', 'reaction_removed']
/**
- * Unified Slack trigger. App Type selects how events arrive:
- * - `sim` (default): the official Sim Slack app the user OAuth-connects — events
- * route to this workflow by Slack `team_id` (stored as the webhook `routingKey`,
- * derived at deploy time). No signing secret, bot token, or app setup.
- * - `custom`: a bring-your-own Slack app, selected as a reusable bot credential
- * (set up once). Events route by that credential (`webhook.routingKey =
- * credentialId`) to one shared ingest URL, so many triggers on the same bot
- * share a single Request URL, verified with the bot's own signing secret.
+ * Slack trigger backed by a reusable custom-bot credential (set up once, reused
+ * across triggers and actions). Events route by that credential
+ * (`webhook.routingKey = credentialId`) to one shared ingest URL, so many
+ * triggers on the same bot share a single Request URL, verified with the bot's
+ * own signing secret.
*/
export const slackOAuthTrigger: TriggerConfig = {
id: 'slack_oauth',
@@ -47,50 +42,12 @@ export const slackOAuthTrigger: TriggerConfig = {
id: 'eventType',
title: 'Event',
type: 'dropdown',
- options: [...SLACK_SIM_EVENT_OPTIONS],
+ options: [...SLACK_ALL_EVENT_OPTIONS],
placeholder: 'Select an event',
description:
'The single Slack event this trigger fires on. Add another trigger block for another event.',
required: true,
mode: 'trigger',
- dependsOn: ['appType'],
- fetchOptions: async (blockId: string) => {
- const appType = useSubBlockStore.getState().getValue(blockId, 'appType')
- return appType === 'custom' ? [...SLACK_ALL_EVENT_OPTIONS] : [...SLACK_SIM_EVENT_OPTIONS]
- },
- },
- {
- id: 'appType',
- title: 'App Type',
- type: 'dropdown',
- // Ship 1 exposes custom bots only; the native "Sim" app mode returns in a
- // later ship (un-hide + default back to 'sim'). Hidden — not removed — so
- // the seeded 'custom' value keeps every `appType==='custom'` condition, the
- // event-catalog fetch, and the deploy routing branch resolving correctly.
- hidden: true,
- options: [
- { label: 'Sim', id: 'sim' },
- { label: 'Custom', id: 'custom' },
- ],
- value: () => 'custom',
- // `value()` only seeds editor-created blocks; `defaultValue` is what
- // buildProviderConfig persists when the stored value is absent
- // (imported / programmatically-created workflows).
- defaultValue: 'custom',
- description: 'Use the official Sim Slack app, or your own custom Slack app.',
- mode: 'trigger',
- },
- {
- id: 'triggerCredentials',
- title: 'Slack Account',
- type: 'oauth-input',
- canonicalParamId: 'oauthCredential',
- serviceId: 'slack',
- requiredScopes: getScopesForService('slack'),
- placeholder: 'Select Slack account',
- required: { field: 'appType', value: 'sim' },
- mode: 'trigger',
- condition: { field: 'appType', value: 'sim' },
},
{
id: 'customBotCredential',
@@ -98,14 +55,14 @@ export const slackOAuthTrigger: TriggerConfig = {
type: 'oauth-input',
canonicalParamId: 'botCredential',
serviceId: 'slack',
- credentialKind: 'custom-bot',
+ credentialKind: 'service-account',
+ credentialLabels: { serviceAccountConnect: 'Set up a custom bot' },
requiredScopes: getScopesForService('slack'),
placeholder: 'Select a connected bot',
description:
'Choose a custom Slack bot you set up once and reuse across triggers and actions.',
- required: { field: 'appType', value: 'custom' },
+ required: true,
mode: 'trigger',
- condition: { field: 'appType', value: 'custom' },
},
{
id: 'manualBotCredential',
@@ -114,9 +71,8 @@ export const slackOAuthTrigger: TriggerConfig = {
canonicalParamId: 'botCredential',
placeholder: 'Enter bot credential ID',
description: 'Set the custom bot credential ID directly.',
- required: { field: 'appType', value: 'custom' },
+ required: true,
mode: 'trigger-advanced',
- condition: { field: 'appType', value: 'custom' },
},
{
id: 'source',
@@ -142,7 +98,7 @@ export const slackOAuthTrigger: TriggerConfig = {
placeholder: 'Any channel the bot is in',
description:
'Restrict to specific channels. Leave empty to trigger on any channel the bot has been added to.',
- dependsOn: { any: ['triggerCredentials', 'customBotCredential'] },
+ dependsOn: ['customBotCredential'],
required: false,
mode: 'trigger',
condition: { field: 'eventType', value: CHANNEL_FILTER_EVENTS },
diff --git a/apps/sim/triggers/slack/shared.ts b/apps/sim/triggers/slack/shared.ts
index 0efca9c72ac..4372f7ba68b 100644
--- a/apps/sim/triggers/slack/shared.ts
+++ b/apps/sim/triggers/slack/shared.ts
@@ -271,17 +271,7 @@ export const slackEventById = new Map(
SLACK_EVENT_CATALOG.map((entry) => [entry.id, entry])
)
-/** Event ids the official shared Sim app subscribes to (Sim-mode gating SOT). */
-export const SIM_SUBSCRIBED_EVENTS: readonly string[] = SLACK_EVENT_CATALOG.filter(
- (entry) => entry.simSubscribed
-).map((entry) => entry.id)
-
-/** Dropdown options for Sim mode — only officially-subscribed events. */
-export const SLACK_SIM_EVENT_OPTIONS = SLACK_EVENT_CATALOG.filter(
- (entry) => entry.simSubscribed
-).map((entry) => ({ label: entry.label, id: entry.id }))
-
-/** Dropdown options for Custom mode — every event (manifest generated on demand). */
+/** Dropdown options for the event picker — every event (manifest generated on demand). */
export const SLACK_ALL_EVENT_OPTIONS = SLACK_EVENT_CATALOG.map((entry) => ({
label: entry.label,
id: entry.id,