@inkeep/agents-work-apps 0.0.0-dev-20260204182014 → 0.0.0-dev-20260204185956
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.
- package/dist/db/index.d.ts +1 -2
- package/dist/db/index.js +1 -2
- package/dist/db/runDbClient.d.ts +2 -2
- package/dist/env.d.ts +0 -22
- package/dist/env.js +1 -12
- package/dist/github/index.d.ts +3 -3
- package/dist/github/mcp/index.d.ts +2 -2
- package/dist/github/mcp/schemas.d.ts +1 -1
- package/dist/github/routes/setup.d.ts +2 -2
- package/dist/github/routes/tokenExchange.d.ts +2 -2
- package/dist/github/routes/webhooks.d.ts +2 -2
- package/package.json +2 -10
- package/dist/db/manageDbClient.d.ts +0 -7
- package/dist/db/manageDbClient.js +0 -16
- package/dist/slack/index.d.ts +0 -19
- package/dist/slack/index.js +0 -29
- package/dist/slack/middleware/permissions.d.ts +0 -16
- package/dist/slack/middleware/permissions.js +0 -49
- package/dist/slack/routes/events.d.ts +0 -10
- package/dist/slack/routes/events.js +0 -319
- package/dist/slack/routes/index.d.ts +0 -11
- package/dist/slack/routes/index.js +0 -64
- package/dist/slack/routes/internal.d.ts +0 -10
- package/dist/slack/routes/internal.js +0 -107
- package/dist/slack/routes/oauth.d.ts +0 -12
- package/dist/slack/routes/oauth.js +0 -218
- package/dist/slack/routes/resources.d.ts +0 -10
- package/dist/slack/routes/resources.js +0 -163
- package/dist/slack/routes/users.d.ts +0 -15
- package/dist/slack/routes/users.js +0 -430
- package/dist/slack/routes/workspaces.d.ts +0 -10
- package/dist/slack/routes/workspaces.js +0 -828
- package/dist/slack/routes.d.ts +0 -7
- package/dist/slack/routes.js +0 -12
- package/dist/slack/services/agent-resolution.d.ts +0 -49
- package/dist/slack/services/agent-resolution.js +0 -135
- package/dist/slack/services/api-client.d.ts +0 -161
- package/dist/slack/services/api-client.js +0 -248
- package/dist/slack/services/auth/index.d.ts +0 -61
- package/dist/slack/services/auth/index.js +0 -164
- package/dist/slack/services/blocks/index.d.ts +0 -60
- package/dist/slack/services/blocks/index.js +0 -143
- package/dist/slack/services/client.d.ts +0 -78
- package/dist/slack/services/client.js +0 -152
- package/dist/slack/services/commands/index.d.ts +0 -15
- package/dist/slack/services/commands/index.js +0 -556
- package/dist/slack/services/events/app-mention.d.ts +0 -41
- package/dist/slack/services/events/app-mention.js +0 -212
- package/dist/slack/services/events/block-actions.d.ts +0 -47
- package/dist/slack/services/events/block-actions.js +0 -287
- package/dist/slack/services/events/index.d.ts +0 -6
- package/dist/slack/services/events/index.js +0 -7
- package/dist/slack/services/events/modal-submission.d.ts +0 -12
- package/dist/slack/services/events/modal-submission.js +0 -279
- package/dist/slack/services/events/streaming.d.ts +0 -27
- package/dist/slack/services/events/streaming.js +0 -285
- package/dist/slack/services/events/utils.d.ts +0 -129
- package/dist/slack/services/events/utils.js +0 -315
- package/dist/slack/services/index.d.ts +0 -18
- package/dist/slack/services/index.js +0 -18
- package/dist/slack/services/modals.d.ts +0 -67
- package/dist/slack/services/modals.js +0 -203
- package/dist/slack/services/nango.d.ts +0 -82
- package/dist/slack/services/nango.js +0 -326
- package/dist/slack/services/security.d.ts +0 -35
- package/dist/slack/services/security.js +0 -65
- package/dist/slack/services/types.d.ts +0 -26
- package/dist/slack/services/types.js +0 -1
- package/dist/slack/services/workspace-tokens.d.ts +0 -37
- package/dist/slack/services/workspace-tokens.js +0 -39
- package/dist/slack/types.d.ts +0 -10
- package/dist/slack/types.js +0 -1
|
@@ -1,319 +0,0 @@
|
|
|
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 { handleCommand } from "../services/commands/index.js";
|
|
7
|
-
import { sendResponseUrlMessage } from "../services/events/utils.js";
|
|
8
|
-
import { handleAppMention } from "../services/events/app-mention.js";
|
|
9
|
-
import { handleOpenAgentSelectorModal, handleShareToChannel, handleShareToThread } from "../services/events/block-actions.js";
|
|
10
|
-
import { 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 { pendingSessionTokens } from "./users.js";
|
|
15
|
-
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
16
|
-
import { deleteAllWorkAppSlackChannelAgentConfigsByTeam, deleteAllWorkAppSlackUserMappingsByTeam, deleteWorkAppSlackWorkspaceByNangoConnectionId } from "@inkeep/agents-core";
|
|
17
|
-
|
|
18
|
-
//#region src/slack/routes/events.ts
|
|
19
|
-
/**
|
|
20
|
-
* Slack Events Routes
|
|
21
|
-
*
|
|
22
|
-
* Endpoints for handling Slack events, commands, and webhooks:
|
|
23
|
-
* - POST /commands - Handle /inkeep slash commands
|
|
24
|
-
* - POST /events - Handle Slack events & interactivity
|
|
25
|
-
* - POST /nango-webhook - Handle Nango auth webhooks
|
|
26
|
-
*/
|
|
27
|
-
const logger = getLogger("slack-events");
|
|
28
|
-
const app = new OpenAPIHono();
|
|
29
|
-
app.post("/commands", async (c) => {
|
|
30
|
-
const body = await c.req.text();
|
|
31
|
-
const timestamp = c.req.header("x-slack-request-timestamp") || "";
|
|
32
|
-
const signature = c.req.header("x-slack-signature") || "";
|
|
33
|
-
if (!env.SLACK_SIGNING_SECRET) {
|
|
34
|
-
logger.error({}, "SLACK_SIGNING_SECRET not configured - rejecting request");
|
|
35
|
-
return c.json({
|
|
36
|
-
response_type: "ephemeral",
|
|
37
|
-
text: "Server configuration error"
|
|
38
|
-
}, 500);
|
|
39
|
-
}
|
|
40
|
-
if (!verifySlackRequest(env.SLACK_SIGNING_SECRET, body, timestamp, signature)) {
|
|
41
|
-
logger.error({}, "Invalid Slack request signature");
|
|
42
|
-
return c.json({
|
|
43
|
-
response_type: "ephemeral",
|
|
44
|
-
text: "Invalid request signature"
|
|
45
|
-
}, 401);
|
|
46
|
-
}
|
|
47
|
-
const params = parseSlackCommandBody(body);
|
|
48
|
-
const response = await handleCommand({
|
|
49
|
-
command: params.command || "",
|
|
50
|
-
text: params.text || "",
|
|
51
|
-
userId: params.user_id || "",
|
|
52
|
-
userName: params.user_name || "",
|
|
53
|
-
teamId: params.team_id || "",
|
|
54
|
-
teamDomain: params.team_domain || "",
|
|
55
|
-
enterpriseId: params.enterprise_id,
|
|
56
|
-
channelId: params.channel_id || "",
|
|
57
|
-
channelName: params.channel_name || "",
|
|
58
|
-
responseUrl: params.response_url || "",
|
|
59
|
-
triggerId: params.trigger_id || ""
|
|
60
|
-
});
|
|
61
|
-
if (Object.keys(response).length === 0) return c.body(null, 200);
|
|
62
|
-
return c.json(response);
|
|
63
|
-
});
|
|
64
|
-
app.post("/events", async (c) => {
|
|
65
|
-
const contentType = c.req.header("content-type") || "";
|
|
66
|
-
const body = await c.req.text();
|
|
67
|
-
const timestamp = c.req.header("x-slack-request-timestamp") || "";
|
|
68
|
-
const signature = c.req.header("x-slack-signature") || "";
|
|
69
|
-
let eventBody;
|
|
70
|
-
try {
|
|
71
|
-
eventBody = parseSlackEventBody(body, contentType);
|
|
72
|
-
} catch (error) {
|
|
73
|
-
logger.error({
|
|
74
|
-
error,
|
|
75
|
-
contentType,
|
|
76
|
-
bodyPreview: body.slice(0, 200)
|
|
77
|
-
}, "Failed to parse Slack event body");
|
|
78
|
-
return c.json({ error: "Invalid payload" }, 400);
|
|
79
|
-
}
|
|
80
|
-
logger.debug({ eventType: eventBody.type }, "Slack event received");
|
|
81
|
-
const eventType = eventBody.type;
|
|
82
|
-
if (eventType === "url_verification") {
|
|
83
|
-
logger.info({}, "Responding to Slack URL verification challenge");
|
|
84
|
-
return c.text(String(eventBody.challenge));
|
|
85
|
-
}
|
|
86
|
-
if (!env.SLACK_SIGNING_SECRET) {
|
|
87
|
-
logger.error({}, "SLACK_SIGNING_SECRET not configured - rejecting request");
|
|
88
|
-
return c.json({ error: "Server configuration error" }, 500);
|
|
89
|
-
}
|
|
90
|
-
if (!verifySlackRequest(env.SLACK_SIGNING_SECRET, body, timestamp, signature)) {
|
|
91
|
-
logger.error({}, "Invalid Slack request signature");
|
|
92
|
-
return c.json({ error: "Invalid request signature" }, 401);
|
|
93
|
-
}
|
|
94
|
-
if (eventType === "event_callback") {
|
|
95
|
-
const teamId = eventBody.team_id;
|
|
96
|
-
const event = eventBody.event;
|
|
97
|
-
if (event?.bot_id || event?.subtype === "bot_message") {
|
|
98
|
-
logger.debug({ botId: event.bot_id }, "Ignoring bot message");
|
|
99
|
-
return c.json({ ok: true });
|
|
100
|
-
}
|
|
101
|
-
logger.debug({
|
|
102
|
-
eventType: event?.type,
|
|
103
|
-
teamId
|
|
104
|
-
}, "Slack event callback");
|
|
105
|
-
if (event?.type === "app_mention" && event.channel && event.user && teamId) {
|
|
106
|
-
const question = (event.text || "").replace(/<@[A-Z0-9]+>/g, "").trim();
|
|
107
|
-
logger.info({
|
|
108
|
-
userId: event.user,
|
|
109
|
-
channel: event.channel,
|
|
110
|
-
teamId
|
|
111
|
-
}, "Bot was mentioned");
|
|
112
|
-
handleAppMention({
|
|
113
|
-
slackUserId: event.user,
|
|
114
|
-
channel: event.channel,
|
|
115
|
-
text: question,
|
|
116
|
-
threadTs: event.thread_ts || event.ts || "",
|
|
117
|
-
messageTs: event.ts || "",
|
|
118
|
-
teamId
|
|
119
|
-
}).catch((err) => {
|
|
120
|
-
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
121
|
-
const errorStack = err instanceof Error ? err.stack : void 0;
|
|
122
|
-
logger.error({
|
|
123
|
-
errorMessage,
|
|
124
|
-
errorStack
|
|
125
|
-
}, "Failed to handle app mention (outer catch)");
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
if (eventType === "block_actions" || eventType === "interactive_message") {
|
|
130
|
-
logger.debug({ eventType }, "Slack interactive event received");
|
|
131
|
-
const actions = eventBody.actions;
|
|
132
|
-
const teamId = eventBody.team?.id;
|
|
133
|
-
const channelId = eventBody.channel?.id;
|
|
134
|
-
const userId = eventBody.user?.id;
|
|
135
|
-
const responseUrl = eventBody.response_url;
|
|
136
|
-
const triggerId = eventBody.trigger_id;
|
|
137
|
-
if (actions && teamId) for (const action of actions) {
|
|
138
|
-
if (action.action_id === "share_to_channel" && action.value) handleShareToChannel({
|
|
139
|
-
teamId,
|
|
140
|
-
channelId: channelId || "",
|
|
141
|
-
userId: userId || "",
|
|
142
|
-
actionValue: action.value,
|
|
143
|
-
responseUrl: responseUrl || ""
|
|
144
|
-
}).catch(async (err) => {
|
|
145
|
-
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
146
|
-
logger.error({
|
|
147
|
-
errorMessage,
|
|
148
|
-
actionId: action.action_id
|
|
149
|
-
}, "Failed to handle share_to_channel");
|
|
150
|
-
if (responseUrl) await sendResponseUrlMessage(responseUrl, {
|
|
151
|
-
text: "Sorry, something went wrong while sharing to channel. Please try again.",
|
|
152
|
-
response_type: "ephemeral"
|
|
153
|
-
}).catch(() => {});
|
|
154
|
-
});
|
|
155
|
-
if (action.action_id === "share_to_thread" && action.value) handleShareToThread({
|
|
156
|
-
teamId,
|
|
157
|
-
channelId: channelId || "",
|
|
158
|
-
userId: userId || "",
|
|
159
|
-
actionValue: action.value,
|
|
160
|
-
responseUrl: responseUrl || ""
|
|
161
|
-
}).catch(async (err) => {
|
|
162
|
-
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
163
|
-
logger.error({
|
|
164
|
-
errorMessage,
|
|
165
|
-
actionId: action.action_id
|
|
166
|
-
}, "Failed to handle share_to_thread");
|
|
167
|
-
if (responseUrl) await sendResponseUrlMessage(responseUrl, {
|
|
168
|
-
text: "Sorry, something went wrong while sharing to thread. Please try again.",
|
|
169
|
-
response_type: "ephemeral"
|
|
170
|
-
}).catch(() => {});
|
|
171
|
-
});
|
|
172
|
-
if (action.action_id === "open_agent_selector_modal" && action.value && triggerId) handleOpenAgentSelectorModal({
|
|
173
|
-
triggerId,
|
|
174
|
-
actionValue: action.value,
|
|
175
|
-
teamId,
|
|
176
|
-
responseUrl: responseUrl || ""
|
|
177
|
-
}).catch(async (err) => {
|
|
178
|
-
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
179
|
-
logger.error({
|
|
180
|
-
errorMessage,
|
|
181
|
-
actionId: action.action_id
|
|
182
|
-
}, "Failed to open agent selector modal");
|
|
183
|
-
if (responseUrl) await sendResponseUrlMessage(responseUrl, {
|
|
184
|
-
text: "Sorry, something went wrong while opening the agent selector. Please try again.",
|
|
185
|
-
response_type: "ephemeral"
|
|
186
|
-
}).catch(() => {});
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
if (eventType === "view_submission") {
|
|
191
|
-
const callbackId = eventBody.view?.callback_id;
|
|
192
|
-
if (callbackId === "agent_selector_modal") {
|
|
193
|
-
const view = eventBody.view;
|
|
194
|
-
handleModalSubmission(view).catch((err) => {
|
|
195
|
-
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
196
|
-
logger.error({
|
|
197
|
-
errorMessage,
|
|
198
|
-
callbackId
|
|
199
|
-
}, "Failed to handle modal submission");
|
|
200
|
-
});
|
|
201
|
-
return new Response(null, { status: 200 });
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
return c.json({ ok: true });
|
|
205
|
-
});
|
|
206
|
-
app.post("/nango-webhook", async (c) => {
|
|
207
|
-
const body = await c.req.text();
|
|
208
|
-
let payload;
|
|
209
|
-
try {
|
|
210
|
-
payload = JSON.parse(body);
|
|
211
|
-
} catch (error) {
|
|
212
|
-
logger.error({
|
|
213
|
-
error,
|
|
214
|
-
bodyPreview: body.slice(0, 200)
|
|
215
|
-
}, "Failed to parse Nango webhook JSON");
|
|
216
|
-
return c.json({ error: "Invalid JSON" }, 400);
|
|
217
|
-
}
|
|
218
|
-
logger.debug({ payload }, "Nango webhook received");
|
|
219
|
-
if (payload.type === "connection_deleted" && payload.connectionId && payload.providerConfigKey) {
|
|
220
|
-
const { connectionId, providerConfigKey } = payload;
|
|
221
|
-
if (providerConfigKey === getSlackIntegrationId()) try {
|
|
222
|
-
const teamMatch = connectionId.match(/T:([A-Z0-9]+)/);
|
|
223
|
-
if (teamMatch) {
|
|
224
|
-
const teamId = teamMatch[1];
|
|
225
|
-
const tenantId = (await findWorkspaceConnectionByTeamId(teamId))?.tenantId || "default";
|
|
226
|
-
if (await deleteWorkAppSlackWorkspaceByNangoConnectionId(runDbClient_default)(connectionId)) logger.info({ connectionId }, "Deleted workspace from database via Nango webhook");
|
|
227
|
-
const deletedMappings = await deleteAllWorkAppSlackUserMappingsByTeam(runDbClient_default)(tenantId, teamId);
|
|
228
|
-
if (deletedMappings > 0) logger.info({
|
|
229
|
-
teamId,
|
|
230
|
-
deletedMappings
|
|
231
|
-
}, "Deleted user mappings via Nango webhook");
|
|
232
|
-
const deletedChannelConfigs = await deleteAllWorkAppSlackChannelAgentConfigsByTeam(runDbClient_default)(tenantId, teamId);
|
|
233
|
-
if (deletedChannelConfigs > 0) logger.info({
|
|
234
|
-
teamId,
|
|
235
|
-
deletedChannelConfigs
|
|
236
|
-
}, "Deleted channel configs via Nango webhook");
|
|
237
|
-
logger.info({
|
|
238
|
-
connectionId,
|
|
239
|
-
teamId
|
|
240
|
-
}, "Processed Nango connection deletion webhook");
|
|
241
|
-
}
|
|
242
|
-
} catch (error) {
|
|
243
|
-
logger.error({
|
|
244
|
-
error,
|
|
245
|
-
connectionId
|
|
246
|
-
}, "Failed to process Nango deletion webhook");
|
|
247
|
-
}
|
|
248
|
-
return c.json({ received: true });
|
|
249
|
-
}
|
|
250
|
-
if (payload.type === "auth" && payload.success && payload.endUser && payload.connectionId) {
|
|
251
|
-
const { endUser, connectionId } = payload;
|
|
252
|
-
const integrationId = getSlackIntegrationId();
|
|
253
|
-
try {
|
|
254
|
-
const rawResponse = (await getSlackNango().getConnection(integrationId, connectionId)).credentials?.raw;
|
|
255
|
-
logger.debug({ teamId: rawResponse?.team?.id }, "Retrieved Nango connection info");
|
|
256
|
-
if (rawResponse?.ok && rawResponse.access_token) {
|
|
257
|
-
const slackUserId = rawResponse.authed_user?.id || "";
|
|
258
|
-
const slackTeamId = rawResponse.team?.id || "";
|
|
259
|
-
const accessToken = rawResponse.access_token;
|
|
260
|
-
let slackUsername = "";
|
|
261
|
-
let slackDisplayName = "";
|
|
262
|
-
let slackEmail = "";
|
|
263
|
-
let isSlackAdmin = false;
|
|
264
|
-
let isSlackOwner = false;
|
|
265
|
-
if (slackUserId && accessToken) {
|
|
266
|
-
const userInfo = await getSlackUserInfo(getSlackClient(accessToken), slackUserId);
|
|
267
|
-
if (userInfo) {
|
|
268
|
-
slackUsername = userInfo.name || "";
|
|
269
|
-
slackDisplayName = userInfo.displayName || userInfo.realName || "";
|
|
270
|
-
slackEmail = userInfo.email || "";
|
|
271
|
-
isSlackAdmin = userInfo.isAdmin || false;
|
|
272
|
-
isSlackOwner = userInfo.isOwner || false;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
const tenantId = payload.organization?.id || "default";
|
|
276
|
-
const pendingSession = pendingSessionTokens.get(endUser.endUserId);
|
|
277
|
-
if (pendingSession) {
|
|
278
|
-
pendingSessionTokens.delete(endUser.endUserId);
|
|
279
|
-
logger.info({ userId: endUser.endUserId }, "Retrieved pending session token");
|
|
280
|
-
}
|
|
281
|
-
await updateConnectionMetadata(connectionId, {
|
|
282
|
-
linked_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
283
|
-
app_user_id: endUser.endUserId,
|
|
284
|
-
app_user_email: endUser.endUserEmail || "",
|
|
285
|
-
tenant_id: tenantId,
|
|
286
|
-
slack_user_id: slackUserId,
|
|
287
|
-
slack_team_id: slackTeamId,
|
|
288
|
-
slack_team_name: rawResponse.team?.name || "",
|
|
289
|
-
slack_username: slackUsername,
|
|
290
|
-
slack_display_name: slackDisplayName,
|
|
291
|
-
slack_email: slackEmail,
|
|
292
|
-
is_slack_admin: String(isSlackAdmin),
|
|
293
|
-
is_slack_owner: String(isSlackOwner),
|
|
294
|
-
enterprise_id: rawResponse.enterprise?.id || "",
|
|
295
|
-
enterprise_name: rawResponse.enterprise?.name || "",
|
|
296
|
-
...pendingSession ? {
|
|
297
|
-
inkeep_session_token: pendingSession.token,
|
|
298
|
-
inkeep_session_expires_at: pendingSession.expiresAt
|
|
299
|
-
} : {}
|
|
300
|
-
});
|
|
301
|
-
logger.info({
|
|
302
|
-
appUserId: endUser.endUserId,
|
|
303
|
-
slackUserId,
|
|
304
|
-
slackEmail
|
|
305
|
-
}, "User linked to Slack with enriched metadata");
|
|
306
|
-
}
|
|
307
|
-
} catch (error) {
|
|
308
|
-
logger.error({
|
|
309
|
-
error,
|
|
310
|
-
connectionId
|
|
311
|
-
}, "Failed to process Nango webhook");
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
return c.json({ received: true });
|
|
315
|
-
});
|
|
316
|
-
var events_default = app;
|
|
317
|
-
|
|
318
|
-
//#endregion
|
|
319
|
-
export { events_default as default };
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { WorkAppsVariables } from "../types.js";
|
|
2
|
-
import { pendingSessionTokens } from "./users.js";
|
|
3
|
-
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
4
|
-
|
|
5
|
-
//#region src/slack/routes/index.d.ts
|
|
6
|
-
|
|
7
|
-
declare const app: OpenAPIHono<{
|
|
8
|
-
Variables: WorkAppsVariables;
|
|
9
|
-
}, {}, "/">;
|
|
10
|
-
//#endregion
|
|
11
|
-
export { app as default, pendingSessionTokens };
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import oauth_default from "./oauth.js";
|
|
2
|
-
import users_default, { pendingSessionTokens } from "./users.js";
|
|
3
|
-
import events_default from "./events.js";
|
|
4
|
-
import internal_default from "./internal.js";
|
|
5
|
-
import resources_default from "./resources.js";
|
|
6
|
-
import workspaces_default from "./workspaces.js";
|
|
7
|
-
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
8
|
-
|
|
9
|
-
//#region src/slack/routes/index.ts
|
|
10
|
-
/**
|
|
11
|
-
* Slack Work App Routes - Main Router
|
|
12
|
-
*
|
|
13
|
-
* Modular RESTful API structure:
|
|
14
|
-
*
|
|
15
|
-
* OAuth & Installation (oauth.ts):
|
|
16
|
-
* GET /install - Redirect to Slack OAuth
|
|
17
|
-
* GET /oauth_redirect - OAuth callback
|
|
18
|
-
*
|
|
19
|
-
* Workspaces (workspaces.ts):
|
|
20
|
-
* GET /workspaces - List all workspaces
|
|
21
|
-
* GET /workspaces/:teamId - Get workspace details
|
|
22
|
-
* GET /workspaces/:teamId/settings - Get workspace settings
|
|
23
|
-
* PUT /workspaces/:teamId/settings - Update workspace settings [ADMIN]
|
|
24
|
-
* DELETE /workspaces/:teamId - Uninstall workspace [ADMIN]
|
|
25
|
-
* GET /workspaces/:teamId/channels - List channels
|
|
26
|
-
* GET/PUT/DELETE /workspaces/:teamId/channels/:channelId/settings - Channel config
|
|
27
|
-
* GET /workspaces/:teamId/users - List linked users
|
|
28
|
-
*
|
|
29
|
-
* Users (users.ts):
|
|
30
|
-
* GET /users/me/settings - Get user's personal settings
|
|
31
|
-
* PUT /users/me/settings - Update user's personal settings
|
|
32
|
-
* GET /users/link-status - Check link status
|
|
33
|
-
* POST /users/link/verify-token - Verify JWT link token (primary linking method)
|
|
34
|
-
* POST /users/connect - Create Nango session
|
|
35
|
-
* POST /users/disconnect - Disconnect/unlink user
|
|
36
|
-
* GET /users/status - Get user connection status
|
|
37
|
-
* POST /users/refresh-session - Refresh session token
|
|
38
|
-
*
|
|
39
|
-
* Resources (resources.ts):
|
|
40
|
-
* GET /projects - List projects
|
|
41
|
-
* GET /projects/:projectId/agents - List agents in project
|
|
42
|
-
* GET /agents - List all agents
|
|
43
|
-
*
|
|
44
|
-
* Events & Commands (events.ts):
|
|
45
|
-
* POST /commands - Handle slash commands
|
|
46
|
-
* POST /events - Handle Slack events
|
|
47
|
-
* POST /nango-webhook - Handle Nango webhooks
|
|
48
|
-
*
|
|
49
|
-
* Internal/Debug (internal.ts):
|
|
50
|
-
* POST /register-workspace - Register workspace (memory cache)
|
|
51
|
-
* GET /workspace-info - Get workspace info
|
|
52
|
-
* POST /debug/generate-token - Generate test tokens (dev only)
|
|
53
|
-
*/
|
|
54
|
-
const app = new OpenAPIHono();
|
|
55
|
-
app.route("/workspaces", workspaces_default);
|
|
56
|
-
app.route("/users", users_default);
|
|
57
|
-
app.route("/", oauth_default);
|
|
58
|
-
app.route("/", events_default);
|
|
59
|
-
app.route("/", internal_default);
|
|
60
|
-
app.route("/", resources_default);
|
|
61
|
-
var routes_default = app;
|
|
62
|
-
|
|
63
|
-
//#endregion
|
|
64
|
-
export { routes_default as default, pendingSessionTokens };
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { WorkAppsVariables } from "../types.js";
|
|
2
|
-
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
3
|
-
|
|
4
|
-
//#region src/slack/routes/internal.d.ts
|
|
5
|
-
|
|
6
|
-
declare const app: OpenAPIHono<{
|
|
7
|
-
Variables: WorkAppsVariables;
|
|
8
|
-
}, {}, "/">;
|
|
9
|
-
//#endregion
|
|
10
|
-
export { app as default };
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { env } from "../../env.js";
|
|
2
|
-
import { getLogger } from "../../logger.js";
|
|
3
|
-
import { getConnectionAccessToken } from "../services/nango.js";
|
|
4
|
-
import { getSlackChannels, getSlackClient, getSlackTeamInfo } from "../services/client.js";
|
|
5
|
-
import { setBotTokenForTeam } from "../services/workspace-tokens.js";
|
|
6
|
-
import "../services/index.js";
|
|
7
|
-
import "./oauth.js";
|
|
8
|
-
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
9
|
-
|
|
10
|
-
//#region src/slack/routes/internal.ts
|
|
11
|
-
/**
|
|
12
|
-
* Slack Internal/Debug Routes
|
|
13
|
-
*
|
|
14
|
-
* Endpoints for internal operations and debugging:
|
|
15
|
-
* - POST /register-workspace - Register workspace bot token (memory cache)
|
|
16
|
-
* - POST /debug/generate-token - Generate test tokens (dev only)
|
|
17
|
-
* - GET /workspace-info - Get workspace info from Nango
|
|
18
|
-
*/
|
|
19
|
-
const logger = getLogger("slack-internal");
|
|
20
|
-
const app = new OpenAPIHono();
|
|
21
|
-
app.post("/register-workspace", async (c) => {
|
|
22
|
-
const { teamId, teamName, botToken } = await c.req.json();
|
|
23
|
-
if (!teamId) return c.json({ error: "teamId is required" }, 400);
|
|
24
|
-
if (!botToken) return c.json({ error: "botToken is required" }, 400);
|
|
25
|
-
setBotTokenForTeam(teamId, {
|
|
26
|
-
botToken,
|
|
27
|
-
teamName: teamName || "",
|
|
28
|
-
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
29
|
-
});
|
|
30
|
-
logger.info({
|
|
31
|
-
teamId,
|
|
32
|
-
teamName
|
|
33
|
-
}, "Registered workspace bot token");
|
|
34
|
-
return c.json({
|
|
35
|
-
success: true,
|
|
36
|
-
teamId
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
app.get("/workspace-info", async (c) => {
|
|
40
|
-
const connectionId = c.req.query("connectionId");
|
|
41
|
-
if (!connectionId) return c.json({ error: "connectionId is required" }, 400);
|
|
42
|
-
try {
|
|
43
|
-
const accessToken = await getConnectionAccessToken(connectionId);
|
|
44
|
-
if (!accessToken) return c.json({ error: "No access token found" }, 404);
|
|
45
|
-
const client = getSlackClient(accessToken);
|
|
46
|
-
const [team, channels] = await Promise.all([getSlackTeamInfo(client), getSlackChannels(client, 20)]);
|
|
47
|
-
logger.debug({
|
|
48
|
-
hasTeam: !!team,
|
|
49
|
-
channelCount: channels.length
|
|
50
|
-
}, "Retrieved Slack workspace info");
|
|
51
|
-
return c.json({
|
|
52
|
-
team,
|
|
53
|
-
channels
|
|
54
|
-
});
|
|
55
|
-
} catch (error) {
|
|
56
|
-
logger.error({
|
|
57
|
-
error,
|
|
58
|
-
connectionId
|
|
59
|
-
}, "Failed to fetch Slack workspace info");
|
|
60
|
-
return c.json({ error: "Failed to fetch workspace info" }, 500);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
app.post("/debug/generate-token", async (c) => {
|
|
64
|
-
if (env.ENVIRONMENT === "production") return c.json({ error: "This endpoint is not available in production" }, 403);
|
|
65
|
-
const { userId, tenantId, slackUserId, slackTeamId, slackEnterpriseId } = await c.req.json();
|
|
66
|
-
if (!userId) return c.json({ error: "userId is required" }, 400);
|
|
67
|
-
if (!slackUserId) return c.json({ error: "slackUserId is required" }, 400);
|
|
68
|
-
if (!slackTeamId) return c.json({ error: "slackTeamId is required" }, 400);
|
|
69
|
-
try {
|
|
70
|
-
const { signSlackUserToken } = await import("@inkeep/agents-core");
|
|
71
|
-
const token = await signSlackUserToken({
|
|
72
|
-
inkeepUserId: userId,
|
|
73
|
-
tenantId: tenantId || "default",
|
|
74
|
-
slackTeamId,
|
|
75
|
-
slackUserId,
|
|
76
|
-
slackEnterpriseId
|
|
77
|
-
});
|
|
78
|
-
logger.info({
|
|
79
|
-
userId,
|
|
80
|
-
tenantId: tenantId || "default",
|
|
81
|
-
slackTeamId,
|
|
82
|
-
slackUserId
|
|
83
|
-
}, "Generated Slack user token for debugging");
|
|
84
|
-
return c.json({
|
|
85
|
-
token,
|
|
86
|
-
expiresIn: "5m",
|
|
87
|
-
tokenType: "slackUser",
|
|
88
|
-
payload: {
|
|
89
|
-
sub: userId,
|
|
90
|
-
tenantId: tenantId || "default",
|
|
91
|
-
slack: {
|
|
92
|
-
teamId: slackTeamId,
|
|
93
|
-
userId: slackUserId,
|
|
94
|
-
enterpriseId: slackEnterpriseId
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
} catch (error) {
|
|
99
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
100
|
-
logger.error({ error: errorMessage }, "Failed to generate Slack user token");
|
|
101
|
-
return c.json({ error: `Failed to generate token: ${errorMessage}` }, 500);
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
var internal_default = app;
|
|
105
|
-
|
|
106
|
-
//#endregion
|
|
107
|
-
export { internal_default as default };
|
|
@@ -1,12 +0,0 @@
|
|
|
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
|
-
declare const app: OpenAPIHono<{
|
|
9
|
-
Variables: WorkAppsVariables;
|
|
10
|
-
}, {}, "/">;
|
|
11
|
-
//#endregion
|
|
12
|
-
export { app as default, getBotTokenForTeam, setBotTokenForTeam };
|