@chaaskit/server 0.1.0

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 (189) hide show
  1. package/dist/api/admin.js +438 -0
  2. package/dist/api/admin.js.map +1 -0
  3. package/dist/api/agents.js +21 -0
  4. package/dist/api/agents.js.map +1 -0
  5. package/dist/api/api-keys.js +122 -0
  6. package/dist/api/api-keys.js.map +1 -0
  7. package/dist/api/auth.js +399 -0
  8. package/dist/api/auth.js.map +1 -0
  9. package/dist/api/chat.js +900 -0
  10. package/dist/api/chat.js.map +1 -0
  11. package/dist/api/config.js +91 -0
  12. package/dist/api/config.js.map +1 -0
  13. package/dist/api/documents.js +237 -0
  14. package/dist/api/documents.js.map +1 -0
  15. package/dist/api/export.js +107 -0
  16. package/dist/api/export.js.map +1 -0
  17. package/dist/api/health.js +25 -0
  18. package/dist/api/health.js.map +1 -0
  19. package/dist/api/mcp-server.js +84 -0
  20. package/dist/api/mcp-server.js.map +1 -0
  21. package/dist/api/mcp.js +400 -0
  22. package/dist/api/mcp.js.map +1 -0
  23. package/dist/api/mentions.js +94 -0
  24. package/dist/api/mentions.js.map +1 -0
  25. package/dist/api/oauth.js +366 -0
  26. package/dist/api/oauth.js.map +1 -0
  27. package/dist/api/payments.js +473 -0
  28. package/dist/api/payments.js.map +1 -0
  29. package/dist/api/projects.js +301 -0
  30. package/dist/api/projects.js.map +1 -0
  31. package/dist/api/scheduled-prompts.js +617 -0
  32. package/dist/api/scheduled-prompts.js.map +1 -0
  33. package/dist/api/search.js +85 -0
  34. package/dist/api/search.js.map +1 -0
  35. package/dist/api/share.js +188 -0
  36. package/dist/api/share.js.map +1 -0
  37. package/dist/api/slack.js +468 -0
  38. package/dist/api/slack.js.map +1 -0
  39. package/dist/api/teams.js +693 -0
  40. package/dist/api/teams.js.map +1 -0
  41. package/dist/api/templates.js +134 -0
  42. package/dist/api/templates.js.map +1 -0
  43. package/dist/api/threads.js +323 -0
  44. package/dist/api/threads.js.map +1 -0
  45. package/dist/api/upload.js +57 -0
  46. package/dist/api/upload.js.map +1 -0
  47. package/dist/api/user.js +111 -0
  48. package/dist/api/user.js.map +1 -0
  49. package/dist/api/v1/openai.js +245 -0
  50. package/dist/api/v1/openai.js.map +1 -0
  51. package/dist/app.js +168 -0
  52. package/dist/app.js.map +1 -0
  53. package/dist/bin/cli.js +57 -0
  54. package/dist/bin/cli.js.map +1 -0
  55. package/dist/commands/db-sync.js +108 -0
  56. package/dist/commands/db-sync.js.map +1 -0
  57. package/dist/config/loader.js +374 -0
  58. package/dist/config/loader.js.map +1 -0
  59. package/dist/documents/extractors.js +136 -0
  60. package/dist/documents/extractors.js.map +1 -0
  61. package/dist/extensions/glob.js +53 -0
  62. package/dist/extensions/glob.js.map +1 -0
  63. package/dist/extensions/loader.js +72 -0
  64. package/dist/extensions/loader.js.map +1 -0
  65. package/dist/index.js +25 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/loaders/index.js +75 -0
  68. package/dist/loaders/index.js.map +1 -0
  69. package/dist/mcp/client.js +551 -0
  70. package/dist/mcp/client.js.map +1 -0
  71. package/dist/mcp/server.js +335 -0
  72. package/dist/mcp/server.js.map +1 -0
  73. package/dist/middleware/apiKeyAuth.js +136 -0
  74. package/dist/middleware/apiKeyAuth.js.map +1 -0
  75. package/dist/middleware/auth.js +192 -0
  76. package/dist/middleware/auth.js.map +1 -0
  77. package/dist/middleware/errorHandler.js +41 -0
  78. package/dist/middleware/errorHandler.js.map +1 -0
  79. package/dist/middleware/mcpServerAuth.js +164 -0
  80. package/dist/middleware/mcpServerAuth.js.map +1 -0
  81. package/dist/middleware/requestLogger.js +9 -0
  82. package/dist/middleware/requestLogger.js.map +1 -0
  83. package/dist/middleware/team.js +132 -0
  84. package/dist/middleware/team.js.map +1 -0
  85. package/dist/oauth/server.js +410 -0
  86. package/dist/oauth/server.js.map +1 -0
  87. package/dist/queue/cli.js +93 -0
  88. package/dist/queue/cli.js.map +1 -0
  89. package/dist/queue/handlers/index.js +91 -0
  90. package/dist/queue/handlers/index.js.map +1 -0
  91. package/dist/queue/handlers/scheduled-prompt.js +270 -0
  92. package/dist/queue/handlers/scheduled-prompt.js.map +1 -0
  93. package/dist/queue/index.js +91 -0
  94. package/dist/queue/index.js.map +1 -0
  95. package/dist/queue/providers/memory.js +296 -0
  96. package/dist/queue/providers/memory.js.map +1 -0
  97. package/dist/queue/providers/sqs.js +275 -0
  98. package/dist/queue/providers/sqs.js.map +1 -0
  99. package/dist/queue/scheduler.js +355 -0
  100. package/dist/queue/scheduler.js.map +1 -0
  101. package/dist/queue/types.js +5 -0
  102. package/dist/queue/types.js.map +1 -0
  103. package/dist/queue/worker.js +230 -0
  104. package/dist/queue/worker.js.map +1 -0
  105. package/dist/registry/index.js +40 -0
  106. package/dist/registry/index.js.map +1 -0
  107. package/dist/server.js +207 -0
  108. package/dist/server.js.map +1 -0
  109. package/dist/services/agent.js +530 -0
  110. package/dist/services/agent.js.map +1 -0
  111. package/dist/services/agents.js +194 -0
  112. package/dist/services/agents.js.map +1 -0
  113. package/dist/services/documents.js +507 -0
  114. package/dist/services/documents.js.map +1 -0
  115. package/dist/services/email/index.js +91 -0
  116. package/dist/services/email/index.js.map +1 -0
  117. package/dist/services/email/providers/ses.js +97 -0
  118. package/dist/services/email/providers/ses.js.map +1 -0
  119. package/dist/services/email/templates.js +194 -0
  120. package/dist/services/email/templates.js.map +1 -0
  121. package/dist/services/email/types.js +5 -0
  122. package/dist/services/email/types.js.map +1 -0
  123. package/dist/services/encryption.js +69 -0
  124. package/dist/services/encryption.js.map +1 -0
  125. package/dist/services/oauth-discovery.js +226 -0
  126. package/dist/services/oauth-discovery.js.map +1 -0
  127. package/dist/services/pendingConfirmation.js +105 -0
  128. package/dist/services/pendingConfirmation.js.map +1 -0
  129. package/dist/services/scheduledPrompts.js +70 -0
  130. package/dist/services/scheduledPrompts.js.map +1 -0
  131. package/dist/services/slack/client.js +174 -0
  132. package/dist/services/slack/client.js.map +1 -0
  133. package/dist/services/slack/events.js +189 -0
  134. package/dist/services/slack/events.js.map +1 -0
  135. package/dist/services/slack/index.js +6 -0
  136. package/dist/services/slack/index.js.map +1 -0
  137. package/dist/services/slack/notifications.js +124 -0
  138. package/dist/services/slack/notifications.js.map +1 -0
  139. package/dist/services/slack/signature.js +74 -0
  140. package/dist/services/slack/signature.js.map +1 -0
  141. package/dist/services/slack/thread-context.js +191 -0
  142. package/dist/services/slack/thread-context.js.map +1 -0
  143. package/dist/services/toolConfirmation.js +55 -0
  144. package/dist/services/toolConfirmation.js.map +1 -0
  145. package/dist/services/usage.js +241 -0
  146. package/dist/services/usage.js.map +1 -0
  147. package/dist/ssr/build.js +90 -0
  148. package/dist/ssr/build.js.map +1 -0
  149. package/dist/ssr/components/SSRMessageList.js +120 -0
  150. package/dist/ssr/components/SSRMessageList.js.map +1 -0
  151. package/dist/ssr/entry.client.js +8 -0
  152. package/dist/ssr/entry.client.js.map +1 -0
  153. package/dist/ssr/entry.server.js +71 -0
  154. package/dist/ssr/entry.server.js.map +1 -0
  155. package/dist/ssr/handler.js +51 -0
  156. package/dist/ssr/handler.js.map +1 -0
  157. package/dist/ssr/root.js +184 -0
  158. package/dist/ssr/root.js.map +1 -0
  159. package/dist/ssr/routes/login.js +140 -0
  160. package/dist/ssr/routes/login.js.map +1 -0
  161. package/dist/ssr/routes/pricing.js +195 -0
  162. package/dist/ssr/routes/pricing.js.map +1 -0
  163. package/dist/ssr/routes/privacy.js +39 -0
  164. package/dist/ssr/routes/privacy.js.map +1 -0
  165. package/dist/ssr/routes/register.js +148 -0
  166. package/dist/ssr/routes/register.js.map +1 -0
  167. package/dist/ssr/routes/shared.$shareId.js +153 -0
  168. package/dist/ssr/routes/shared.$shareId.js.map +1 -0
  169. package/dist/ssr/routes/terms.js +39 -0
  170. package/dist/ssr/routes/terms.js.map +1 -0
  171. package/dist/storage/index.js +43 -0
  172. package/dist/storage/index.js.map +1 -0
  173. package/dist/storage/providers/database.js +38 -0
  174. package/dist/storage/providers/database.js.map +1 -0
  175. package/dist/storage/providers/filesystem.js +51 -0
  176. package/dist/storage/providers/filesystem.js.map +1 -0
  177. package/dist/storage/types.js +2 -0
  178. package/dist/storage/types.js.map +1 -0
  179. package/dist/tools/documents.js +336 -0
  180. package/dist/tools/documents.js.map +1 -0
  181. package/dist/tools/get-plan-usage.js +82 -0
  182. package/dist/tools/get-plan-usage.js.map +1 -0
  183. package/dist/tools/index.js +106 -0
  184. package/dist/tools/index.js.map +1 -0
  185. package/dist/tools/types.js +2 -0
  186. package/dist/tools/types.js.map +1 -0
  187. package/dist/tools/web-scrape.js +145 -0
  188. package/dist/tools/web-scrape.js.map +1 -0
  189. package/package.json +93 -0
