@inkeep/agents-work-apps 0.0.0-dev-20260211191741 → 0.0.0-dev-20260211220939

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/env.d.ts +24 -2
  2. package/dist/env.js +13 -2
  3. package/dist/github/index.d.ts +3 -3
  4. package/dist/github/mcp/index.d.ts +2 -2
  5. package/dist/github/routes/setup.d.ts +2 -2
  6. package/dist/github/routes/tokenExchange.d.ts +2 -2
  7. package/dist/github/routes/webhooks.d.ts +2 -2
  8. package/dist/slack/i18n/index.d.ts +2 -0
  9. package/dist/slack/i18n/index.js +3 -0
  10. package/dist/slack/i18n/strings.d.ts +73 -0
  11. package/dist/slack/i18n/strings.js +67 -0
  12. package/dist/slack/index.d.ts +18 -0
  13. package/dist/slack/index.js +28 -0
  14. package/dist/slack/middleware/permissions.d.ts +31 -0
  15. package/dist/slack/middleware/permissions.js +159 -0
  16. package/dist/slack/routes/events.d.ts +10 -0
  17. package/dist/slack/routes/events.js +390 -0
  18. package/dist/slack/routes/index.d.ts +10 -0
  19. package/dist/slack/routes/index.js +47 -0
  20. package/dist/slack/routes/oauth.d.ts +20 -0
  21. package/dist/slack/routes/oauth.js +325 -0
  22. package/dist/slack/routes/users.d.ts +10 -0
  23. package/dist/slack/routes/users.js +358 -0
  24. package/dist/slack/routes/workspaces.d.ts +10 -0
  25. package/dist/slack/routes/workspaces.js +875 -0
  26. package/dist/slack/services/agent-resolution.d.ts +41 -0
  27. package/dist/slack/services/agent-resolution.js +99 -0
  28. package/dist/slack/services/blocks/index.d.ts +73 -0
  29. package/dist/slack/services/blocks/index.js +103 -0
  30. package/dist/slack/services/client.d.ts +105 -0
  31. package/dist/slack/services/client.js +220 -0
  32. package/dist/slack/services/commands/index.d.ts +19 -0
  33. package/dist/slack/services/commands/index.js +538 -0
  34. package/dist/slack/services/events/app-mention.d.ts +40 -0
  35. package/dist/slack/services/events/app-mention.js +234 -0
  36. package/dist/slack/services/events/block-actions.d.ts +40 -0
  37. package/dist/slack/services/events/block-actions.js +221 -0
  38. package/dist/slack/services/events/index.d.ts +6 -0
  39. package/dist/slack/services/events/index.js +7 -0
  40. package/dist/slack/services/events/modal-submission.d.ts +30 -0
  41. package/dist/slack/services/events/modal-submission.js +346 -0
  42. package/dist/slack/services/events/streaming.d.ts +26 -0
  43. package/dist/slack/services/events/streaming.js +228 -0
  44. package/dist/slack/services/events/utils.d.ts +146 -0
  45. package/dist/slack/services/events/utils.js +369 -0
  46. package/dist/slack/services/index.d.ts +16 -0
  47. package/dist/slack/services/index.js +16 -0
  48. package/dist/slack/services/modals.d.ts +86 -0
  49. package/dist/slack/services/modals.js +355 -0
  50. package/dist/slack/services/nango.d.ts +85 -0
  51. package/dist/slack/services/nango.js +462 -0
  52. package/dist/slack/services/security.d.ts +35 -0
  53. package/dist/slack/services/security.js +65 -0
  54. package/dist/slack/services/types.d.ts +26 -0
  55. package/dist/slack/services/types.js +1 -0
  56. package/dist/slack/services/workspace-tokens.d.ts +25 -0
  57. package/dist/slack/services/workspace-tokens.js +27 -0
  58. package/dist/slack/types.d.ts +10 -0
  59. package/dist/slack/types.js +1 -0
  60. package/package.json +10 -2
