@fased/fased 0.1.36 → 0.1.37
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/config/capability-catalog.json +241 -0
- package/config/dependency-ownership.json +130 -0
- package/config/official-channel-catalog.json +39 -0
- package/dist/agents/tools/web-fetch-utils.js +2 -1
- package/dist/agents/tools/web-fetch-visibility.js +3 -1
- package/dist/brand.js +1 -1
- package/dist/browser/pw-session.js +2 -1
- package/dist/browser/pw-tools-core.state.js +3 -2
- package/dist/browser/runtime-dependency.js +27 -0
- package/dist/build-info.json +3 -3
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/capabilities/catalog.js +228 -0
- package/dist/cli/components-cli.js +105 -0
- package/dist/cli/hooks-cli.js +1 -1
- package/dist/cli/plugins-cli.js +3 -3
- package/dist/cli/program/register.subclis.js +9 -0
- package/dist/cli/update-cli/update-command.js +1 -1
- package/dist/commands/doctor-capabilities.js +26 -0
- package/dist/commands/doctor.js +2 -0
- package/dist/control-ui/assets/{app-DXYMrRJ9.js → app-JBrTSsNu.js} +1480 -1465
- package/dist/control-ui/assets/{index-iGQkJE0l.js → index-H-2DWAnH.js} +3 -3
- package/dist/control-ui/index.html +1 -1
- package/dist/gateway/method-scopes.js +1 -0
- package/dist/gateway/server-methods/plugins-marketplace.js +1 -1
- package/dist/gateway/server-methods/services.js +8 -0
- package/dist/gateway/server-methods-list.js +1 -0
- package/dist/infra/optional-runtime-dependency.js +46 -0
- package/dist/media/image-ops.js +6 -1
- package/dist/media/input-files.js +11 -2
- package/dist/media/mime.js +6 -1
- package/dist/memory/sqlite-vec.js +7 -1
- package/dist/plugin-sdk/{accounts-VqAX3HJ0.js → accounts-BwkH5bTD.js} +1 -1
- package/dist/plugin-sdk/{accounts-COY-15zJ.js → accounts-C5BjfxoO.js} +1 -1
- package/dist/plugin-sdk/{accounts-Zgt0NP54.js → accounts-RT6y7n3H.js} +1 -1
- package/dist/plugin-sdk/{actions-lB3PCwsz.js → actions-BrU_JMqM.js} +2 -2
- package/dist/plugin-sdk/{actions-BI5QViLk.js → actions-CUdVHzeJ.js} +2 -2
- package/dist/plugin-sdk/{active-listener-DKZiSaRA.js → active-listener-CE8t5g6l.js} +1 -1
- package/dist/plugin-sdk/{active-listener-D6_pdTMC.js → active-listener-Dx1SEGDn.js} +1 -1
- package/dist/plugin-sdk/{audio-preflight-Dx8J7XhV.js → audio-preflight-C8SbY4fV.js} +22 -22
- package/dist/plugin-sdk/{audio-preflight-CeRstduc.js → audio-preflight-CuABlLDL.js} +22 -22
- package/dist/plugin-sdk/{audit-BImNOQvk.js → audit-DxB2Kml5.js} +11 -11
- package/dist/plugin-sdk/{audit-CKWkq0Un.js → audit-sSeRDwJb.js} +11 -11
- package/dist/plugin-sdk/channel-plugin-common.js +3 -2
- package/dist/plugin-sdk/{chunk-skAJZWCT.js → chunk-KCxbJLsV.js} +1 -1
- package/dist/plugin-sdk/{chunk-Cjw4712g.js → chunk-M2d7r-Zt.js} +1 -1
- package/dist/plugin-sdk/{chunk-items-Df5811D0.js → chunk-items-BGbYyNvO.js} +1 -1
- package/dist/plugin-sdk/command-status.js +22 -22
- package/dist/plugin-sdk/{commands-registry-5J619bQ2.js → commands-registry-CdT-nl7v.js} +2 -2
- package/dist/plugin-sdk/{commands-registry-CoLAT03J.js → commands-registry-DoWdYAJd.js} +2 -2
- package/dist/plugin-sdk/{common-CSTxewqY.js → common-Cpw-vuuM.js} +1 -1
- package/dist/plugin-sdk/{common-BiF0sTnY.js → common-DJWrErdE.js} +1 -1
- package/dist/plugin-sdk/{config-BxVjLTIv.js → config-C0qggNKQ.js} +7 -7
- package/dist/plugin-sdk/{config-TFokWwvO.js → config-CgwTaper.js} +45 -2
- package/dist/plugin-sdk/{config-DXlISPlx.js → config-DtqAN2L3.js} +45 -2
- package/dist/plugin-sdk/{config-DgD5T-Ui.js → config-g1MG9Bet.js} +7 -7
- package/dist/plugin-sdk/discord.js +2 -1
- package/dist/plugin-sdk/{fetch-guard-DPMynms8.js → fetch-guard-BLdujDnt.js} +1 -1
- package/dist/plugin-sdk/{fetch-guard-COLmW2TM.js → fetch-guard-DTKgMN9f.js} +1 -1
- package/dist/plugin-sdk/{handle-action-C-UndB8E.js → handle-action-B61D85yo.js} +12 -12
- package/dist/plugin-sdk/{handle-action-hhufKxmU.js → handle-action-CjcxGzQD.js} +12 -12
- package/dist/plugin-sdk/index.js +22 -22
- package/dist/plugin-sdk/{login-DL1oBBfL.js → login-CB_nCjX3.js} +3 -3
- package/dist/plugin-sdk/{login-YveoqEvH.js → login-CfRfRNc7.js} +2 -2
- package/dist/plugin-sdk/{login-Dnxas1dI.js → login-CzUuDd1v.js} +3 -3
- package/dist/plugin-sdk/{login-qr-CVQsGWKq.js → login-qr-D7MEpFza.js} +3 -3
- package/dist/plugin-sdk/{login-qr-B343JNXJ.js → login-qr-DgxfBFVN.js} +3 -3
- package/dist/plugin-sdk/{manager-BytwRIfK.js → manager-9see0IX5.js} +8 -3
- package/dist/plugin-sdk/{manager-BZjd_PCt.js → manager-D2kZ0Cps.js} +8 -3
- package/dist/plugin-sdk/{markdown-tables-krKiU4cT.js → markdown-tables-CCSD52rA.js} +1 -1
- package/dist/plugin-sdk/{markdown-tables-9rJDQ1X-.js → markdown-tables-DWUNvLrc.js} +1 -1
- package/dist/plugin-sdk/{media-D7ZkWU-A.js → media-C7YT4DeU.js} +13 -4
- package/dist/plugin-sdk/{media-C6C2c9a4.js → media-Cxw-xLGU.js} +13 -4
- package/dist/plugin-sdk/{monitor-CVQNDfhs.js → monitor-9X7wapUN.js} +27 -27
- package/dist/plugin-sdk/{monitor-BCxkQBoh.js → monitor-B3IfJzKX.js} +26 -26
- package/dist/plugin-sdk/{monitor-BzDW50H6.js → monitor-CTjAST_W.js} +27 -27
- package/dist/plugin-sdk/{monitor-BsLMfn3U.js → monitor-tYFfy2u-.js} +26 -26
- package/dist/plugin-sdk/{openresponses-http-BB67Z4QM.js → openresponses-http-DEB2fEya.js} +22 -22
- package/dist/plugin-sdk/{openresponses-http-NE76GGhj.js → openresponses-http-YgMg1jnp.js} +22 -22
- package/dist/plugin-sdk/{ssrf-u0Ul7okY.js → optional-runtime-dependency-szS49voX.js} +46 -2
- package/dist/plugin-sdk/{outbound-PGNWU6T-.js → outbound-BCxOxdi-.js} +6 -6
- package/dist/plugin-sdk/{outbound-BHWJD9q0.js → outbound-JIwQbpRY.js} +6 -6
- package/dist/plugin-sdk/{outbound-attachment-BVzfhqnk.js → outbound-attachment-C-jSFaEB.js} +1 -1
- package/dist/plugin-sdk/{outbound-attachment-ClMvNW17.js → outbound-attachment-D6tj5Y5H.js} +1 -1
- package/dist/plugin-sdk/{pi-embedded-runner-DQ6UPx6-.js → pi-embedded-runner-CUVk8CIj.js} +72 -60
- package/dist/plugin-sdk/{pi-model-discovery-D51L5E9I.js → pi-model-discovery-DadlvsZW.js} +1 -1
- package/dist/plugin-sdk/{pi-model-discovery-runtime-DxoFm4Vd.js → pi-model-discovery-runtime-C5ssE6EW.js} +1 -1
- package/dist/plugin-sdk/{pi-model-discovery-runtime-DRuh4PNV.js → pi-model-discovery-runtime-DAaOPt64.js} +2 -2
- package/dist/plugin-sdk/{pi-model-discovery-runtime-CQOauapl.js → pi-model-discovery-runtime-LB-5lX5L.js} +1 -1
- package/dist/plugin-sdk/{pi-model-discovery-runtime-BTWgkx4x.js → pi-model-discovery-runtime-gd77b0UF.js} +2 -2
- package/dist/plugin-sdk/{pi-model-discovery-CkH5l9X5.js → pi-model-discovery-yifTIDIn.js} +1 -1
- package/dist/plugin-sdk/{pw-ai-DZs6uYRd.js → pw-ai-SNCI9UXT.js} +6 -5
- package/dist/plugin-sdk/{pw-ai-Cn-EUPZK.js → pw-ai-sH1Pi-Fh.js} +6 -5
- package/dist/plugin-sdk/{registry-B4HvWzob.js → registry-DNkJsNsz.js} +4 -3
- package/dist/plugin-sdk/{replies-jDMUBsNO.js → replies-fvzN5wnU.js} +2 -2
- package/dist/plugin-sdk/{replies-B_LW9c9f.js → replies-zebgZCHX.js} +2 -2
- package/dist/plugin-sdk/{resolve-route-_YZHbS-z.js → resolve-route-CNhTJG_2.js} +1 -1
- package/dist/plugin-sdk/{resolve-route-DlHzggnG.js → resolve-route-DO0WR4nB.js} +1 -1
- package/dist/plugin-sdk/{resolve-utils-zBhVX3Vx.js → resolve-utils-EFP1DYqG.js} +1 -1
- package/dist/plugin-sdk/{retry-policy-DGLs5ebP.js → retry-policy-BLYEgIwP.js} +1 -1
- package/dist/plugin-sdk/{retry-policy-DaodShGa.js → retry-policy-sM01QZT2.js} +1 -1
- package/dist/plugin-sdk/{runtime-Dd0sswuW.js → runtime-BPyuAmka.js} +4 -3
- package/dist/plugin-sdk/{paths-DW-U2r7Y.js → runtime-dependency-B-1u41Ph.js} +27 -3
- package/dist/plugin-sdk/{paths-CBCpJ5bu.js → runtime-dependency-Csswyv5r.js} +27 -3
- package/dist/plugin-sdk/sat-runtime.js +1 -0
- package/dist/plugin-sdk/{send-8remZhsH.js → send-B09HRfHN.js} +6 -6
- package/dist/plugin-sdk/{send-DaaAscWj.js → send-BBYcgXA4.js} +5 -5
- package/dist/plugin-sdk/{send-DFTB0cnx.js → send-BQXQA81e.js} +6 -6
- package/dist/plugin-sdk/{send-CtMVvMJs.js → send-BzFdvD_i.js} +6 -6
- package/dist/plugin-sdk/{send-Di9irjS-.js → send-C3u-F_8s.js} +6 -6
- package/dist/plugin-sdk/{send-Dl88ZKq2.js → send-D3836_UN.js} +6 -6
- package/dist/plugin-sdk/{send-ifgZCHVB.js → send-D7tr-EsH.js} +5 -5
- package/dist/plugin-sdk/{send-DvUpYh0d.js → send-DRGzRdI3.js} +6 -6
- package/dist/plugin-sdk/{send-D2jlPeKH.js → send-DfkPKz_0.js} +4 -4
- package/dist/plugin-sdk/{send-QSt6nbny.js → send-DsxFXrCO.js} +4 -4
- package/dist/plugin-sdk/{session-CknrceVU.js → session-DG_bYisw.js} +2 -2
- package/dist/plugin-sdk/{session-CyRTcJ8N.js → session-EIStzK0E.js} +2 -2
- package/dist/plugin-sdk/{skill-commands-DHxkTA0s.js → skill-commands-CkgGmWBS.js} +2 -2
- package/dist/plugin-sdk/{skill-commands-CLXAG5sU.js → skill-commands-hyZA0LE3.js} +2 -2
- package/dist/plugin-sdk/{slack-BpJXkwxF.js → slack-C0WZVJPZ.js} +34 -34
- package/dist/plugin-sdk/{slack-Br9c6Yzs.js → slack-DtlPw_PN.js} +34 -34
- package/dist/plugin-sdk/{slack-actions-8tLGt1Ht.js → slack-actions-BQawWGTJ.js} +11 -11
- package/dist/plugin-sdk/{slack-actions-CDSSRo8Y.js → slack-actions-DDMszx56.js} +11 -11
- package/dist/plugin-sdk/slack.js +2 -1
- package/dist/plugin-sdk/src/brand.d.ts +2 -2
- package/dist/plugin-sdk/src/browser/runtime-dependency.d.ts +3 -0
- package/dist/plugin-sdk/src/infra/optional-runtime-dependency.d.ts +6 -0
- package/dist/plugin-sdk/{ssrf-fG4UHKBw.js → ssrf-Cce6LubA.js} +41 -7
- package/dist/plugin-sdk/{status-DoxnzyMC.js → status-CIiBeb9B.js} +72 -60
- package/dist/plugin-sdk/{sticker-cache-zmJ39ByC.js → sticker-cache-9houHChV.js} +3 -3
- package/dist/plugin-sdk/{sticker-cache-D7WcMYsF.js → sticker-cache-Dwi-XsgB.js} +3 -3
- package/dist/plugin-sdk/{tables-CkxblF0u.js → tables-BD7H5ug-.js} +1 -1
- package/dist/plugin-sdk/{tables-RBtf8G4P.js → tables-CJE8kB35.js} +1 -1
- package/dist/plugin-sdk/{telegram-actions-DAeYXSLk.js → telegram-actions-Bu1edXF2.js} +25 -25
- package/dist/plugin-sdk/{telegram-actions-BDeS3ocd.js → telegram-actions-CRXVO8lG.js} +25 -25
- package/dist/plugin-sdk/telegram.js +2 -1
- package/dist/plugin-sdk/{thread-bindings.lifecycle-DsB94WbE.js → thread-bindings.lifecycle-Djem8FWF.js} +2 -2
- package/dist/plugin-sdk/{thread-bindings.lifecycle-DMhV3TsR.js → thread-bindings.lifecycle-gmHv3hc7.js} +2 -2
- package/dist/plugin-sdk/{thread-bindings.state-DYWpy7hJ.js → thread-bindings.state-CNT2vxm3.js} +2 -2
- package/dist/plugin-sdk/{thread-bindings.state-DG5cBaRn.js → thread-bindings.state-D8kN2X6H.js} +2 -2
- package/dist/plugin-sdk/{web-IJ4NoGPJ.js → web-DCrVQr6y.js} +26 -26
- package/dist/plugin-sdk/{web-DJwacWQo.js → web-Ds6OWw3C.js} +26 -26
- package/dist/plugin-sdk/{whatsapp-actions-DAY8hWpD.js → whatsapp-actions-68Mfs2dJ.js} +12 -12
- package/dist/plugin-sdk/{whatsapp-actions-6opfo-oB.js → whatsapp-actions-DRqtzvTO.js} +12 -12
- package/dist/plugin-sdk/whatsapp.js +6 -5
- package/dist/plugin-sdk/{wsl-B2euLEc2.js → wsl-DcM2PgSS.js} +3 -3
- package/dist/plugin-sdk/{wsl-B8eyviuv.js → wsl-PXrdWitE.js} +3 -3
- package/dist/plugins/update.js +1 -1
- package/dist/tts/tts-core.js +6 -1
- package/dist/wizard/onboarding.finalize.js +9 -0
- package/extensions/acpx/package.json +1 -1
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/fased-federation/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +6 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +2 -2
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +6 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +6 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/sat-mining/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/synology-chat/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +6 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +6 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +6 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +6 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +22 -15
- package/extensions/feishu/fased.plugin.json +0 -10
- package/extensions/feishu/index.ts +0 -63
- package/extensions/feishu/package.json +0 -33
- package/extensions/feishu/skills/feishu-doc/SKILL.md +0 -211
- package/extensions/feishu/skills/feishu-doc/references/block-types.md +0 -103
- package/extensions/feishu/skills/feishu-drive/SKILL.md +0 -97
- package/extensions/feishu/skills/feishu-perm/SKILL.md +0 -119
- package/extensions/feishu/skills/feishu-wiki/SKILL.md +0 -111
- package/extensions/feishu/src/accounts.ts +0 -159
- package/extensions/feishu/src/bitable.ts +0 -713
- package/extensions/feishu/src/bot.ts +0 -979
- package/extensions/feishu/src/channel.ts +0 -359
- package/extensions/feishu/src/client.ts +0 -118
- package/extensions/feishu/src/config-schema.ts +0 -226
- package/extensions/feishu/src/dedup.ts +0 -54
- package/extensions/feishu/src/directory.ts +0 -177
- package/extensions/feishu/src/doc-schema.ts +0 -122
- package/extensions/feishu/src/docx.ts +0 -998
- package/extensions/feishu/src/drive-schema.ts +0 -46
- package/extensions/feishu/src/drive.ts +0 -232
- package/extensions/feishu/src/dynamic-agent.ts +0 -131
- package/extensions/feishu/src/external-keys.ts +0 -19
- package/extensions/feishu/src/media.ts +0 -447
- package/extensions/feishu/src/mention.ts +0 -133
- package/extensions/feishu/src/monitor.ts +0 -434
- package/extensions/feishu/src/onboarding.ts +0 -430
- package/extensions/feishu/src/outbound.ts +0 -56
- package/extensions/feishu/src/perm-schema.ts +0 -52
- package/extensions/feishu/src/perm.ts +0 -180
- package/extensions/feishu/src/policy.ts +0 -116
- package/extensions/feishu/src/probe.ts +0 -44
- package/extensions/feishu/src/reactions.ts +0 -160
- package/extensions/feishu/src/reply-dispatcher.ts +0 -239
- package/extensions/feishu/src/runtime.ts +0 -14
- package/extensions/feishu/src/send-result.ts +0 -29
- package/extensions/feishu/src/send-target.ts +0 -25
- package/extensions/feishu/src/send.ts +0 -313
- package/extensions/feishu/src/streaming-card.ts +0 -218
- package/extensions/feishu/src/targets.ts +0 -78
- package/extensions/feishu/src/tool-account.ts +0 -58
- package/extensions/feishu/src/tools-config.ts +0 -21
- package/extensions/feishu/src/types.ts +0 -81
- package/extensions/feishu/src/typing.ts +0 -80
- package/extensions/feishu/src/wiki-schema.ts +0 -55
- package/extensions/feishu/src/wiki.ts +0 -237
- package/extensions/googlechat/fased.plugin.json +0 -9
- package/extensions/googlechat/index.ts +0 -19
- package/extensions/googlechat/package.json +0 -37
- package/extensions/googlechat/src/accounts.ts +0 -147
- package/extensions/googlechat/src/actions.ts +0 -176
- package/extensions/googlechat/src/api.ts +0 -282
- package/extensions/googlechat/src/auth.ts +0 -137
- package/extensions/googlechat/src/channel.ts +0 -591
- package/extensions/googlechat/src/monitor.ts +0 -996
- package/extensions/googlechat/src/onboarding.ts +0 -344
- package/extensions/googlechat/src/runtime.ts +0 -14
- package/extensions/googlechat/src/targets.ts +0 -65
- package/extensions/googlechat/src/types.config.ts +0 -3
- package/extensions/googlechat/src/types.ts +0 -73
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
import type * as Lark from "@larksuiteoapi/node-sdk";
|
|
2
|
-
import type { FasedAgentPluginApi } from "fased/plugin-sdk";
|
|
3
|
-
import { listEnabledFeishuAccounts } from "./accounts.js";
|
|
4
|
-
import { createFeishuToolClient, resolveAnyEnabledFeishuToolsConfig } from "./tool-account.js";
|
|
5
|
-
import { FeishuWikiSchema, type FeishuWikiParams } from "./wiki-schema.js";
|
|
6
|
-
|
|
7
|
-
// ============ Helpers ============
|
|
8
|
-
|
|
9
|
-
function json(data: unknown) {
|
|
10
|
-
return {
|
|
11
|
-
content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }],
|
|
12
|
-
details: data,
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
type ObjType = "doc" | "sheet" | "mindnote" | "bitable" | "file" | "docx" | "slides";
|
|
17
|
-
|
|
18
|
-
// ============ Actions ============
|
|
19
|
-
|
|
20
|
-
const WIKI_ACCESS_HINT =
|
|
21
|
-
"To grant wiki access: Open wiki space → Settings → Members → Add the bot. " +
|
|
22
|
-
"See: https://open.feishu.cn/document/server-docs/docs/wiki-v2/wiki-qa#a40ad4ca";
|
|
23
|
-
|
|
24
|
-
async function listSpaces(client: Lark.Client) {
|
|
25
|
-
const res = await client.wiki.space.list({});
|
|
26
|
-
if (res.code !== 0) {
|
|
27
|
-
throw new Error(res.msg);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const spaces =
|
|
31
|
-
res.data?.items?.map((s) => ({
|
|
32
|
-
space_id: s.space_id,
|
|
33
|
-
name: s.name,
|
|
34
|
-
description: s.description,
|
|
35
|
-
visibility: s.visibility,
|
|
36
|
-
})) ?? [];
|
|
37
|
-
|
|
38
|
-
return {
|
|
39
|
-
spaces,
|
|
40
|
-
...(spaces.length === 0 && { hint: WIKI_ACCESS_HINT }),
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async function listNodes(client: Lark.Client, spaceId: string, parentNodeToken?: string) {
|
|
45
|
-
const res = await client.wiki.spaceNode.list({
|
|
46
|
-
path: { space_id: spaceId },
|
|
47
|
-
params: { parent_node_token: parentNodeToken },
|
|
48
|
-
});
|
|
49
|
-
if (res.code !== 0) {
|
|
50
|
-
throw new Error(res.msg);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return {
|
|
54
|
-
nodes:
|
|
55
|
-
res.data?.items?.map((n) => ({
|
|
56
|
-
node_token: n.node_token,
|
|
57
|
-
obj_token: n.obj_token,
|
|
58
|
-
obj_type: n.obj_type,
|
|
59
|
-
title: n.title,
|
|
60
|
-
has_child: n.has_child,
|
|
61
|
-
})) ?? [],
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
async function getNode(client: Lark.Client, token: string) {
|
|
66
|
-
const res = await client.wiki.space.getNode({
|
|
67
|
-
params: { token },
|
|
68
|
-
});
|
|
69
|
-
if (res.code !== 0) {
|
|
70
|
-
throw new Error(res.msg);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const node = res.data?.node;
|
|
74
|
-
return {
|
|
75
|
-
node_token: node?.node_token,
|
|
76
|
-
space_id: node?.space_id,
|
|
77
|
-
obj_token: node?.obj_token,
|
|
78
|
-
obj_type: node?.obj_type,
|
|
79
|
-
title: node?.title,
|
|
80
|
-
parent_node_token: node?.parent_node_token,
|
|
81
|
-
has_child: node?.has_child,
|
|
82
|
-
creator: node?.creator,
|
|
83
|
-
create_time: node?.node_create_time,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
async function createNode(
|
|
88
|
-
client: Lark.Client,
|
|
89
|
-
spaceId: string,
|
|
90
|
-
title: string,
|
|
91
|
-
objType?: string,
|
|
92
|
-
parentNodeToken?: string,
|
|
93
|
-
) {
|
|
94
|
-
const res = await client.wiki.spaceNode.create({
|
|
95
|
-
path: { space_id: spaceId },
|
|
96
|
-
data: {
|
|
97
|
-
obj_type: (objType as ObjType) || "docx",
|
|
98
|
-
node_type: "origin" as const,
|
|
99
|
-
title,
|
|
100
|
-
parent_node_token: parentNodeToken,
|
|
101
|
-
},
|
|
102
|
-
});
|
|
103
|
-
if (res.code !== 0) {
|
|
104
|
-
throw new Error(res.msg);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const node = res.data?.node;
|
|
108
|
-
return {
|
|
109
|
-
node_token: node?.node_token,
|
|
110
|
-
obj_token: node?.obj_token,
|
|
111
|
-
obj_type: node?.obj_type,
|
|
112
|
-
title: node?.title,
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async function moveNode(
|
|
117
|
-
client: Lark.Client,
|
|
118
|
-
spaceId: string,
|
|
119
|
-
nodeToken: string,
|
|
120
|
-
targetSpaceId?: string,
|
|
121
|
-
targetParentToken?: string,
|
|
122
|
-
) {
|
|
123
|
-
const res = await client.wiki.spaceNode.move({
|
|
124
|
-
path: { space_id: spaceId, node_token: nodeToken },
|
|
125
|
-
data: {
|
|
126
|
-
target_space_id: targetSpaceId || spaceId,
|
|
127
|
-
target_parent_token: targetParentToken,
|
|
128
|
-
},
|
|
129
|
-
});
|
|
130
|
-
if (res.code !== 0) {
|
|
131
|
-
throw new Error(res.msg);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
success: true,
|
|
136
|
-
node_token: res.data?.node?.node_token,
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
async function renameNode(client: Lark.Client, spaceId: string, nodeToken: string, title: string) {
|
|
141
|
-
const res = await client.wiki.spaceNode.updateTitle({
|
|
142
|
-
path: { space_id: spaceId, node_token: nodeToken },
|
|
143
|
-
data: { title },
|
|
144
|
-
});
|
|
145
|
-
if (res.code !== 0) {
|
|
146
|
-
throw new Error(res.msg);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return {
|
|
150
|
-
success: true,
|
|
151
|
-
node_token: nodeToken,
|
|
152
|
-
title,
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// ============ Tool Registration ============
|
|
157
|
-
|
|
158
|
-
export function registerFeishuWikiTools(api: FasedAgentPluginApi) {
|
|
159
|
-
if (!api.config) {
|
|
160
|
-
api.logger.debug?.("feishu_wiki: No config available, skipping wiki tools");
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const accounts = listEnabledFeishuAccounts(api.config);
|
|
165
|
-
if (accounts.length === 0) {
|
|
166
|
-
api.logger.debug?.("feishu_wiki: No Feishu accounts configured, skipping wiki tools");
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const toolsCfg = resolveAnyEnabledFeishuToolsConfig(accounts);
|
|
171
|
-
if (!toolsCfg.wiki) {
|
|
172
|
-
api.logger.debug?.("feishu_wiki: wiki tool disabled in config");
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
type FeishuWikiExecuteParams = FeishuWikiParams & { accountId?: string };
|
|
177
|
-
|
|
178
|
-
api.registerTool(
|
|
179
|
-
(ctx) => {
|
|
180
|
-
const defaultAccountId = ctx.agentAccountId;
|
|
181
|
-
return {
|
|
182
|
-
name: "feishu_wiki",
|
|
183
|
-
label: "Feishu Wiki",
|
|
184
|
-
description:
|
|
185
|
-
"Feishu knowledge base operations. Actions: spaces, nodes, get, create, move, rename",
|
|
186
|
-
parameters: FeishuWikiSchema,
|
|
187
|
-
async execute(_toolCallId, params) {
|
|
188
|
-
const p = params as FeishuWikiExecuteParams;
|
|
189
|
-
try {
|
|
190
|
-
const client = createFeishuToolClient({
|
|
191
|
-
api,
|
|
192
|
-
executeParams: p,
|
|
193
|
-
defaultAccountId,
|
|
194
|
-
});
|
|
195
|
-
switch (p.action) {
|
|
196
|
-
case "spaces":
|
|
197
|
-
return json(await listSpaces(client));
|
|
198
|
-
case "nodes":
|
|
199
|
-
return json(await listNodes(client, p.space_id, p.parent_node_token));
|
|
200
|
-
case "get":
|
|
201
|
-
return json(await getNode(client, p.token));
|
|
202
|
-
case "search":
|
|
203
|
-
return json({
|
|
204
|
-
error:
|
|
205
|
-
"Search is not available. Use feishu_wiki with action: 'nodes' to browse or action: 'get' to lookup by token.",
|
|
206
|
-
});
|
|
207
|
-
case "create":
|
|
208
|
-
return json(
|
|
209
|
-
await createNode(client, p.space_id, p.title, p.obj_type, p.parent_node_token),
|
|
210
|
-
);
|
|
211
|
-
case "move":
|
|
212
|
-
return json(
|
|
213
|
-
await moveNode(
|
|
214
|
-
client,
|
|
215
|
-
p.space_id,
|
|
216
|
-
p.node_token,
|
|
217
|
-
p.target_space_id,
|
|
218
|
-
p.target_parent_token,
|
|
219
|
-
),
|
|
220
|
-
);
|
|
221
|
-
case "rename":
|
|
222
|
-
return json(await renameNode(client, p.space_id, p.node_token, p.title));
|
|
223
|
-
default:
|
|
224
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- exhaustive check fallback
|
|
225
|
-
return json({ error: `Unknown action: ${(p as any).action}` });
|
|
226
|
-
}
|
|
227
|
-
} catch (err) {
|
|
228
|
-
return json({ error: err instanceof Error ? err.message : String(err) });
|
|
229
|
-
}
|
|
230
|
-
},
|
|
231
|
-
};
|
|
232
|
-
},
|
|
233
|
-
{ name: "feishu_wiki" },
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
api.logger.debug?.(`feishu_wiki: Registered feishu_wiki tool`);
|
|
237
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { FasedAgentPluginApi } from "fased/plugin-sdk";
|
|
2
|
-
import { emptyPluginConfigSchema } from "fased/plugin-sdk";
|
|
3
|
-
import { googlechatDock, googlechatPlugin } from "./src/channel.js";
|
|
4
|
-
import { handleGoogleChatWebhookRequest } from "./src/monitor.js";
|
|
5
|
-
import { setGoogleChatRuntime } from "./src/runtime.js";
|
|
6
|
-
|
|
7
|
-
const plugin = {
|
|
8
|
-
id: "googlechat",
|
|
9
|
-
name: "Google Chat",
|
|
10
|
-
description: "FasedAgent Google Chat channel plugin",
|
|
11
|
-
configSchema: emptyPluginConfigSchema(),
|
|
12
|
-
register(api: FasedAgentPluginApi) {
|
|
13
|
-
setGoogleChatRuntime(api.runtime);
|
|
14
|
-
api.registerChannel({ plugin: googlechatPlugin, dock: googlechatDock });
|
|
15
|
-
api.registerHttpHandler(handleGoogleChatWebhookRequest);
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export default plugin;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@fased/googlechat",
|
|
3
|
-
"version": "0.1.36",
|
|
4
|
-
"private": true,
|
|
5
|
-
"description": "FasedAgent Google Chat channel plugin",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"dependencies": {
|
|
8
|
-
"google-auth-library": "^10.6.1"
|
|
9
|
-
},
|
|
10
|
-
"peerDependencies": {
|
|
11
|
-
"@fased/fased": "^0.1.36"
|
|
12
|
-
},
|
|
13
|
-
"fased": {
|
|
14
|
-
"extensions": [
|
|
15
|
-
"./index.ts"
|
|
16
|
-
],
|
|
17
|
-
"channel": {
|
|
18
|
-
"id": "googlechat",
|
|
19
|
-
"label": "Google Chat",
|
|
20
|
-
"selectionLabel": "Google Chat (Chat API)",
|
|
21
|
-
"detailLabel": "Google Chat",
|
|
22
|
-
"docsPath": "/channels/googlechat",
|
|
23
|
-
"docsLabel": "googlechat",
|
|
24
|
-
"blurb": "Google Workspace Chat app via HTTP webhooks.",
|
|
25
|
-
"aliases": [
|
|
26
|
-
"gchat",
|
|
27
|
-
"google-chat"
|
|
28
|
-
],
|
|
29
|
-
"order": 55
|
|
30
|
-
},
|
|
31
|
-
"install": {
|
|
32
|
-
"npmSpec": "@fased/googlechat",
|
|
33
|
-
"localPath": "extensions/googlechat",
|
|
34
|
-
"defaultChoice": "local"
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import type { FasedAgentConfig } from "fased/plugin-sdk";
|
|
2
|
-
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "fased/plugin-sdk/account-id";
|
|
3
|
-
import type { GoogleChatAccountConfig } from "./types.config.js";
|
|
4
|
-
|
|
5
|
-
export type GoogleChatCredentialSource = "file" | "inline" | "env" | "none";
|
|
6
|
-
|
|
7
|
-
export type ResolvedGoogleChatAccount = {
|
|
8
|
-
accountId: string;
|
|
9
|
-
name?: string;
|
|
10
|
-
enabled: boolean;
|
|
11
|
-
config: GoogleChatAccountConfig;
|
|
12
|
-
credentialSource: GoogleChatCredentialSource;
|
|
13
|
-
credentials?: Record<string, unknown>;
|
|
14
|
-
credentialsFile?: string;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const ENV_SERVICE_ACCOUNT = "GOOGLE_CHAT_SERVICE_ACCOUNT";
|
|
18
|
-
const ENV_SERVICE_ACCOUNT_FILE = "GOOGLE_CHAT_SERVICE_ACCOUNT_FILE";
|
|
19
|
-
|
|
20
|
-
function listConfiguredAccountIds(cfg: FasedAgentConfig): string[] {
|
|
21
|
-
const accounts = cfg.channels?.["googlechat"]?.accounts;
|
|
22
|
-
if (!accounts || typeof accounts !== "object") {
|
|
23
|
-
return [];
|
|
24
|
-
}
|
|
25
|
-
return Object.keys(accounts).filter(Boolean);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function listGoogleChatAccountIds(cfg: FasedAgentConfig): string[] {
|
|
29
|
-
const ids = listConfiguredAccountIds(cfg);
|
|
30
|
-
if (ids.length === 0) {
|
|
31
|
-
return [DEFAULT_ACCOUNT_ID];
|
|
32
|
-
}
|
|
33
|
-
return ids.toSorted((a, b) => a.localeCompare(b));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function resolveDefaultGoogleChatAccountId(cfg: FasedAgentConfig): string {
|
|
37
|
-
const channel = cfg.channels?.["googlechat"];
|
|
38
|
-
if (channel?.defaultAccount?.trim()) {
|
|
39
|
-
return channel.defaultAccount.trim();
|
|
40
|
-
}
|
|
41
|
-
const ids = listGoogleChatAccountIds(cfg);
|
|
42
|
-
if (ids.includes(DEFAULT_ACCOUNT_ID)) {
|
|
43
|
-
return DEFAULT_ACCOUNT_ID;
|
|
44
|
-
}
|
|
45
|
-
return ids[0] ?? DEFAULT_ACCOUNT_ID;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function resolveAccountConfig(
|
|
49
|
-
cfg: FasedAgentConfig,
|
|
50
|
-
accountId: string,
|
|
51
|
-
): GoogleChatAccountConfig | undefined {
|
|
52
|
-
const accounts = cfg.channels?.["googlechat"]?.accounts;
|
|
53
|
-
if (!accounts || typeof accounts !== "object") {
|
|
54
|
-
return undefined;
|
|
55
|
-
}
|
|
56
|
-
return accounts[accountId];
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function mergeGoogleChatAccountConfig(
|
|
60
|
-
cfg: FasedAgentConfig,
|
|
61
|
-
accountId: string,
|
|
62
|
-
): GoogleChatAccountConfig {
|
|
63
|
-
const raw = cfg.channels?.["googlechat"] ?? {};
|
|
64
|
-
const { accounts: _ignored, defaultAccount: _ignored2, ...base } = raw;
|
|
65
|
-
const account = resolveAccountConfig(cfg, accountId) ?? {};
|
|
66
|
-
return { ...base, ...account } as GoogleChatAccountConfig;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function parseServiceAccount(value: unknown): Record<string, unknown> | null {
|
|
70
|
-
if (value && typeof value === "object") {
|
|
71
|
-
return value as Record<string, unknown>;
|
|
72
|
-
}
|
|
73
|
-
if (typeof value !== "string") {
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
const trimmed = value.trim();
|
|
77
|
-
if (!trimmed) {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
try {
|
|
81
|
-
return JSON.parse(trimmed) as Record<string, unknown>;
|
|
82
|
-
} catch {
|
|
83
|
-
return null;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function resolveCredentialsFromConfig(params: {
|
|
88
|
-
accountId: string;
|
|
89
|
-
account: GoogleChatAccountConfig;
|
|
90
|
-
}): {
|
|
91
|
-
credentials?: Record<string, unknown>;
|
|
92
|
-
credentialsFile?: string;
|
|
93
|
-
source: GoogleChatCredentialSource;
|
|
94
|
-
} {
|
|
95
|
-
const { account, accountId } = params;
|
|
96
|
-
const inline = parseServiceAccount(account.serviceAccount);
|
|
97
|
-
if (inline) {
|
|
98
|
-
return { credentials: inline, source: "inline" };
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const file = account.serviceAccountFile?.trim();
|
|
102
|
-
if (file) {
|
|
103
|
-
return { credentialsFile: file, source: "file" };
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (accountId === DEFAULT_ACCOUNT_ID) {
|
|
107
|
-
const envJson = process.env[ENV_SERVICE_ACCOUNT];
|
|
108
|
-
const envInline = parseServiceAccount(envJson);
|
|
109
|
-
if (envInline) {
|
|
110
|
-
return { credentials: envInline, source: "env" };
|
|
111
|
-
}
|
|
112
|
-
const envFile = process.env[ENV_SERVICE_ACCOUNT_FILE]?.trim();
|
|
113
|
-
if (envFile) {
|
|
114
|
-
return { credentialsFile: envFile, source: "env" };
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return { source: "none" };
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export function resolveGoogleChatAccount(params: {
|
|
122
|
-
cfg: FasedAgentConfig;
|
|
123
|
-
accountId?: string | null;
|
|
124
|
-
}): ResolvedGoogleChatAccount {
|
|
125
|
-
const accountId = normalizeAccountId(params.accountId);
|
|
126
|
-
const baseEnabled = params.cfg.channels?.["googlechat"]?.enabled !== false;
|
|
127
|
-
const merged = mergeGoogleChatAccountConfig(params.cfg, accountId);
|
|
128
|
-
const accountEnabled = merged.enabled !== false;
|
|
129
|
-
const enabled = baseEnabled && accountEnabled;
|
|
130
|
-
const credentials = resolveCredentialsFromConfig({ accountId, account: merged });
|
|
131
|
-
|
|
132
|
-
return {
|
|
133
|
-
accountId,
|
|
134
|
-
name: merged.name?.trim() || undefined,
|
|
135
|
-
enabled,
|
|
136
|
-
config: merged,
|
|
137
|
-
credentialSource: credentials.source,
|
|
138
|
-
credentials: credentials.credentials,
|
|
139
|
-
credentialsFile: credentials.credentialsFile,
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
export function listEnabledGoogleChatAccounts(cfg: FasedAgentConfig): ResolvedGoogleChatAccount[] {
|
|
144
|
-
return listGoogleChatAccountIds(cfg)
|
|
145
|
-
.map((accountId) => resolveGoogleChatAccount({ cfg, accountId }))
|
|
146
|
-
.filter((account) => account.enabled);
|
|
147
|
-
}
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ChannelMessageActionAdapter,
|
|
3
|
-
ChannelMessageActionName,
|
|
4
|
-
FasedAgentConfig,
|
|
5
|
-
} from "fased/plugin-sdk";
|
|
6
|
-
import {
|
|
7
|
-
createActionGate,
|
|
8
|
-
extractToolSend,
|
|
9
|
-
jsonResult,
|
|
10
|
-
readNumberParam,
|
|
11
|
-
readReactionParams,
|
|
12
|
-
readStringParam,
|
|
13
|
-
} from "fased/plugin-sdk";
|
|
14
|
-
import { listEnabledGoogleChatAccounts, resolveGoogleChatAccount } from "./accounts.js";
|
|
15
|
-
import {
|
|
16
|
-
createGoogleChatReaction,
|
|
17
|
-
deleteGoogleChatReaction,
|
|
18
|
-
listGoogleChatReactions,
|
|
19
|
-
sendGoogleChatMessage,
|
|
20
|
-
uploadGoogleChatAttachment,
|
|
21
|
-
} from "./api.js";
|
|
22
|
-
import { getGoogleChatRuntime } from "./runtime.js";
|
|
23
|
-
import { resolveGoogleChatOutboundSpace } from "./targets.js";
|
|
24
|
-
|
|
25
|
-
const providerId = "googlechat";
|
|
26
|
-
|
|
27
|
-
function listEnabledAccounts(cfg: FasedAgentConfig) {
|
|
28
|
-
return listEnabledGoogleChatAccounts(cfg).filter(
|
|
29
|
-
(account) => account.enabled && account.credentialSource !== "none",
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function isReactionsEnabled(
|
|
34
|
-
accounts: ReturnType<typeof listEnabledAccounts>,
|
|
35
|
-
cfg: FasedAgentConfig,
|
|
36
|
-
) {
|
|
37
|
-
for (const account of accounts) {
|
|
38
|
-
const gate = createActionGate(
|
|
39
|
-
(account.config.actions ??
|
|
40
|
-
(cfg.channels?.["googlechat"] as { actions?: unknown })?.actions) as Record<
|
|
41
|
-
string,
|
|
42
|
-
boolean | undefined
|
|
43
|
-
>,
|
|
44
|
-
);
|
|
45
|
-
if (gate("reactions")) {
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function resolveAppUserNames(account: { config: { botUser?: string | null } }) {
|
|
53
|
-
return new Set(["users/app", account.config.botUser?.trim()].filter(Boolean) as string[]);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export const googlechatMessageActions: ChannelMessageActionAdapter = {
|
|
57
|
-
listActions: ({ cfg }) => {
|
|
58
|
-
const accounts = listEnabledAccounts(cfg);
|
|
59
|
-
if (accounts.length === 0) {
|
|
60
|
-
return [];
|
|
61
|
-
}
|
|
62
|
-
const actions = new Set<ChannelMessageActionName>([]);
|
|
63
|
-
actions.add("send");
|
|
64
|
-
if (isReactionsEnabled(accounts, cfg)) {
|
|
65
|
-
actions.add("react");
|
|
66
|
-
actions.add("reactions");
|
|
67
|
-
}
|
|
68
|
-
return Array.from(actions);
|
|
69
|
-
},
|
|
70
|
-
extractToolSend: ({ args }) => {
|
|
71
|
-
return extractToolSend(args, "sendMessage");
|
|
72
|
-
},
|
|
73
|
-
handleAction: async ({ action, params, cfg, accountId }) => {
|
|
74
|
-
const account = resolveGoogleChatAccount({
|
|
75
|
-
cfg: cfg,
|
|
76
|
-
accountId,
|
|
77
|
-
});
|
|
78
|
-
if (account.credentialSource === "none") {
|
|
79
|
-
throw new Error("Google Chat credentials are missing.");
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (action === "send") {
|
|
83
|
-
const to = readStringParam(params, "to", { required: true });
|
|
84
|
-
const content = readStringParam(params, "message", {
|
|
85
|
-
required: true,
|
|
86
|
-
allowEmpty: true,
|
|
87
|
-
});
|
|
88
|
-
const mediaUrl = readStringParam(params, "media", { trim: false });
|
|
89
|
-
const threadId = readStringParam(params, "threadId") ?? readStringParam(params, "replyTo");
|
|
90
|
-
const space = await resolveGoogleChatOutboundSpace({ account, target: to });
|
|
91
|
-
|
|
92
|
-
if (mediaUrl) {
|
|
93
|
-
const core = getGoogleChatRuntime();
|
|
94
|
-
const maxBytes = (account.config.mediaMaxMb ?? 20) * 1024 * 1024;
|
|
95
|
-
const loaded = await core.channel.media.fetchRemoteMedia({ url: mediaUrl, maxBytes });
|
|
96
|
-
const upload = await uploadGoogleChatAttachment({
|
|
97
|
-
account,
|
|
98
|
-
space,
|
|
99
|
-
filename: loaded.fileName ?? "attachment",
|
|
100
|
-
buffer: loaded.buffer,
|
|
101
|
-
contentType: loaded.contentType,
|
|
102
|
-
});
|
|
103
|
-
await sendGoogleChatMessage({
|
|
104
|
-
account,
|
|
105
|
-
space,
|
|
106
|
-
text: content,
|
|
107
|
-
thread: threadId ?? undefined,
|
|
108
|
-
attachments: upload.attachmentUploadToken
|
|
109
|
-
? [
|
|
110
|
-
{
|
|
111
|
-
attachmentUploadToken: upload.attachmentUploadToken,
|
|
112
|
-
contentName: loaded.fileName,
|
|
113
|
-
},
|
|
114
|
-
]
|
|
115
|
-
: undefined,
|
|
116
|
-
});
|
|
117
|
-
return jsonResult({ ok: true, to: space });
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
await sendGoogleChatMessage({
|
|
121
|
-
account,
|
|
122
|
-
space,
|
|
123
|
-
text: content,
|
|
124
|
-
thread: threadId ?? undefined,
|
|
125
|
-
});
|
|
126
|
-
return jsonResult({ ok: true, to: space });
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (action === "react") {
|
|
130
|
-
const messageName = readStringParam(params, "messageId", { required: true });
|
|
131
|
-
const { emoji, remove, isEmpty } = readReactionParams(params, {
|
|
132
|
-
removeErrorMessage: "Emoji is required to remove a Google Chat reaction.",
|
|
133
|
-
});
|
|
134
|
-
if (remove || isEmpty) {
|
|
135
|
-
const reactions = await listGoogleChatReactions({ account, messageName });
|
|
136
|
-
const appUsers = resolveAppUserNames(account);
|
|
137
|
-
const toRemove = reactions.filter((reaction) => {
|
|
138
|
-
const userName = reaction.user?.name?.trim();
|
|
139
|
-
if (appUsers.size > 0 && !appUsers.has(userName ?? "")) {
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
142
|
-
if (emoji) {
|
|
143
|
-
return reaction.emoji?.unicode === emoji;
|
|
144
|
-
}
|
|
145
|
-
return true;
|
|
146
|
-
});
|
|
147
|
-
for (const reaction of toRemove) {
|
|
148
|
-
if (!reaction.name) {
|
|
149
|
-
continue;
|
|
150
|
-
}
|
|
151
|
-
await deleteGoogleChatReaction({ account, reactionName: reaction.name });
|
|
152
|
-
}
|
|
153
|
-
return jsonResult({ ok: true, removed: toRemove.length });
|
|
154
|
-
}
|
|
155
|
-
const reaction = await createGoogleChatReaction({
|
|
156
|
-
account,
|
|
157
|
-
messageName,
|
|
158
|
-
emoji,
|
|
159
|
-
});
|
|
160
|
-
return jsonResult({ ok: true, reaction });
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
if (action === "reactions") {
|
|
164
|
-
const messageName = readStringParam(params, "messageId", { required: true });
|
|
165
|
-
const limit = readNumberParam(params, "limit", { integer: true });
|
|
166
|
-
const reactions = await listGoogleChatReactions({
|
|
167
|
-
account,
|
|
168
|
-
messageName,
|
|
169
|
-
limit: limit ?? undefined,
|
|
170
|
-
});
|
|
171
|
-
return jsonResult({ ok: true, reactions });
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
throw new Error(`Action ${action} is not supported for provider ${providerId}.`);
|
|
175
|
-
},
|
|
176
|
-
};
|