diff options
| author | Dax Raad <[email protected]> | 2025-10-14 02:53:55 -0400 |
|---|---|---|
| committer | Dax Raad <[email protected]> | 2025-10-14 02:53:55 -0400 |
| commit | 1923ddab6eebbd5b817a88574deda7cb7f94e782 (patch) | |
| tree | 10e1e54e8b106b67b64346cc5b23a12fa3775deb /packages/slack/src | |
| parent | b8249cde4b1c5ed73daf31c002f9f5e2b2e3c89b (diff) | |
| download | opencode-1923ddab6eebbd5b817a88574deda7cb7f94e782.tar.gz opencode-1923ddab6eebbd5b817a88574deda7cb7f94e782.zip | |
feat: add Slack integration package with Bolt framework
Diffstat (limited to 'packages/slack/src')
| -rw-r--r-- | packages/slack/src/index.ts | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/packages/slack/src/index.ts b/packages/slack/src/index.ts new file mode 100644 index 000000000..e86b8fec5 --- /dev/null +++ b/packages/slack/src/index.ts @@ -0,0 +1,105 @@ +import { App } from "@slack/bolt" +import { createOpencode } from "@opencode-ai/sdk" + +const app = new App({ + token: process.env.SLACK_BOT_TOKEN, + signingSecret: process.env.SLACK_SIGNING_SECRET, + socketMode: true, + appToken: process.env.SLACK_APP_TOKEN, +}) + +console.log("๐ง Bot configuration:") +console.log("- Bot token present:", !!process.env.SLACK_BOT_TOKEN) +console.log("- Signing secret present:", !!process.env.SLACK_SIGNING_SECRET) +console.log("- App token present:", !!process.env.SLACK_APP_TOKEN) + +console.log("๐ Starting opencode server...") +const opencode = await createOpencode({ + port: 0, +}) +console.log("โ
Opencode server ready") + +const sessions = new Map<string, { client: any; server: any; sessionId: string; channel: string; thread: string }>() + +app.use(async ({ next, context }) => { + console.log("๐ก Raw Slack event:", JSON.stringify(context, null, 2)) + await next() +}) + +app.message(async ({ message, say }) => { + console.log("๐จ Received message event:", JSON.stringify(message, null, 2)) + + if (message.subtype || !("text" in message) || !message.text) { + console.log("โญ๏ธ Skipping message - no text or has subtype") + return + } + + console.log("โ
Processing message:", message.text) + + const channel = message.channel + const thread = (message as any).thread_ts || message.ts + const sessionKey = `${channel}-${thread}` + + let session = sessions.get(sessionKey) + + if (!session) { + console.log("๐ Creating new opencode session...") + const { client, server } = opencode + + const createResult = await client.session.create({ + body: { title: `Slack thread ${thread}` }, + }) + + if (createResult.error) { + console.error("โ Failed to create session:", createResult.error) + await say({ text: "Sorry, I had trouble creating a session. Please try again.", thread_ts: thread }) + return + } + + console.log("โ
Created opencode session:", createResult.data.id) + session = { client, server, sessionId: createResult.data.id, channel, thread } + sessions.set(sessionKey, session) + + const shareResult = await client.session.share({ path: { id: createResult.data.id } }) + if (!shareResult.error && shareResult.data) { + const sessionUrl = shareResult.data.share?.url! + console.log("๐ Session shared:", sessionUrl) + await app.client.chat.postMessage({ channel, thread_ts: thread, text: sessionUrl }) + } + } + + console.log("๐ Sending to opencode:", message.text) + const result = await session.client.session.prompt({ + path: { id: session.sessionId }, + body: { parts: [{ type: "text", text: message.text }] }, + }) + + console.log("๐ค Opencode response:", JSON.stringify(result, null, 2)) + + if (result.error) { + console.error("โ Failed to send message:", result.error) + await say({ text: "Sorry, I had trouble processing your message. Please try again.", thread_ts: thread }) + return + } + + const response = result.data + const responseText = + response.info?.content || + response.parts + ?.filter((p: any) => p.type === "text") + .map((p: any) => p.text) + .join("\n") || + "I received your message but didn't have a response." + + console.log("๐ฌ Sending response:", responseText) + await say({ text: responseText, thread_ts: thread }) +}) + +app.command("/test", async ({ command, ack, say }) => { + await ack() + console.log("๐งช Test command received:", JSON.stringify(command, null, 2)) + await say("๐ค Bot is working! I can hear you loud and clear.") +}) + +await app.start() +console.log("โก๏ธ Slack bot is running!") |