@@ -0,0 +1,390 @@
1
+ import { env } from "../../env.js";
2
+ import { getLogger } from "../../logger.js";
3
+ import runDbClient_default from "../../db/runDbClient.js";
4
+ import { findWorkspaceConnectionByTeamId, getSlackIntegrationId, getSlackNango, updateConnectionMetadata } from "../services/nango.js";
5
+ import { getSlackClient, getSlackUserInfo } from "../services/client.js";
6
+ import { sendResponseUrlMessage } from "../services/events/utils.js";
7
+ import { handleCommand } from "../services/commands/index.js";
8
+ import { handleAppMention } from "../services/events/app-mention.js";
9
+ import { handleMessageShortcut, handleOpenAgentSelectorModal, handleOpenFollowUpModal } from "../services/events/block-actions.js";
10
+ import { handleFollowUpSubmission, handleModalSubmission } from "../services/events/modal-submission.js";
11
+ import "../services/events/index.js";
12
+ import { parseSlackCommandBody, parseSlackEventBody, verifySlackRequest } from "../services/security.js";
13
+ import "../services/index.js";
14
+ import { OpenAPIHono } from "@hono/zod-openapi";
15
+ import { deleteAllWorkAppSlackChannelAgentConfigsByTeam, deleteAllWorkAppSlackUserMappingsByTeam, deleteWorkAppSlackWorkspaceByNangoConnectionId } from "@inkeep/agents-core";
16
+
17
+ //#region src/slack/routes/events.ts
18
+ /**
19
+ * Slack Events Routes
20
+ *
21
+ * Endpoints for handling Slack events, commands, and webhooks:
22
+ * - POST /commands - Handle /inkeep slash commands
23
+ * - POST /events - Handle Slack events & interactivity
24
+ * - POST /nango-webhook - Handle Nango auth webhooks
25
+ */
26
+ const logger = getLogger("slack-events");
27
+ const app = new OpenAPIHono();
28
+ app.post("/commands", async (c) => {
29
+ const body = await c.req.text();
30
+ const timestamp = c.req.header("x-slack-request-timestamp") || "";
31
+ const signature = c.req.header("x-slack-signature") || "";
32
+ if (!env.SLACK_SIGNING_SECRET) {
33
+ logger.error({}, "SLACK_SIGNING_SECRET not configured - rejecting request");
34
+ return c.json({
35
+ response_type: "ephemeral",
36
+ text: "Server configuration error"
37
+ }, 500);
38
+ }
39
+ if (!verifySlackRequest(env.SLACK_SIGNING_SECRET, body, timestamp, signature)) {
40
+ logger.error({}, "Invalid Slack request signature");
41
+ return c.json({
42
+ response_type: "ephemeral",
43
+ text: "Invalid request signature"
44
+ }, 401);
45
+ }
46
+ const params = parseSlackCommandBody(body);
47
+ const response = await handleCommand({
48
+ command: params.command || "",
49
+ text: params.text || "",
50
+ userId: params.user_id || "",
51
+ userName: params.user_name || "",
52
+ teamId: params.team_id || "",
53
+ teamDomain: params.team_domain || "",
54
+ enterpriseId: params.enterprise_id,
55
+ channelId: params.channel_id || "",
56
+ channelName: params.channel_name || "",
57
+ responseUrl: params.response_url || "",
58
+ triggerId: params.trigger_id || ""
59
+ });
60
+ if (Object.keys(response).length === 0) return c.body(null, 200);
61
+ return c.json(response);
62
+ });
63
+ app.post("/events", async (c) => {
64
+ const contentType = c.req.header("content-type") || "";
65
+ const body = await c.req.text();
66
+ const timestamp = c.req.header("x-slack-request-timestamp") || "";
67
+ const signature = c.req.header("x-slack-signature") || "";
68
+ let eventBody;
69
+ try {
70
+ eventBody = parseSlackEventBody(body, contentType);
71
+ } catch (error) {
72
+ logger.error({
73
+ error,
74
+ contentType,
75
+ bodyPreview: body.slice(0, 200)
76
+ }, "Failed to parse Slack event body");
77
+ return c.json({ error: "Invalid payload" }, 400);
78
+ }
79
+ logger.debug({ eventType: eventBody.type }, "Slack event received");
80
+ const eventType = eventBody.type;
81
+ if (eventType === "url_verification") {
82
+ logger.info({}, "Responding to Slack URL verification challenge");
83
+ return c.text(String(eventBody.challenge));
84
+ }
85
+ if (!env.SLACK_SIGNING_SECRET) {
86
+ logger.error({}, "SLACK_SIGNING_SECRET not configured - rejecting request");
87
+ return c.json({ error: "Server configuration error" }, 500);
88
+ }
89
+ if (!verifySlackRequest(env.SLACK_SIGNING_SECRET, body, timestamp, signature)) {
90
+ logger.error({}, "Invalid Slack request signature");
91
+ return c.json({ error: "Invalid request signature" }, 401);
92
+ }
93
+ if (eventType === "event_callback") {
94
+ const teamId = eventBody.team_id;
95
+ const event = eventBody.event;
96
+ if (event?.bot_id || event?.subtype === "bot_message") {
97
+ logger.debug({ botId: event.bot_id }, "Ignoring bot message");
98
+ return c.json({ ok: true });
99
+ }
100
+ logger.debug({
101
+ eventType: event?.type,
102
+ teamId
103
+ }, "Slack event callback");
104
+ if (event?.type === "app_mention" && event.channel && event.user && teamId) {
105
+ const question = (event.text || "").replace(/<@[A-Z0-9]+>/g, "").trim();
106
+ logger.info({
107
+ userId: event.user,
108
+ channel: event.channel,
109
+ teamId
110
+ }, "Bot was mentioned");
111
+ handleAppMention({
112
+ slackUserId: event.user,
113
+ channel: event.channel,
114
+ text: question,
115
+ threadTs: event.thread_ts || event.ts || "",
116
+ messageTs: event.ts || "",
117
+ teamId
118
+ }).catch((err) => {
119
+ const errorMessage = err instanceof Error ? err.message : String(err);
120
+ const errorStack = err instanceof Error ? err.stack : void 0;
121
+ logger.error({
122
+ errorMessage,
123
+ errorStack
124
+ }, "Failed to handle app mention (outer catch)");
125
+ });
126
+ }
127
+ }
128
+ if (eventType === "block_actions" || eventType === "interactive_message") {
129
+ logger.debug({ eventType }, "Slack interactive event received");
130
+ const actions = eventBody.actions;
131
+ const teamId = eventBody.team?.id;
132
+ const responseUrl = eventBody.response_url;
133
+ const triggerId = eventBody.trigger_id;
134
+ if (actions && teamId) for (const action of actions) {
135
+ if (action.action_id === "open_agent_selector_modal" && action.value && triggerId) handleOpenAgentSelectorModal({
136
+ triggerId,
137
+ actionValue: action.value,
138
+ teamId,
139
+ responseUrl: responseUrl || ""
140
+ }).catch(async (err) => {
141
+ const errorMessage = err instanceof Error ? err.message : String(err);
142
+ logger.error({
143
+ errorMessage,
144
+ actionId: action.action_id
145
+ }, "Failed to open agent selector modal");
146
+ if (responseUrl) await sendResponseUrlMessage(responseUrl, {
147
+ text: "Sorry, something went wrong while opening the agent selector. Please try again.",
148
+ response_type: "ephemeral"
149
+ }).catch(() => {});
150
+ });
151
+ if (action.action_id === "modal_project_select") {
152
+ const selectedProjectId = action.selected_option?.value;
153
+ const view = eventBody.view;
154
+ if (selectedProjectId && view?.id) (async () => {
155
+ try {
156
+ const metadata = JSON.parse(view.private_metadata || "{}");
157
+ const tenantId = metadata.tenantId || "default";
158
+ const workspace = await findWorkspaceConnectionByTeamId(teamId);
159
+ if (!workspace?.botToken) return;
160
+ const slackClient = getSlackClient(workspace.botToken);
161
+ const { fetchProjectsForTenant, fetchAgentsForProject } = await import("../services/events/utils.js");
162
+ const { buildAgentSelectorModal, buildMessageShortcutModal } = await import("../services/modals.js");
163
+ const projectList = await fetchProjectsForTenant(tenantId);
164
+ const agentList = await fetchAgentsForProject(tenantId, selectedProjectId);
165
+ const agentOptions = agentList.map((a) => ({
166
+ id: a.id,
167
+ name: a.name,
168
+ projectId: a.projectId,
169
+ projectName: a.projectName || a.projectId
170
+ }));
171
+ const modal = metadata.messageContext ? buildMessageShortcutModal({
172
+ projects: projectList,
173
+ agents: agentOptions,
174
+ metadata,
175
+ selectedProjectId,
176
+ messageContext: metadata.messageContext
177
+ }) : buildAgentSelectorModal({
178
+ projects: projectList,
179
+ agents: agentOptions,
180
+ metadata,
181
+ selectedProjectId
182
+ });
183
+ await slackClient.views.update({
184
+ view_id: view.id,
185
+ view: modal
186
+ });
187
+ logger.debug({
188
+ selectedProjectId,
189
+ agentCount: agentList.length
190
+ }, "Updated modal with agents for selected project");
191
+ } catch (err) {
192
+ logger.error({
193
+ err,
194
+ selectedProjectId
195
+ }, "Failed to update modal on project change");
196
+ }
197
+ })();
198
+ }
199
+ if (action.action_id === "open_follow_up_modal" && action.value && triggerId) handleOpenFollowUpModal({
200
+ triggerId,
201
+ actionValue: action.value,
202
+ teamId,
203
+ responseUrl: responseUrl || void 0
204
+ }).catch((err) => {
205
+ const errorMessage = err instanceof Error ? err.message : String(err);
206
+ logger.error({
207
+ errorMessage,
208
+ actionId: action.action_id
209
+ }, "Failed to open follow-up modal");
210
+ });
211
+ }
212
+ }
213
+ if (eventType === "message_action") {
214
+ const callbackId = eventBody.callback_id;
215
+ if (callbackId === "ask_agent_shortcut") {
216
+ const triggerId = eventBody.trigger_id;
217
+ const teamId = eventBody.team?.id;
218
+ const channelId = eventBody.channel?.id;
219
+ const userId = eventBody.user?.id;
220
+ const message = eventBody.message;
221
+ const responseUrl = eventBody.response_url;
222
+ if (triggerId && teamId && channelId && userId && message?.ts) handleMessageShortcut({
223
+ triggerId,
224
+ teamId,
225
+ channelId,
226
+ userId,
227
+ messageTs: message.ts,
228
+ messageText: message.text || "",
229
+ threadTs: message.thread_ts,
230
+ responseUrl
231
+ }).catch((err) => {
232
+ const errorMessage = err instanceof Error ? err.message : String(err);
233
+ logger.error({
234
+ errorMessage,
235
+ callbackId
236
+ }, "Failed to handle message shortcut");
237
+ });
238
+ }
239
+ }
240
+ if (eventType === "view_submission") {
241
+ const callbackId = eventBody.view?.callback_id;
242
+ if (callbackId === "agent_selector_modal") {
243
+ const view = eventBody.view;
244
+ const agentSelect = view.state?.values?.agent_select_block?.agent_select;
245
+ if (!agentSelect?.selected_option?.value || agentSelect.selected_option.value === "none") return c.json({
246
+ response_action: "errors",
247
+ errors: { agent_select_block: "Please select an agent. If none are available, add agents to this project in the dashboard." }
248
+ });
249
+ handleModalSubmission(view).catch((err) => {
250
+ const errorMessage = err instanceof Error ? err.message : String(err);
251
+ logger.error({
252
+ errorMessage,
253
+ callbackId
254
+ }, "Failed to handle modal submission");
255
+ });
256
+ return new Response(null, { status: 200 });
257
+ }
258
+ if (callbackId === "follow_up_modal") {
259
+ const view = eventBody.view;
260
+ handleFollowUpSubmission(view).catch((err) => {
261
+ const errorMessage = err instanceof Error ? err.message : String(err);
262
+ logger.error({
263
+ errorMessage,
264
+ callbackId
265
+ }, "Failed to handle follow-up submission");
266
+ });
267
+ return new Response(null, { status: 200 });
268
+ }
269
+ }
270
+ return c.json({ ok: true });
271
+ });
272
+ app.post("/nango-webhook", async (c) => {
273
+ const body = await c.req.text();
274
+ if (env.NANGO_SECRET_KEY) {
275
+ const signature = c.req.header("x-nango-signature");
276
+ if (!signature) {
277
+ logger.warn({}, "Missing Nango webhook signature");
278
+ return c.json({ error: "Missing signature" }, 401);
279
+ }
280
+ const crypto = await import("node:crypto");
281
+ const expectedSignature = crypto.createHmac("sha256", env.NANGO_SECRET_KEY).update(body).digest("hex");
282
+ if (signature.length !== expectedSignature.length || !crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature))) {
283
+ logger.warn({ signature }, "Invalid Nango webhook signature");
284
+ return c.json({ error: "Invalid signature" }, 401);
285
+ }
286
+ }
287
+ let payload;
288
+ try {
289
+ payload = JSON.parse(body);
290
+ } catch (error) {
291
+ logger.error({
292
+ error,
293
+ bodyPreview: body.slice(0, 200)
294
+ }, "Failed to parse Nango webhook JSON");
295
+ return c.json({ error: "Invalid JSON" }, 400);
296
+ }
297
+ logger.debug({ payload }, "Nango webhook received");
298
+ if (payload.type === "connection_deleted" && payload.connectionId && payload.providerConfigKey) {
299
+ const { connectionId, providerConfigKey } = payload;
300
+ if (providerConfigKey === getSlackIntegrationId()) try {
301
+ const teamMatch = connectionId.match(/T:([A-Z0-9]+)/);
302
+ if (teamMatch) {
303
+ const teamId = teamMatch[1];
304
+ const tenantId = (await findWorkspaceConnectionByTeamId(teamId))?.tenantId || "default";
305
+ if (await deleteWorkAppSlackWorkspaceByNangoConnectionId(runDbClient_default)(connectionId)) logger.info({ connectionId }, "Deleted workspace from database via Nango webhook");
306
+ const deletedMappings = await deleteAllWorkAppSlackUserMappingsByTeam(runDbClient_default)(tenantId, teamId);
307
+ if (deletedMappings > 0) logger.info({
308
+ teamId,
309
+ deletedMappings
310
+ }, "Deleted user mappings via Nango webhook");
311
+ const deletedChannelConfigs = await deleteAllWorkAppSlackChannelAgentConfigsByTeam(runDbClient_default)(tenantId, teamId);
312
+ if (deletedChannelConfigs > 0) logger.info({
313
+ teamId,
314
+ deletedChannelConfigs
315
+ }, "Deleted channel configs via Nango webhook");
316
+ logger.info({
317
+ connectionId,
318
+ teamId
319
+ }, "Processed Nango connection deletion webhook");
320
+ }
321
+ } catch (error) {
322
+ logger.error({
323
+ error,
324
+ connectionId
325
+ }, "Failed to process Nango deletion webhook");
326
+ return c.json({ error: "Deletion processing failed" }, 500);
327
+ }
328
+ return c.json({ received: true });
329
+ }
330
+ if (payload.type === "auth" && payload.success && payload.endUser && payload.connectionId) {
331
+ const { endUser, connectionId } = payload;
332
+ const integrationId = getSlackIntegrationId();
333
+ try {
334
+ const rawResponse = (await getSlackNango().getConnection(integrationId, connectionId)).credentials?.raw;
335
+ logger.debug({ teamId: rawResponse?.team?.id }, "Retrieved Nango connection info");
336
+ if (rawResponse?.ok && rawResponse.access_token) {
337
+ const slackUserId = rawResponse.authed_user?.id || "";
338
+ const slackTeamId = rawResponse.team?.id || "";
339
+ const accessToken = rawResponse.access_token;
340
+ let slackUsername = "";
341
+ let slackDisplayName = "";
342
+ let slackEmail = "";
343
+ let isSlackAdmin = false;
344
+ let isSlackOwner = false;
345
+ if (slackUserId && accessToken) {
346
+ const userInfo = await getSlackUserInfo(getSlackClient(accessToken), slackUserId);
347
+ if (userInfo) {
348
+ slackUsername = userInfo.name || "";
349
+ slackDisplayName = userInfo.displayName || userInfo.realName || "";
350
+ slackEmail = userInfo.email || "";
351
+ isSlackAdmin = userInfo.isAdmin || false;
352
+ isSlackOwner = userInfo.isOwner || false;
353
+ }
354
+ }
355
+ const tenantId = payload.organization?.id || "default";
356
+ await updateConnectionMetadata(connectionId, {
357
+ linked_at: (/* @__PURE__ */ new Date()).toISOString(),
358
+ app_user_id: endUser.endUserId,
359
+ app_user_email: endUser.endUserEmail || "",
360
+ tenant_id: tenantId,
361
+ slack_user_id: slackUserId,
362
+ slack_team_id: slackTeamId,
363
+ slack_team_name: rawResponse.team?.name || "",
364
+ slack_username: slackUsername,
365
+ slack_display_name: slackDisplayName,
366
+ slack_email: slackEmail,
367
+ is_slack_admin: String(isSlackAdmin),
368
+ is_slack_owner: String(isSlackOwner),
369
+ enterprise_id: rawResponse.enterprise?.id || "",
370
+ enterprise_name: rawResponse.enterprise?.name || ""
371
+ });
372
+ logger.info({
373
+ appUserId: endUser.endUserId,
374
+ slackUserId,
375
+ slackEmail
376
+ }, "User linked to Slack with enriched metadata");
377
+ }
378
+ } catch (error) {
379
+ logger.error({
380
+ error,
381
+ connectionId
382
+ }, "Failed to process Nango webhook");
383
+ }
384
+ }
385
+ return c.json({ received: true });
386
+ });
387
+ var events_default = app;
388
+
389
+ //#endregion
390
+ export { events_default as default };
@@ -0,0 +1,10 @@
1
+ import { WorkAppsVariables } from "../types.js";
2
+ import { OpenAPIHono } from "@hono/zod-openapi";
3
+
4
+ //#region src/slack/routes/index.d.ts
5
+
6
+ declare const app: OpenAPIHono<{
7
+ Variables: WorkAppsVariables;
8
+ }, {}, "/">;
9
+ //#endregion
10
+ export { app as default };
@@ -0,0 +1,47 @@
1
+ import events_default from "./events.js";
2
+ import oauth_default from "./oauth.js";
3
+ import users_default from "./users.js";
4
+ import workspaces_default from "./workspaces.js";
5
+ import { OpenAPIHono } from "@hono/zod-openapi";
6
+
7
+ //#region src/slack/routes/index.ts
8
+ /**
9
+ * Slack Work App Routes - Main Router
10
+ *
11
+ * Modular RESTful API structure:
12
+ *
13
+ * OAuth & Installation (oauth.ts):
14
+ * GET /install - Redirect to Slack OAuth
15
+ * GET /oauth_redirect - OAuth callback
16
+ *
17
+ * Workspaces (workspaces.ts):
18
+ * GET /workspaces - List all workspaces
19
+ * GET /workspaces/:teamId - Get workspace details
20
+ * GET /workspaces/:teamId/settings - Get workspace settings
21
+ * PUT /workspaces/:teamId/settings - Update workspace settings [ADMIN]
22
+ * DELETE /workspaces/:teamId - Uninstall workspace [ADMIN]
23
+ * GET /workspaces/:teamId/channels - List channels
24
+ * GET/PUT/DELETE /workspaces/:teamId/channels/:channelId/settings - Channel config
25
+ * GET /workspaces/:teamId/users - List linked users
26
+ *
27
+ * Users (users.ts):
28
+ * GET /users/link-status - Check link status
29
+ * POST /users/link/verify-token - Verify JWT link token (primary linking method)
30
+ * POST /users/connect - Create Nango session
31
+ * POST /users/disconnect - Disconnect/unlink user
32
+ * GET /users/status - Get user connection status
33
+ *
34
+ * Events & Commands (events.ts):
35
+ * POST /commands - Handle slash commands
36
+ * POST /events - Handle Slack events
37
+ * POST /nango-webhook - Handle Nango webhooks
38
+ */
39
+ const app = new OpenAPIHono();
40
+ app.route("/workspaces", workspaces_default);
41
+ app.route("/users", users_default);
42
+ app.route("/", oauth_default);
43
+ app.route("/", events_default);
44
+ var routes_default = app;
45
+
46
+ //#endregion
47
+ export { routes_default as default };
@@ -0,0 +1,20 @@
1
+ import { WorkAppsVariables } from "../types.js";
2
+ import { getBotTokenForTeam, setBotTokenForTeam } from "../services/workspace-tokens.js";
3
+ import "../services/index.js";
4
+ import { OpenAPIHono } from "@hono/zod-openapi";
5
+
6
+ //#region src/slack/routes/oauth.d.ts
7
+
8
+ interface OAuthState {
9
+ nonce: string;
10
+ tenantId?: string;
11
+ timestamp: number;
12
+ }
13
+ declare function getStateSigningSecret(): string;
14
+ declare function createOAuthState(tenantId?: string): string;
15
+ declare function parseOAuthState(stateStr: string): OAuthState | null;
16
+ declare const app: OpenAPIHono<{
17
+ Variables: WorkAppsVariables;
18
+ }, {}, "/">;
19
+ //#endregion
20
+ export { createOAuthState, app as default, getBotTokenForTeam, getStateSigningSecret, parseOAuthState, setBotTokenForTeam };