MCPcopy Create free account
hub / github.com/apache/maka / FeishuBotBridge

Class FeishuBotBridge

packages/runtime/src/bots/feishu-bridge.ts:58–229  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

56
57/** Feishu/Lark long-connection bridge backed by the official Channel API. */
58export class FeishuBotBridge extends BaseBotAdapter implements SendCapable {
59 private channel: LarkChannel | null = null;
60 private unsubscribe: Array<() => void> = [];
61 private explicitlyStopped = false;
62
63 constructor(settings: BotChannelSettings) {
64 super('feishu', settings);
65 }
66
67 async start(): Promise<void> {
68 if (this.running) return;
69 if (!this.settings.enabled) {
70 this.reason = 'disabled';
71 this.readiness = 'scaffolded';
72 return;
73 }
74 const appId = this.settings.appId?.trim() ?? '';
75 const appSecret = this.settings.appSecret?.trim() || this.settings.token.trim();
76 if (!appId || !appSecret) {
77 this.reason = 'missing-feishu-credentials';
78 this.readiness = 'scaffolded';
79 this.emitStatusChange();
80 return;
81 }
82
83 this.explicitlyStopped = false;
84 const isLark = this.settings.domain?.trim() === 'larksuite.com';
85 const channel = createLarkChannel({
86 appId,
87 appSecret,
88 domain: isLark ? Domain.Lark : Domain.Feishu,
89 transport: 'websocket',
90 source: 'maka',
91 loggerLevel: LoggerLevel.error,
92 handshakeTimeoutMs: HANDSHAKE_TIMEOUT_MS,
93 policy: {
94 dmMode: this.settings.allowedUserIds?.length ? 'allowlist' : 'open',
95 dmAllowlist: [...(this.settings.allowedUserIds ?? [])],
96 requireMention: false,
97 },
98 });
99 this.channel = channel;
100 this.wire(channel, appId);
101
102 try {
103 await channel.connect();
104 if (this.explicitlyStopped || this.channel !== channel) return;
105 this.startedAt = Date.now();
106 this.markConnected(channel, appId);
107 } catch (error) {
108 if (this.explicitlyStopped || this.channel !== channel) return;
109 this.running = false;
110 this.reason = generalizedErrorMessage(error);
111 this.readiness = 'configured';
112 this.emitStatusChange();
113 await this.disconnectChannel(channel);
114 }
115 }

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected