wip: support
This commit is contained in:
15
infra/app.ts
15
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")
|
const GITHUB_APP_PRIVATE_KEY = new sst.Secret("GITHUB_APP_PRIVATE_KEY")
|
||||||
export const EMAILOCTOPUS_API_KEY = new sst.Secret("EMAILOCTOPUS_API_KEY")
|
export const EMAILOCTOPUS_API_KEY = new sst.Secret("EMAILOCTOPUS_API_KEY")
|
||||||
const ADMIN_SECRET = new sst.Secret("ADMIN_SECRET")
|
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")
|
const bucket = new sst.cloudflare.Bucket("Bucket")
|
||||||
|
|
||||||
export const api = new sst.cloudflare.Worker("Api", {
|
export const api = new sst.cloudflare.Worker("Api", {
|
||||||
@@ -13,7 +17,16 @@ export const api = new sst.cloudflare.Worker("Api", {
|
|||||||
WEB_DOMAIN: domain,
|
WEB_DOMAIN: domain,
|
||||||
},
|
},
|
||||||
url: true,
|
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: {
|
transform: {
|
||||||
worker: (args) => {
|
worker: (args) => {
|
||||||
args.logpush = true
|
args.logpush = true
|
||||||
|
|||||||
16
packages/console/core/sst-env.d.ts
vendored
16
packages/console/core/sst-env.d.ts
vendored
@@ -34,6 +34,14 @@ declare module "sst" {
|
|||||||
"type": "sst.cloudflare.SolidStart"
|
"type": "sst.cloudflare.SolidStart"
|
||||||
"url": string
|
"url": string
|
||||||
}
|
}
|
||||||
|
"DISCORD_SUPPORT_BOT_TOKEN": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
|
"DISCORD_SUPPORT_CHANNEL_ID": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
"Database": {
|
"Database": {
|
||||||
"database": string
|
"database": string
|
||||||
"host": string
|
"host": string
|
||||||
@@ -46,6 +54,14 @@ declare module "sst" {
|
|||||||
"type": "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
"value": string
|
"value": string
|
||||||
}
|
}
|
||||||
|
"FEISHU_APP_ID": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
|
"FEISHU_APP_SECRET": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
"GITHUB_APP_ID": {
|
"GITHUB_APP_ID": {
|
||||||
"type": "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
"value": string
|
"value": string
|
||||||
|
|||||||
16
packages/console/function/sst-env.d.ts
vendored
16
packages/console/function/sst-env.d.ts
vendored
@@ -34,6 +34,14 @@ declare module "sst" {
|
|||||||
"type": "sst.cloudflare.SolidStart"
|
"type": "sst.cloudflare.SolidStart"
|
||||||
"url": string
|
"url": string
|
||||||
}
|
}
|
||||||
|
"DISCORD_SUPPORT_BOT_TOKEN": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
|
"DISCORD_SUPPORT_CHANNEL_ID": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
"Database": {
|
"Database": {
|
||||||
"database": string
|
"database": string
|
||||||
"host": string
|
"host": string
|
||||||
@@ -46,6 +54,14 @@ declare module "sst" {
|
|||||||
"type": "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
"value": string
|
"value": string
|
||||||
}
|
}
|
||||||
|
"FEISHU_APP_ID": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
|
"FEISHU_APP_SECRET": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
"GITHUB_APP_ID": {
|
"GITHUB_APP_ID": {
|
||||||
"type": "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
"value": string
|
"value": string
|
||||||
|
|||||||
16
packages/console/resource/sst-env.d.ts
vendored
16
packages/console/resource/sst-env.d.ts
vendored
@@ -34,6 +34,14 @@ declare module "sst" {
|
|||||||
"type": "sst.cloudflare.SolidStart"
|
"type": "sst.cloudflare.SolidStart"
|
||||||
"url": string
|
"url": string
|
||||||
}
|
}
|
||||||
|
"DISCORD_SUPPORT_BOT_TOKEN": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
|
"DISCORD_SUPPORT_CHANNEL_ID": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
"Database": {
|
"Database": {
|
||||||
"database": string
|
"database": string
|
||||||
"host": string
|
"host": string
|
||||||
@@ -46,6 +54,14 @@ declare module "sst" {
|
|||||||
"type": "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
"value": string
|
"value": string
|
||||||
}
|
}
|
||||||
|
"FEISHU_APP_ID": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
|
"FEISHU_APP_SECRET": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
"GITHUB_APP_ID": {
|
"GITHUB_APP_ID": {
|
||||||
"type": "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
"value": string
|
"value": string
|
||||||
|
|||||||
16
packages/enterprise/sst-env.d.ts
vendored
16
packages/enterprise/sst-env.d.ts
vendored
@@ -34,6 +34,14 @@ declare module "sst" {
|
|||||||
"type": "sst.cloudflare.SolidStart"
|
"type": "sst.cloudflare.SolidStart"
|
||||||
"url": string
|
"url": string
|
||||||
}
|
}
|
||||||
|
"DISCORD_SUPPORT_BOT_TOKEN": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
|
"DISCORD_SUPPORT_CHANNEL_ID": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
"Database": {
|
"Database": {
|
||||||
"database": string
|
"database": string
|
||||||
"host": string
|
"host": string
|
||||||
@@ -46,6 +54,14 @@ declare module "sst" {
|
|||||||
"type": "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
"value": string
|
"value": string
|
||||||
}
|
}
|
||||||
|
"FEISHU_APP_ID": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
|
"FEISHU_APP_SECRET": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
"GITHUB_APP_ID": {
|
"GITHUB_APP_ID": {
|
||||||
"type": "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
"value": string
|
"value": string
|
||||||
|
|||||||
@@ -12,6 +12,20 @@ type Env = {
|
|||||||
WEB_DOMAIN: string
|
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> {
|
export class SyncServer extends DurableObject<Env> {
|
||||||
constructor(ctx: DurableObjectState, env: Env) {
|
constructor(ctx: DurableObjectState, env: Env) {
|
||||||
super(ctx, env)
|
super(ctx, env)
|
||||||
@@ -200,6 +214,58 @@ export default new Hono<{ Bindings: Env }>()
|
|||||||
|
|
||||||
return c.json({ info, messages })
|
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
|
* Used by the GitHub action to get GitHub installation access token given the OIDC token
|
||||||
*/
|
*/
|
||||||
|
|||||||
16
packages/function/sst-env.d.ts
vendored
16
packages/function/sst-env.d.ts
vendored
@@ -34,6 +34,14 @@ declare module "sst" {
|
|||||||
"type": "sst.cloudflare.SolidStart"
|
"type": "sst.cloudflare.SolidStart"
|
||||||
"url": string
|
"url": string
|
||||||
}
|
}
|
||||||
|
"DISCORD_SUPPORT_BOT_TOKEN": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
|
"DISCORD_SUPPORT_CHANNEL_ID": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
"Database": {
|
"Database": {
|
||||||
"database": string
|
"database": string
|
||||||
"host": string
|
"host": string
|
||||||
@@ -46,6 +54,14 @@ declare module "sst" {
|
|||||||
"type": "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
"value": string
|
"value": string
|
||||||
}
|
}
|
||||||
|
"FEISHU_APP_ID": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
|
"FEISHU_APP_SECRET": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
"GITHUB_APP_ID": {
|
"GITHUB_APP_ID": {
|
||||||
"type": "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
"value": string
|
"value": string
|
||||||
|
|||||||
16
sst-env.d.ts
vendored
16
sst-env.d.ts
vendored
@@ -49,6 +49,14 @@ declare module "sst" {
|
|||||||
"type": "sst.cloudflare.SolidStart"
|
"type": "sst.cloudflare.SolidStart"
|
||||||
"url": string
|
"url": string
|
||||||
}
|
}
|
||||||
|
"DISCORD_SUPPORT_BOT_TOKEN": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
|
"DISCORD_SUPPORT_CHANNEL_ID": {
|
||||||
|
"type": "sst.sst.Secret"
|
||||||
|
"value": string
|
||||||
|
}
|
||||||
"Database": {
|
"Database": {
|
||||||
"database": string
|
"database": string
|
||||||
"host": string
|
"host": string
|
||||||
@@ -65,6 +73,14 @@ declare module "sst" {
|
|||||||
"name": string
|
"name": string
|
||||||
"type": "sst.cloudflare.Bucket"
|
"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": {
|
"GITHUB_APP_ID": {
|
||||||
"type": "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
"value": string
|
"value": string
|
||||||
|
|||||||
Reference in New Issue
Block a user