@@ -0,0 +1,468 @@
1
+ import { Router } from 'express';
2
+ import crypto from 'crypto';
3
+ import { db } from '@chaaskit/db';
4
+ import { HTTP_STATUS } from '@chaaskit/shared';
5
+ import { requireAuth } from '../middleware/auth.js';
6
+ import { requireTeamRole } from '../middleware/team.js';
7
+ import { AppError } from '../middleware/errorHandler.js';
8
+ import { getConfig } from '../config/loader.js';
9
+ import { verifySlackSignature, verifyInternalSecret, getInternalSecret, buildOAuthUrl, exchangeCodeForTokens, encryptTokens, } from '../services/slack/index.js';
10
+ import { processSlackEvent } from '../services/slack/events.js';
11
+ export const slackRouter = Router();
12
+ // Store for OAuth state tokens (in production, use Redis or similar)
13
+ const oauthStates = new Map();
14
+ // Clean up expired states every 5 minutes
15
+ setInterval(() => {
16
+ const now = Date.now();
17
+ for (const [key, value] of oauthStates.entries()) {
18
+ if (now - value.createdAt > 10 * 60 * 1000) {
19
+ oauthStates.delete(key);
20
+ }
21
+ }
22
+ }, 5 * 60 * 1000);
23
+ // Middleware to check if Slack feature is enabled
24
+ const requireSlackEnabled = (req, res, next) => {
25
+ const config = getConfig();
26
+ if (!config.slack?.enabled) {
27
+ return next(new AppError(HTTP_STATUS.FORBIDDEN, 'Slack integration is not enabled'));
28
+ }
29
+ next();
30
+ };
31
+ // Middleware to check if teams feature is enabled (Slack requires teams)
32
+ const requireTeamsEnabled = (req, res, next) => {
33
+ const config = getConfig();
34
+ if (!config.teams?.enabled) {
35
+ return next(new AppError(HTTP_STATUS.FORBIDDEN, 'Teams feature is required for Slack integration'));
36
+ }
37
+ next();
38
+ };
39
+ // Check if team's plan is allowed for Slack
40
+ async function checkPlanAllowed(teamId) {
41
+ const config = getConfig();
42
+ if (!config.slack?.allowedPlans || config.slack.allowedPlans.length === 0) {
43
+ return true;
44
+ }
45
+ const team = await db.team.findUnique({
46
+ where: { id: teamId },
47
+ select: { plan: true },
48
+ });
49
+ if (!team) {
50
+ return false;
51
+ }
52
+ return config.slack.allowedPlans.includes(team.plan);
53
+ }
54
+ // ============================================================================
55
+ // OAuth Flow
56
+ // ============================================================================
57
+ /**
58
+ * GET /api/slack/install/:teamId - Initiate OAuth flow
59
+ */
60
+ slackRouter.get('/install/:teamId', requireSlackEnabled, requireTeamsEnabled, requireAuth, requireTeamRole('admin'), async (req, res, next) => {
61
+ try {
62
+ const { teamId } = req.params;
63
+ // Check if team plan is allowed
64
+ const planAllowed = await checkPlanAllowed(teamId);
65
+ if (!planAllowed) {
66
+ throw new AppError(HTTP_STATUS.FORBIDDEN, 'Your plan does not include Slack integration');
67
+ }
68
+ // Check if already connected
69
+ const existing = await db.slackIntegration.findUnique({
70
+ where: { teamId },
71
+ });
72
+ if (existing && existing.status === 'active') {
73
+ throw new AppError(HTTP_STATUS.CONFLICT, 'Slack is already connected to this team');
74
+ }
75
+ // Generate state for CSRF protection
76
+ const nonce = crypto.randomBytes(16).toString('hex');
77
+ const state = `${teamId}:${nonce}`;
78
+ oauthStates.set(state, {
79
+ teamId,
80
+ nonce,
81
+ createdAt: Date.now(),
82
+ });
83
+ // Build redirect URL (use API_URL since callback is on the server)
84
+ const apiUrl = process.env.API_URL || 'http://localhost:3000';
85
+ const redirectUri = `${apiUrl}/api/slack/callback`;
86
+ const authUrl = buildOAuthUrl(state, redirectUri);
87
+ res.redirect(authUrl);
88
+ }
89
+ catch (error) {
90
+ next(error);
91
+ }
92
+ });
93
+ /**
94
+ * GET /api/slack/callback - OAuth callback
95
+ */
96
+ slackRouter.get('/callback', requireSlackEnabled, async (req, res, next) => {
97
+ try {
98
+ const { code, state, error: oauthError } = req.query;
99
+ const appUrl = process.env.APP_URL || 'http://localhost:5173';
100
+ const apiUrl = process.env.API_URL || 'http://localhost:3000';
101
+ const config = getConfig();
102
+ const basePath = config.app?.basePath || '';
103
+ // Handle OAuth errors
104
+ if (oauthError) {
105
+ console.error('[Slack] OAuth error:', oauthError);
106
+ return res.redirect(`${appUrl}${basePath}/teams?slack=error&message=${encodeURIComponent(String(oauthError))}`);
107
+ }
108
+ if (!code || !state || typeof code !== 'string' || typeof state !== 'string') {
109
+ return res.redirect(`${appUrl}${basePath}/teams?slack=error&message=invalid_request`);
110
+ }
111
+ // Validate state
112
+ const stateData = oauthStates.get(state);
113
+ if (!stateData) {
114
+ return res.redirect(`${appUrl}${basePath}/teams?slack=error&message=invalid_state`);
115
+ }
116
+ oauthStates.delete(state);
117
+ const { teamId } = stateData;
118
+ // Exchange code for tokens (redirect URI must match what was sent in the auth request)
119
+ const redirectUri = `${apiUrl}/api/slack/callback`;
120
+ const tokenResponse = await exchangeCodeForTokens(code, redirectUri);
121
+ if (!tokenResponse.ok || !tokenResponse.access_token) {
122
+ console.error('[Slack] Token exchange failed:', tokenResponse.error);
123
+ return res.redirect(`${appUrl}${basePath}/team/${teamId}/settings?slack=error&message=${encodeURIComponent(tokenResponse.error || 'token_error')}`);
124
+ }
125
+ // Encrypt tokens for storage
126
+ const encryptedTokens = encryptTokens({
127
+ botToken: tokenResponse.access_token,
128
+ userAccessToken: tokenResponse.authed_user?.access_token,
129
+ });
130
+ // Get the user who initiated (we'll use system for now since we don't have auth context)
131
+ // In a full implementation, we'd pass the user ID through the state
132
+ const team = await db.team.findUnique({
133
+ where: { id: teamId },
134
+ include: {
135
+ members: {
136
+ where: { role: 'owner' },
137
+ take: 1,
138
+ },
139
+ },
140
+ });
141
+ if (!team || !team.members[0]) {
142
+ return res.redirect(`${appUrl}${basePath}/teams?slack=error&message=team_not_found`);
143
+ }
144
+ // Upsert the integration
145
+ await db.slackIntegration.upsert({
146
+ where: { teamId },
147
+ create: {
148
+ teamId,
149
+ slackWorkspaceId: tokenResponse.team?.id || '',
150
+ slackWorkspaceName: tokenResponse.team?.name || 'Unknown Workspace',
151
+ slackBotUserId: tokenResponse.bot_user_id || '',
152
+ encryptedTokens,
153
+ installedBy: team.members[0].userId,
154
+ status: 'active',
155
+ },
156
+ update: {
157
+ slackWorkspaceId: tokenResponse.team?.id || '',
158
+ slackWorkspaceName: tokenResponse.team?.name || 'Unknown Workspace',
159
+ slackBotUserId: tokenResponse.bot_user_id || '',
160
+ encryptedTokens,
161
+ status: 'active',
162
+ statusMessage: null,
163
+ },
164
+ });
165
+ console.log('[Slack] Successfully connected workspace:', tokenResponse.team?.name, 'to team:', teamId);
166
+ res.redirect(`${appUrl}${basePath}/team/${teamId}/settings?slack=connected`);
167
+ }
168
+ catch (error) {
169
+ console.error('[Slack] Callback error:', error);
170
+ const appUrl = process.env.APP_URL || 'http://localhost:5173';
171
+ const config = getConfig();
172
+ const basePath = config.app?.basePath || '';
173
+ res.redirect(`${appUrl}${basePath}/teams?slack=error&message=server_error`);
174
+ }
175
+ });
176
+ // ============================================================================
177
+ // Integration Management
178
+ // ============================================================================
179
+ /**
180
+ * GET /api/slack/:teamId/status - Get Slack integration status
181
+ */
182
+ slackRouter.get('/:teamId/status', requireSlackEnabled, requireTeamsEnabled, requireAuth, requireTeamRole('viewer'), async (req, res, next) => {
183
+ try {
184
+ const { teamId } = req.params;
185
+ const integration = await db.slackIntegration.findUnique({
186
+ where: { teamId },
187
+ select: {
188
+ id: true,
189
+ slackWorkspaceId: true,
190
+ slackWorkspaceName: true,
191
+ notificationChannel: true,
192
+ aiChatEnabled: true,
193
+ status: true,
194
+ statusMessage: true,
195
+ installedAt: true,
196
+ },
197
+ });
198
+ if (!integration) {
199
+ return res.json({ connected: false });
200
+ }
201
+ res.json({
202
+ connected: integration.status === 'active',
203
+ integration: {
204
+ id: integration.id,
205
+ workspaceId: integration.slackWorkspaceId,
206
+ workspaceName: integration.slackWorkspaceName,
207
+ notificationChannel: integration.notificationChannel,
208
+ aiChatEnabled: integration.aiChatEnabled,
209
+ status: integration.status,
210
+ statusMessage: integration.statusMessage,
211
+ installedAt: integration.installedAt,
212
+ },
213
+ });
214
+ }
215
+ catch (error) {
216
+ next(error);
217
+ }
218
+ });
219
+ /**
220
+ * DELETE /api/slack/:teamId - Disconnect Slack integration
221
+ */
222
+ slackRouter.delete('/:teamId', requireSlackEnabled, requireTeamsEnabled, requireAuth, requireTeamRole('admin'), async (req, res, next) => {
223
+ try {
224
+ const { teamId } = req.params;
225
+ const integration = await db.slackIntegration.findUnique({
226
+ where: { teamId },
227
+ });
228
+ if (!integration) {
229
+ throw new AppError(HTTP_STATUS.NOT_FOUND, 'Slack integration not found');
230
+ }
231
+ // Delete the integration
232
+ await db.slackIntegration.delete({
233
+ where: { id: integration.id },
234
+ });
235
+ console.log('[Slack] Disconnected workspace from team:', teamId);
236
+ res.status(HTTP_STATUS.NO_CONTENT).send();
237
+ }
238
+ catch (error) {
239
+ next(error);
240
+ }
241
+ });
242
+ /**
243
+ * PATCH /api/slack/:teamId/settings - Update integration settings
244
+ */
245
+ slackRouter.patch('/:teamId/settings', requireSlackEnabled, requireTeamsEnabled, requireAuth, requireTeamRole('admin'), async (req, res, next) => {
246
+ try {
247
+ const { teamId } = req.params;
248
+ const { notificationChannel, aiChatEnabled } = req.body;
249
+ const integration = await db.slackIntegration.findUnique({
250
+ where: { teamId },
251
+ });
252
+ if (!integration) {
253
+ throw new AppError(HTTP_STATUS.NOT_FOUND, 'Slack integration not found');
254
+ }
255
+ const updateData = {};
256
+ if (notificationChannel !== undefined)
257
+ updateData.notificationChannel = notificationChannel;
258
+ if (aiChatEnabled !== undefined)
259
+ updateData.aiChatEnabled = aiChatEnabled;
260
+ const updated = await db.slackIntegration.update({
261
+ where: { id: integration.id },
262
+ data: updateData,
263
+ select: {
264
+ id: true,
265
+ notificationChannel: true,
266
+ aiChatEnabled: true,
267
+ },
268
+ });
269
+ res.json({ integration: updated });
270
+ }
271
+ catch (error) {
272
+ next(error);
273
+ }
274
+ });
275
+ // ============================================================================
276
+ // Webhook Endpoints
277
+ // ============================================================================
278
+ // We need raw body for signature verification
279
+ // This is handled at app level with express.raw middleware
280
+ /**
281
+ * POST /api/slack/events - Receive Slack events
282
+ */
283
+ slackRouter.post('/events', requireSlackEnabled, async (req, res, next) => {
284
+ try {
285
+ // Get raw body for signature verification
286
+ const rawBody = typeof req.body === 'string' ? req.body : JSON.stringify(req.body);
287
+ const signature = req.headers['x-slack-signature'];
288
+ const timestamp = req.headers['x-slack-request-timestamp'];
289
+ // Verify signature
290
+ if (!verifySlackSignature(signature, timestamp, rawBody)) {
291
+ console.warn('[Slack] Invalid signature');
292
+ return res.status(HTTP_STATUS.UNAUTHORIZED).json({ error: 'Invalid signature' });
293
+ }
294
+ const event = typeof req.body === 'string' ? JSON.parse(req.body) : req.body;
295
+ // Handle URL verification challenge
296
+ if (event.type === 'url_verification') {
297
+ return res.json({ challenge: event.challenge });
298
+ }
299
+ // Handle event callbacks
300
+ if (event.type === 'event_callback') {
301
+ const workspaceId = event.team_id;
302
+ const innerEvent = event.event;
303
+ // Find integration by workspace ID
304
+ const integration = await db.slackIntegration.findUnique({
305
+ where: { slackWorkspaceId: workspaceId },
306
+ });
307
+ if (!integration) {
308
+ // Silently ignore events from unknown workspaces
309
+ console.log('[Slack] Event from unknown workspace:', workspaceId);
310
+ return res.status(HTTP_STATUS.OK).send();
311
+ }
312
+ if (integration.status !== 'active') {
313
+ console.log('[Slack] Event from inactive integration:', integration.id);
314
+ return res.status(HTTP_STATUS.OK).send();
315
+ }
316
+ // Check for app_mention or message events
317
+ if (innerEvent.type === 'app_mention' || innerEvent.type === 'message') {
318
+ // Skip bot messages to avoid loops
319
+ if (innerEvent.bot_id || innerEvent.subtype === 'bot_message') {
320
+ return res.status(HTTP_STATUS.OK).send();
321
+ }
322
+ // For message events (not app_mention), only respond to thread replies
323
+ // where the bot has already participated
324
+ if (innerEvent.type === 'message') {
325
+ // Must be in a thread
326
+ if (!innerEvent.thread_ts) {
327
+ return res.status(HTTP_STATUS.OK).send();
328
+ }
329
+ // Check if bot has already participated in this thread
330
+ const botParticipated = await db.slackMessageEvent.findFirst({
331
+ where: {
332
+ integrationId: integration.id,
333
+ slackChannelId: innerEvent.channel,
334
+ slackThreadTs: innerEvent.thread_ts,
335
+ status: { in: ['completed', 'processing', 'pending'] },
336
+ },
337
+ });
338
+ if (!botParticipated) {
339
+ // Bot hasn't been mentioned in this thread, ignore the message
340
+ return res.status(HTTP_STATUS.OK).send();
341
+ }
342
+ }
343
+ // Check for deduplication
344
+ const existingEvent = await db.slackMessageEvent.findUnique({
345
+ where: { slackEventId: event.event_id },
346
+ });
347
+ if (existingEvent) {
348
+ console.log('[Slack] Duplicate event:', event.event_id);
349
+ return res.status(HTTP_STATUS.OK).send();
350
+ }
351
+ // Create pending event record
352
+ const slackEvent = await db.slackMessageEvent.create({
353
+ data: {
354
+ integrationId: integration.id,
355
+ slackEventId: event.event_id,
356
+ slackChannelId: innerEvent.channel,
357
+ slackThreadTs: innerEvent.thread_ts || null,
358
+ slackMessageTs: innerEvent.ts,
359
+ slackUserId: innerEvent.user,
360
+ messageText: innerEvent.text,
361
+ status: 'pending',
362
+ },
363
+ });
364
+ // Fire-and-forget async processing
365
+ const apiUrl = process.env.API_URL || 'http://localhost:3000';
366
+ fetch(`${apiUrl}/api/slack/internal/process`, {
367
+ method: 'POST',
368
+ headers: {
369
+ 'Content-Type': 'application/json',
370
+ 'X-Slack-Internal-Secret': getInternalSecret(),
371
+ },
372
+ body: JSON.stringify({ eventId: slackEvent.id }),
373
+ }).catch(err => {
374
+ console.error('[Slack] Failed to trigger processing:', err);
375
+ });
376
+ }
377
+ // Always respond quickly to Slack
378
+ return res.status(HTTP_STATUS.OK).send();
379
+ }
380
+ // Unknown event type
381
+ res.status(HTTP_STATUS.OK).send();
382
+ }
383
+ catch (error) {
384
+ console.error('[Slack] Event handler error:', error);
385
+ // Still return 200 to avoid Slack retrying on our errors
386
+ res.status(HTTP_STATUS.OK).send();
387
+ }
388
+ });
389
+ // ============================================================================
390
+ // Internal Processing Endpoints
391
+ // ============================================================================
392
+ /**
393
+ * POST /api/slack/internal/process - Process a pending event
394
+ */
395
+ slackRouter.post('/internal/process', requireSlackEnabled, async (req, res, next) => {
396
+ try {
397
+ // Verify internal secret
398
+ const internalSecret = req.headers['x-slack-internal-secret'];
399
+ if (!verifyInternalSecret(internalSecret)) {
400
+ return res.status(HTTP_STATUS.UNAUTHORIZED).json({ error: 'Unauthorized' });
401
+ }
402
+ const { eventId } = req.body;
403
+ if (!eventId) {
404
+ return res.status(HTTP_STATUS.BAD_REQUEST).json({ error: 'Missing eventId' });
405
+ }
406
+ // Process the event
407
+ await processSlackEvent(eventId);
408
+ res.status(HTTP_STATUS.OK).json({ processed: true });
409
+ }
410
+ catch (error) {
411
+ console.error('[Slack] Process error:', error);
412
+ res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({
413
+ error: error instanceof Error ? error.message : 'Processing failed',
414
+ });
415
+ }
416
+ });
417
+ /**
418
+ * POST /api/slack/internal/retry - Retry stale events
419
+ */
420
+ slackRouter.post('/internal/retry', requireSlackEnabled, async (req, res, next) => {
421
+ try {
422
+ // Verify internal secret
423
+ const internalSecret = req.headers['x-slack-internal-secret'];
424
+ if (!verifyInternalSecret(internalSecret)) {
425
+ return res.status(HTTP_STATUS.UNAUTHORIZED).json({ error: 'Unauthorized' });
426
+ }
427
+ // Find stale events
428
+ const staleThreshold = new Date(Date.now() - 3 * 60 * 1000); // 3 minutes ago
429
+ const staleEvents = await db.slackMessageEvent.findMany({
430
+ where: {
431
+ status: { in: ['pending', 'processing'] },
432
+ updatedAt: { lt: staleThreshold },
433
+ retryCount: { lt: 3 },
434
+ },
435
+ take: 10,
436
+ });
437
+ const apiUrl = process.env.API_URL || 'http://localhost:3000';
438
+ let retriedCount = 0;
439
+ for (const event of staleEvents) {
440
+ // Increment retry count
441
+ await db.slackMessageEvent.update({
442
+ where: { id: event.id },
443
+ data: {
444
+ retryCount: { increment: 1 },
445
+ status: 'pending',
446
+ },
447
+ });
448
+ // Trigger reprocessing
449
+ fetch(`${apiUrl}/api/slack/internal/process`, {
450
+ method: 'POST',
451
+ headers: {
452
+ 'Content-Type': 'application/json',
453
+ 'X-Slack-Internal-Secret': getInternalSecret(),
454
+ },
455
+ body: JSON.stringify({ eventId: event.id }),
456
+ }).catch(err => {
457
+ console.error('[Slack] Failed to trigger retry:', err);
458
+ });
459
+ retriedCount++;
460
+ }
461
+ res.json({ retriedCount });
462
+ }
463
+ catch (error) {
464
+ console.error('[Slack] Retry error:', error);
465
+ next(error);
466
+ }
467
+ });
468
+ //# sourceMappingURL=slack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.js","sourceRoot":"","sources":["../../src/api/slack.ts"],"names":[],"mappings":"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"}