summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFrank <[email protected]>2026-01-20 23:06:06 -0500
committerFrank <[email protected]>2026-01-20 23:06:08 -0500
commitbe9a0bfee7b5e3a3f553a2d29b7b983cc5bccf5e (patch)
tree5ca9000914d7b7992c0963418cab4a87f3a12b65
parentdac73572e0ecf708d2968bb981e3fe65743dfbda (diff)
downloadopencode-be9a0bfee7b5e3a3f553a2d29b7b983cc5bccf5e.tar.gz
opencode-be9a0bfee7b5e3a3f553a2d29b7b983cc5bccf5e.zip
wip: support
-rw-r--r--infra/app.ts15
-rw-r--r--packages/console/core/sst-env.d.ts16
-rw-r--r--packages/console/function/sst-env.d.ts16
-rw-r--r--packages/console/resource/sst-env.d.ts16
-rw-r--r--packages/enterprise/sst-env.d.ts16
-rw-r--r--packages/function/src/api.ts66
-rw-r--r--packages/function/sst-env.d.ts16
-rw-r--r--sst-env.d.ts16
8 files changed, 176 insertions, 1 deletions
diff --git a/infra/app.ts b/infra/app.ts
index 1b2351ec8..bb627f51e 100644
--- a/infra/app.ts
+++ b/infra/app.ts
@@ -4,6 +4,10 @@ const GITHUB_APP_ID = new sst.Secret("GITHUB_APP_ID")
const GITHUB_APP_PRIVATE_KEY = new sst.Secret("GITHUB_APP_PRIVATE_KEY")
export const EMAILOCTOPUS_API_KEY = new sst.Secret("EMAILOCTOPUS_API_KEY")
const ADMIN_SECRET = new sst.Secret("ADMIN_SECRET")
+const DISCORD_SUPPORT_BOT_TOKEN = new sst.Secret("DISCORD_SUPPORT_BOT_TOKEN")
+const DISCORD_SUPPORT_CHANNEL_ID = new sst.Secret("DISCORD_SUPPORT_CHANNEL_ID")
+const FEISHU_APP_ID = new sst.Secret("FEISHU_APP_ID")
+const FEISHU_APP_SECRET = new sst.Secret("FEISHU_APP_SECRET")
const bucket = new sst.cloudflare.Bucket("Bucket")
export const api = new sst.cloudflare.Worker("Api", {
@@ -13,7 +17,16 @@ export const api = new sst.cloudflare.Worker("Api", {
WEB_DOMAIN: domain,
},
url: true,
- link: [bucket, GITHUB_APP_ID, GITHUB_APP_PRIVATE_KEY, ADMIN_SECRET],
+ link: [
+ bucket,
+ GITHUB_APP_ID,
+ GITHUB_APP_PRIVATE_KEY,
+ ADMIN_SECRET,
+ DISCORD_SUPPORT_BOT_TOKEN,
+ DISCORD_SUPPORT_CHANNEL_ID,
+ FEISHU_APP_ID,
+ FEISHU_APP_SECRET,
+ ],
transform: {
worker: (args) => {
args.logpush = true
diff --git a/packages/console/core/sst-env.d.ts b/packages/console/core/sst-env.d.ts
index 3710cb77f..66c06a824 100644
--- a/packages/console/core/sst-env.d.ts
+++ b/packages/console/core/sst-env.d.ts
@@ -34,6 +34,14 @@ declare module "sst" {
"type": "sst.cloudflare.SolidStart"
"url": string
}
+ "DISCORD_SUPPORT_BOT_TOKEN": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
+ "DISCORD_SUPPORT_CHANNEL_ID": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"Database": {
"database": string
"host": string
@@ -46,6 +54,14 @@ declare module "sst" {
"type": "sst.sst.Secret"
"value": string
}
+ "FEISHU_APP_ID": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
+ "FEISHU_APP_SECRET": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"GITHUB_APP_ID": {
"type": "sst.sst.Secret"
"value": string
diff --git a/packages/console/function/sst-env.d.ts b/packages/console/function/sst-env.d.ts
index 3710cb77f..66c06a824 100644
--- a/packages/console/function/sst-env.d.ts
+++ b/packages/console/function/sst-env.d.ts
@@ -34,6 +34,14 @@ declare module "sst" {
"type": "sst.cloudflare.SolidStart"
"url": string
}
+ "DISCORD_SUPPORT_BOT_TOKEN": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
+ "DISCORD_SUPPORT_CHANNEL_ID": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"Database": {
"database": string
"host": string
@@ -46,6 +54,14 @@ declare module "sst" {
"type": "sst.sst.Secret"
"value": string
}
+ "FEISHU_APP_ID": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
+ "FEISHU_APP_SECRET": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"GITHUB_APP_ID": {
"type": "sst.sst.Secret"
"value": string
diff --git a/packages/console/resource/sst-env.d.ts b/packages/console/resource/sst-env.d.ts
index 3710cb77f..66c06a824 100644
--- a/packages/console/resource/sst-env.d.ts
+++ b/packages/console/resource/sst-env.d.ts
@@ -34,6 +34,14 @@ declare module "sst" {
"type": "sst.cloudflare.SolidStart"
"url": string
}
+ "DISCORD_SUPPORT_BOT_TOKEN": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
+ "DISCORD_SUPPORT_CHANNEL_ID": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"Database": {
"database": string
"host": string
@@ -46,6 +54,14 @@ declare module "sst" {
"type": "sst.sst.Secret"
"value": string
}
+ "FEISHU_APP_ID": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
+ "FEISHU_APP_SECRET": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"GITHUB_APP_ID": {
"type": "sst.sst.Secret"
"value": string
diff --git a/packages/enterprise/sst-env.d.ts b/packages/enterprise/sst-env.d.ts
index 3710cb77f..66c06a824 100644
--- a/packages/enterprise/sst-env.d.ts
+++ b/packages/enterprise/sst-env.d.ts
@@ -34,6 +34,14 @@ declare module "sst" {
"type": "sst.cloudflare.SolidStart"
"url": string
}
+ "DISCORD_SUPPORT_BOT_TOKEN": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
+ "DISCORD_SUPPORT_CHANNEL_ID": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"Database": {
"database": string
"host": string
@@ -46,6 +54,14 @@ declare module "sst" {
"type": "sst.sst.Secret"
"value": string
}
+ "FEISHU_APP_ID": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
+ "FEISHU_APP_SECRET": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"GITHUB_APP_ID": {
"type": "sst.sst.Secret"
"value": string
diff --git a/packages/function/src/api.ts b/packages/function/src/api.ts
index 6f00dae9a..d08e9e49a 100644
--- a/packages/function/src/api.ts
+++ b/packages/function/src/api.ts
@@ -12,6 +12,20 @@ type Env = {
WEB_DOMAIN: string
}
+async function getFeishuTenantToken(): Promise<string> {
+ const response = await fetch("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({
+ app_id: Resource.FEISHU_APP_ID.value,
+ app_secret: Resource.FEISHU_APP_SECRET.value,
+ }),
+ })
+ const data = (await response.json()) as { tenant_access_token?: string }
+ if (!data.tenant_access_token) throw new Error("Failed to get Feishu tenant token")
+ return data.tenant_access_token
+}
+
export class SyncServer extends DurableObject<Env> {
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env)
@@ -200,6 +214,58 @@ export default new Hono<{ Bindings: Env }>()
return c.json({ info, messages })
})
+ .post("/feishu", async (c) => {
+ const body = (await c.req.json()) as {
+ challenge?: string
+ event?: {
+ message?: {
+ message_id?: string
+ root_id?: string
+ parent_id?: string
+ chat_id?: string
+ content?: string
+ }
+ }
+}
+ console.log(JSON.stringify(body, null, 2))
+ const challenge = body.challenge
+ if (challenge) return c.json({ challenge })
+
+ const content = body.event?.message?.content
+ const parsed =
+ typeof content === "string" && content.trim().startsWith("{") ? (JSON.parse(content) as {
+ text?: string
+}) : undefined
+ const text = typeof parsed?.text === "string" ? parsed.text : typeof content === "string" ? content : ""
+
+ let message = text.trim().replace(/^@_user_\d+\s*/, "")
+ message = message.replace(/^aiden,?\s*/i, "<@759257817772851260> ")
+ if (!message) return c.json({ ok: true })
+
+ const threadId = body.event?.message?.root_id || body.event?.message?.message_id
+ if (threadId) message = `${message} [${threadId}]`
+
+ const response = await fetch(
+ `https://discord.com/api/v10/channels/${Resource.DISCORD_SUPPORT_CHANNEL_ID.value}/messages`,
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: `Bot ${Resource.DISCORD_SUPPORT_BOT_TOKEN.value}`,
+ },
+ body: JSON.stringify({
+ content: `${message}`,
+ }),
+ },
+ )
+
+ if (!response.ok) {
+ console.error(await response.text())
+ return c.json({ error: "Discord bot message failed" }, { status: 502 })
+ }
+
+ return c.json({ ok: true })
+ })
/**
* Used by the GitHub action to get GitHub installation access token given the OIDC token
*/
diff --git a/packages/function/sst-env.d.ts b/packages/function/sst-env.d.ts
index 3710cb77f..66c06a824 100644
--- a/packages/function/sst-env.d.ts
+++ b/packages/function/sst-env.d.ts
@@ -34,6 +34,14 @@ declare module "sst" {
"type": "sst.cloudflare.SolidStart"
"url": string
}
+ "DISCORD_SUPPORT_BOT_TOKEN": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
+ "DISCORD_SUPPORT_CHANNEL_ID": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"Database": {
"database": string
"host": string
@@ -46,6 +54,14 @@ declare module "sst" {
"type": "sst.sst.Secret"
"value": string
}
+ "FEISHU_APP_ID": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
+ "FEISHU_APP_SECRET": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"GITHUB_APP_ID": {
"type": "sst.sst.Secret"
"value": string
diff --git a/sst-env.d.ts b/sst-env.d.ts
index ad02b7bf1..b767ef1b3 100644
--- a/sst-env.d.ts
+++ b/sst-env.d.ts
@@ -49,6 +49,14 @@ declare module "sst" {
"type": "sst.cloudflare.SolidStart"
"url": string
}
+ "DISCORD_SUPPORT_BOT_TOKEN": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
+ "DISCORD_SUPPORT_CHANNEL_ID": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"Database": {
"database": string
"host": string
@@ -65,6 +73,14 @@ declare module "sst" {
"name": string
"type": "sst.cloudflare.Bucket"
}
+ "FEISHU_APP_ID": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
+ "FEISHU_APP_SECRET": {
+ "type": "sst.sst.Secret"
+ "value": string
+ }
"GITHUB_APP_ID": {
"type": "sst.sst.Secret"
"value": string