@symerian/symi 3.0.20 → 3.0.21

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.
Files changed (52) hide show
  1. package/dist/{audio-preflight-BaCdNfrk.js → audio-preflight-D7BVT-ls.js} +4 -4
  2. package/dist/build-info.json +3 -3
  3. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  4. package/dist/{chrome-UfmVM0xR.js → chrome-B5CO2vB5.js} +7 -7
  5. package/dist/{deliver-BqXdac6W.js → deliver-CrwjsDwv.js} +1 -1
  6. package/dist/extensionAPI.js +7 -7
  7. package/dist/{image-DIWsXYcW.js → image-Csu7WcLW.js} +1 -1
  8. package/dist/{manager-DW3SxcPr.js → manager-BkkVjTO8.js} +1 -1
  9. package/dist/{pi-embedded-BNch0U5F.js → pi-embedded-Dhp64z5l.js} +16 -16
  10. package/dist/{pi-embedded-helpers-IkHl02JF.js → pi-embedded-helpers-840E4hop.js} +4 -4
  11. package/dist/{pw-ai-nMkA-oDJ.js → pw-ai-CBgJf_RR.js} +1 -1
  12. package/dist/{runner-DNEC58JI.js → runner-BbFKo1ne.js} +1 -1
  13. package/dist/{synthesis-BWAr0sZ9.js → synthesis-DoEM0E8_.js} +7 -7
  14. package/dist/{web-7a-m_UxL.js → web-BYXJn-Ps.js} +7 -7
  15. package/package.json +1 -1
  16. package/extensions/imessage/index.ts +0 -17
  17. package/extensions/imessage/node_modules/.bin/symi +0 -21
  18. package/extensions/imessage/package.json +0 -15
  19. package/extensions/imessage/src/channel.outbound.test.ts +0 -66
  20. package/extensions/imessage/src/channel.ts +0 -298
  21. package/extensions/imessage/src/runtime.ts +0 -14
  22. package/extensions/imessage/symi.plugin.json +0 -9
  23. package/extensions/line/index.ts +0 -19
  24. package/extensions/line/node_modules/.bin/symi +0 -21
  25. package/extensions/line/package.json +0 -30
  26. package/extensions/line/src/card-command.ts +0 -344
  27. package/extensions/line/src/channel.logout.test.ts +0 -133
  28. package/extensions/line/src/channel.sendPayload.test.ts +0 -312
  29. package/extensions/line/src/channel.startup.test.ts +0 -133
  30. package/extensions/line/src/channel.ts +0 -801
  31. package/extensions/line/src/runtime.ts +0 -14
  32. package/extensions/line/symi.plugin.json +0 -9
  33. package/extensions/signal/index.ts +0 -17
  34. package/extensions/signal/node_modules/.bin/symi +0 -21
  35. package/extensions/signal/package.json +0 -15
  36. package/extensions/signal/src/channel.ts +0 -302
  37. package/extensions/signal/src/runtime.ts +0 -14
  38. package/extensions/signal/symi.plugin.json +0 -9
  39. package/extensions/telegram/index.ts +0 -17
  40. package/extensions/telegram/node_modules/.bin/symi +0 -21
  41. package/extensions/telegram/package.json +0 -15
  42. package/extensions/telegram/src/channel.test.ts +0 -125
  43. package/extensions/telegram/src/channel.ts +0 -560
  44. package/extensions/telegram/src/runtime.ts +0 -14
  45. package/extensions/telegram/symi.plugin.json +0 -9
  46. package/extensions/whatsapp/index.ts +0 -17
  47. package/extensions/whatsapp/node_modules/.bin/symi +0 -21
  48. package/extensions/whatsapp/package.json +0 -15
  49. package/extensions/whatsapp/src/channel.ts +0 -465
  50. package/extensions/whatsapp/src/resolve-target.test.ts +0 -170
  51. package/extensions/whatsapp/src/runtime.ts +0 -14
  52. package/extensions/whatsapp/symi.plugin.json +0 -9
@@ -1,560 +0,0 @@
1
- import {
2
- applyAccountNameToChannelSection,
3
- buildChannelConfigSchema,
4
- collectTelegramStatusIssues,
5
- DEFAULT_ACCOUNT_ID,
6
- deleteAccountFromConfigSection,
7
- formatPairingApproveHint,
8
- getChatChannelMeta,
9
- listTelegramAccountIds,
10
- listTelegramDirectoryGroupsFromConfig,
11
- listTelegramDirectoryPeersFromConfig,
12
- looksLikeTelegramTargetId,
13
- migrateBaseNameToDefaultAccount,
14
- normalizeAccountId,
15
- normalizeTelegramMessagingTarget,
16
- PAIRING_APPROVED_MESSAGE,
17
- parseTelegramReplyToMessageId,
18
- parseTelegramThreadId,
19
- resolveDefaultTelegramAccountId,
20
- resolveTelegramAccount,
21
- resolveTelegramGroupRequireMention,
22
- resolveTelegramGroupToolPolicy,
23
- setAccountEnabledInConfigSection,
24
- telegramOnboardingAdapter,
25
- TelegramConfigSchema,
26
- type ChannelMessageActionAdapter,
27
- type ChannelPlugin,
28
- type SymiConfig,
29
- type ResolvedTelegramAccount,
30
- type TelegramProbe,
31
- } from "symi/plugin-sdk";
32
- import { getTelegramRuntime } from "./runtime.js";
33
-
34
- const meta = getChatChannelMeta("telegram");
35
-
36
- function findTelegramTokenOwnerAccountId(params: {
37
- cfg: SymiConfig;
38
- accountId: string;
39
- }): string | null {
40
- const normalizedAccountId = normalizeAccountId(params.accountId);
41
- const tokenOwners = new Map<string, string>();
42
- for (const id of listTelegramAccountIds(params.cfg)) {
43
- const account = resolveTelegramAccount({ cfg: params.cfg, accountId: id });
44
- const token = account.token.trim();
45
- if (!token) {
46
- continue;
47
- }
48
- const ownerAccountId = tokenOwners.get(token);
49
- if (!ownerAccountId) {
50
- tokenOwners.set(token, account.accountId);
51
- continue;
52
- }
53
- if (account.accountId === normalizedAccountId) {
54
- return ownerAccountId;
55
- }
56
- }
57
- return null;
58
- }
59
-
60
- function formatDuplicateTelegramTokenReason(params: {
61
- accountId: string;
62
- ownerAccountId: string;
63
- }): string {
64
- return (
65
- `Duplicate Telegram bot token: account "${params.accountId}" shares a token with ` +
66
- `account "${params.ownerAccountId}". Keep one owner account per bot token.`
67
- );
68
- }
69
-
70
- const telegramMessageActions: ChannelMessageActionAdapter = {
71
- listActions: (ctx) =>
72
- getTelegramRuntime().channel.telegram.messageActions?.listActions?.(ctx) ?? [],
73
- extractToolSend: (ctx) =>
74
- getTelegramRuntime().channel.telegram.messageActions?.extractToolSend?.(ctx) ?? null,
75
- handleAction: async (ctx) => {
76
- const ma = getTelegramRuntime().channel.telegram.messageActions;
77
- if (!ma?.handleAction) {
78
- throw new Error("Telegram message actions not available");
79
- }
80
- return ma.handleAction(ctx);
81
- },
82
- };
83
-
84
- export const telegramPlugin: ChannelPlugin<ResolvedTelegramAccount, TelegramProbe> = {
85
- id: "telegram",
86
- meta: {
87
- ...meta,
88
- quickstartAllowFrom: true,
89
- },
90
- onboarding: telegramOnboardingAdapter,
91
- pairing: {
92
- idLabel: "telegramUserId",
93
- normalizeAllowEntry: (entry) => entry.replace(/^(telegram|tg):/i, ""),
94
- notifyApproval: async ({ cfg, id }) => {
95
- const { token } = getTelegramRuntime().channel.telegram.resolveTelegramToken(cfg);
96
- if (!token) {
97
- throw new Error("telegram token not configured");
98
- }
99
- await getTelegramRuntime().channel.telegram.sendMessageTelegram(
100
- id,
101
- PAIRING_APPROVED_MESSAGE,
102
- {
103
- token,
104
- },
105
- );
106
- },
107
- },
108
- capabilities: {
109
- chatTypes: ["direct", "group", "channel", "thread"],
110
- reactions: true,
111
- threads: true,
112
- media: true,
113
- polls: true,
114
- nativeCommands: true,
115
- blockStreaming: true,
116
- },
117
- reload: { configPrefixes: ["channels.telegram"] },
118
- configSchema: buildChannelConfigSchema(TelegramConfigSchema),
119
- config: {
120
- listAccountIds: (cfg) => listTelegramAccountIds(cfg),
121
- resolveAccount: (cfg, accountId) => resolveTelegramAccount({ cfg, accountId }),
122
- defaultAccountId: (cfg) => resolveDefaultTelegramAccountId(cfg),
123
- setAccountEnabled: ({ cfg, accountId, enabled }) =>
124
- setAccountEnabledInConfigSection({
125
- cfg,
126
- sectionKey: "telegram",
127
- accountId,
128
- enabled,
129
- allowTopLevel: true,
130
- }),
131
- deleteAccount: ({ cfg, accountId }) =>
132
- deleteAccountFromConfigSection({
133
- cfg,
134
- sectionKey: "telegram",
135
- accountId,
136
- clearBaseFields: ["botToken", "tokenFile", "name"],
137
- }),
138
- isConfigured: (account, cfg) => {
139
- if (!account.token?.trim()) {
140
- return false;
141
- }
142
- return !findTelegramTokenOwnerAccountId({ cfg, accountId: account.accountId });
143
- },
144
- unconfiguredReason: (account, cfg) => {
145
- if (!account.token?.trim()) {
146
- return "not configured";
147
- }
148
- const ownerAccountId = findTelegramTokenOwnerAccountId({ cfg, accountId: account.accountId });
149
- if (!ownerAccountId) {
150
- return "not configured";
151
- }
152
- return formatDuplicateTelegramTokenReason({
153
- accountId: account.accountId,
154
- ownerAccountId,
155
- });
156
- },
157
- describeAccount: (account, cfg) => ({
158
- accountId: account.accountId,
159
- name: account.name,
160
- enabled: account.enabled,
161
- configured:
162
- Boolean(account.token?.trim()) &&
163
- !findTelegramTokenOwnerAccountId({ cfg, accountId: account.accountId }),
164
- tokenSource: account.tokenSource,
165
- }),
166
- resolveAllowFrom: ({ cfg, accountId }) =>
167
- (resolveTelegramAccount({ cfg, accountId }).config.allowFrom ?? []).map((entry) =>
168
- String(entry),
169
- ),
170
- formatAllowFrom: ({ allowFrom }) =>
171
- allowFrom
172
- .map((entry) => String(entry).trim())
173
- .filter(Boolean)
174
- .map((entry) => entry.replace(/^(telegram|tg):/i, ""))
175
- .map((entry) => entry.toLowerCase()),
176
- resolveDefaultTo: ({ cfg, accountId }) => {
177
- const val = resolveTelegramAccount({ cfg, accountId }).config.defaultTo;
178
- return val != null ? String(val) : undefined;
179
- },
180
- },
181
- security: {
182
- resolveDmPolicy: ({ cfg, accountId, account }) => {
183
- const resolvedAccountId = accountId ?? account.accountId ?? DEFAULT_ACCOUNT_ID;
184
- const useAccountPath = Boolean(cfg.channels?.telegram?.accounts?.[resolvedAccountId]);
185
- const basePath = useAccountPath
186
- ? `channels.telegram.accounts.${resolvedAccountId}.`
187
- : "channels.telegram.";
188
- return {
189
- policy: account.config.dmPolicy ?? "pairing",
190
- allowFrom: account.config.allowFrom ?? [],
191
- policyPath: `${basePath}dmPolicy`,
192
- allowFromPath: basePath,
193
- approveHint: formatPairingApproveHint("telegram"),
194
- normalizeEntry: (raw) => raw.replace(/^(telegram|tg):/i, ""),
195
- };
196
- },
197
- collectWarnings: ({ account, cfg }) => {
198
- const defaultGroupPolicy = cfg.channels?.defaults?.groupPolicy;
199
- const groupPolicy = account.config.groupPolicy ?? defaultGroupPolicy ?? "allowlist";
200
- if (groupPolicy !== "open") {
201
- return [];
202
- }
203
- const groupAllowlistConfigured =
204
- account.config.groups && Object.keys(account.config.groups).length > 0;
205
- if (groupAllowlistConfigured) {
206
- return [
207
- `- Telegram groups: groupPolicy="open" allows any member in allowed groups to trigger (mention-gated). Set channels.telegram.groupPolicy="allowlist" + channels.telegram.groupAllowFrom to restrict senders.`,
208
- ];
209
- }
210
- return [
211
- `- Telegram groups: groupPolicy="open" with no channels.telegram.groups allowlist; any group can add + ping (mention-gated). Set channels.telegram.groupPolicy="allowlist" + channels.telegram.groupAllowFrom or configure channels.telegram.groups.`,
212
- ];
213
- },
214
- },
215
- groups: {
216
- resolveRequireMention: resolveTelegramGroupRequireMention,
217
- resolveToolPolicy: resolveTelegramGroupToolPolicy,
218
- },
219
- threading: {
220
- resolveReplyToMode: ({ cfg }) => cfg.channels?.telegram?.replyToMode ?? "off",
221
- },
222
- messaging: {
223
- normalizeTarget: normalizeTelegramMessagingTarget,
224
- targetResolver: {
225
- looksLikeId: looksLikeTelegramTargetId,
226
- hint: "<chatId>",
227
- },
228
- },
229
- directory: {
230
- self: async () => null,
231
- listPeers: async (params) => listTelegramDirectoryPeersFromConfig(params),
232
- listGroups: async (params) => listTelegramDirectoryGroupsFromConfig(params),
233
- },
234
- actions: telegramMessageActions,
235
- setup: {
236
- resolveAccountId: ({ accountId }) => normalizeAccountId(accountId),
237
- applyAccountName: ({ cfg, accountId, name }) =>
238
- applyAccountNameToChannelSection({
239
- cfg,
240
- channelKey: "telegram",
241
- accountId,
242
- name,
243
- }),
244
- validateInput: ({ accountId, input }) => {
245
- if (input.useEnv && accountId !== DEFAULT_ACCOUNT_ID) {
246
- return "TELEGRAM_BOT_TOKEN can only be used for the default account.";
247
- }
248
- if (!input.useEnv && !input.token && !input.tokenFile) {
249
- return "Telegram requires token or --token-file (or --use-env).";
250
- }
251
- return null;
252
- },
253
- applyAccountConfig: ({ cfg, accountId, input }) => {
254
- const namedConfig = applyAccountNameToChannelSection({
255
- cfg,
256
- channelKey: "telegram",
257
- accountId,
258
- name: input.name,
259
- });
260
- const next =
261
- accountId !== DEFAULT_ACCOUNT_ID
262
- ? migrateBaseNameToDefaultAccount({
263
- cfg: namedConfig,
264
- channelKey: "telegram",
265
- })
266
- : namedConfig;
267
- if (accountId === DEFAULT_ACCOUNT_ID) {
268
- return {
269
- ...next,
270
- channels: {
271
- ...next.channels,
272
- telegram: {
273
- ...next.channels?.telegram,
274
- enabled: true,
275
- ...(input.useEnv
276
- ? {}
277
- : input.tokenFile
278
- ? { tokenFile: input.tokenFile }
279
- : input.token
280
- ? { botToken: input.token }
281
- : {}),
282
- },
283
- },
284
- };
285
- }
286
- return {
287
- ...next,
288
- channels: {
289
- ...next.channels,
290
- telegram: {
291
- ...next.channels?.telegram,
292
- enabled: true,
293
- accounts: {
294
- ...next.channels?.telegram?.accounts,
295
- [accountId]: {
296
- ...next.channels?.telegram?.accounts?.[accountId],
297
- enabled: true,
298
- ...(input.tokenFile
299
- ? { tokenFile: input.tokenFile }
300
- : input.token
301
- ? { botToken: input.token }
302
- : {}),
303
- },
304
- },
305
- },
306
- },
307
- };
308
- },
309
- },
310
- outbound: {
311
- deliveryMode: "direct",
312
- chunker: (text, limit) => getTelegramRuntime().channel.text.chunkMarkdownText(text, limit),
313
- chunkerMode: "markdown",
314
- textChunkLimit: 4000,
315
- pollMaxOptions: 10,
316
- sendText: async ({ to, text, accountId, deps, replyToId, threadId, silent }) => {
317
- const send = deps?.sendTelegram ?? getTelegramRuntime().channel.telegram.sendMessageTelegram;
318
- const replyToMessageId = parseTelegramReplyToMessageId(replyToId);
319
- const messageThreadId = parseTelegramThreadId(threadId);
320
- const result = await send(to, text, {
321
- verbose: false,
322
- messageThreadId,
323
- replyToMessageId,
324
- accountId: accountId ?? undefined,
325
- silent: silent ?? undefined,
326
- });
327
- return { channel: "telegram", ...result };
328
- },
329
- sendMedia: async ({ to, text, mediaUrl, accountId, deps, replyToId, threadId, silent }) => {
330
- const send = deps?.sendTelegram ?? getTelegramRuntime().channel.telegram.sendMessageTelegram;
331
- const replyToMessageId = parseTelegramReplyToMessageId(replyToId);
332
- const messageThreadId = parseTelegramThreadId(threadId);
333
- const result = await send(to, text, {
334
- verbose: false,
335
- mediaUrl,
336
- messageThreadId,
337
- replyToMessageId,
338
- accountId: accountId ?? undefined,
339
- silent: silent ?? undefined,
340
- });
341
- return { channel: "telegram", ...result };
342
- },
343
- sendPoll: async ({ to, poll, accountId, threadId, silent, isAnonymous }) =>
344
- await getTelegramRuntime().channel.telegram.sendPollTelegram(to, poll, {
345
- accountId: accountId ?? undefined,
346
- messageThreadId: parseTelegramThreadId(threadId),
347
- silent: silent ?? undefined,
348
- isAnonymous: isAnonymous ?? undefined,
349
- }),
350
- },
351
- status: {
352
- defaultRuntime: {
353
- accountId: DEFAULT_ACCOUNT_ID,
354
- running: false,
355
- lastStartAt: null,
356
- lastStopAt: null,
357
- lastError: null,
358
- },
359
- collectStatusIssues: collectTelegramStatusIssues,
360
- buildChannelSummary: ({ snapshot }) => ({
361
- configured: snapshot.configured ?? false,
362
- tokenSource: snapshot.tokenSource ?? "none",
363
- running: snapshot.running ?? false,
364
- mode: snapshot.mode ?? null,
365
- lastStartAt: snapshot.lastStartAt ?? null,
366
- lastStopAt: snapshot.lastStopAt ?? null,
367
- lastError: snapshot.lastError ?? null,
368
- probe: snapshot.probe,
369
- lastProbeAt: snapshot.lastProbeAt ?? null,
370
- }),
371
- probeAccount: async ({ account, timeoutMs }) =>
372
- getTelegramRuntime().channel.telegram.probeTelegram(
373
- account.token,
374
- timeoutMs,
375
- account.config.proxy,
376
- ),
377
- auditAccount: async ({ account, timeoutMs, probe, cfg }) => {
378
- const groups =
379
- cfg.channels?.telegram?.accounts?.[account.accountId]?.groups ??
380
- cfg.channels?.telegram?.groups;
381
- const { groupIds, unresolvedGroups, hasWildcardUnmentionedGroups } =
382
- getTelegramRuntime().channel.telegram.collectUnmentionedGroupIds(groups);
383
- if (!groupIds.length && unresolvedGroups === 0 && !hasWildcardUnmentionedGroups) {
384
- return undefined;
385
- }
386
- const botId = probe?.ok && probe.bot?.id != null ? probe.bot.id : null;
387
- if (!botId) {
388
- return {
389
- ok: unresolvedGroups === 0 && !hasWildcardUnmentionedGroups,
390
- checkedGroups: 0,
391
- unresolvedGroups,
392
- hasWildcardUnmentionedGroups,
393
- groups: [],
394
- elapsedMs: 0,
395
- };
396
- }
397
- const audit = await getTelegramRuntime().channel.telegram.auditGroupMembership({
398
- token: account.token,
399
- botId,
400
- groupIds,
401
- proxyUrl: account.config.proxy,
402
- timeoutMs,
403
- });
404
- return { ...audit, unresolvedGroups, hasWildcardUnmentionedGroups };
405
- },
406
- buildAccountSnapshot: ({ account, cfg, runtime, probe, audit }) => {
407
- const ownerAccountId = findTelegramTokenOwnerAccountId({
408
- cfg,
409
- accountId: account.accountId,
410
- });
411
- const duplicateTokenReason = ownerAccountId
412
- ? formatDuplicateTelegramTokenReason({
413
- accountId: account.accountId,
414
- ownerAccountId,
415
- })
416
- : null;
417
- const configured = Boolean(account.token?.trim()) && !ownerAccountId;
418
- const groups =
419
- cfg.channels?.telegram?.accounts?.[account.accountId]?.groups ??
420
- cfg.channels?.telegram?.groups;
421
- const allowUnmentionedGroups =
422
- groups?.["*"]?.requireMention === false ||
423
- Object.entries(groups ?? {}).some(
424
- ([key, value]) => key !== "*" && value?.requireMention === false,
425
- );
426
- return {
427
- accountId: account.accountId,
428
- name: account.name,
429
- enabled: account.enabled,
430
- configured,
431
- tokenSource: account.tokenSource,
432
- running: runtime?.running ?? false,
433
- lastStartAt: runtime?.lastStartAt ?? null,
434
- lastStopAt: runtime?.lastStopAt ?? null,
435
- lastError: runtime?.lastError ?? duplicateTokenReason,
436
- mode: runtime?.mode ?? (account.config.webhookUrl ? "webhook" : "polling"),
437
- probe,
438
- audit,
439
- allowUnmentionedGroups,
440
- lastInboundAt: runtime?.lastInboundAt ?? null,
441
- lastOutboundAt: runtime?.lastOutboundAt ?? null,
442
- };
443
- },
444
- },
445
- gateway: {
446
- startAccount: async (ctx) => {
447
- const account = ctx.account;
448
- const ownerAccountId = findTelegramTokenOwnerAccountId({
449
- cfg: ctx.cfg,
450
- accountId: account.accountId,
451
- });
452
- if (ownerAccountId) {
453
- const reason = formatDuplicateTelegramTokenReason({
454
- accountId: account.accountId,
455
- ownerAccountId,
456
- });
457
- ctx.log?.error?.(`[${account.accountId}] ${reason}`);
458
- throw new Error(reason);
459
- }
460
- const token = account.token.trim();
461
- let telegramBotLabel = "";
462
- try {
463
- const probe = await getTelegramRuntime().channel.telegram.probeTelegram(
464
- token,
465
- 2500,
466
- account.config.proxy,
467
- );
468
- const username = probe.ok ? probe.bot?.username?.trim() : null;
469
- if (username) {
470
- telegramBotLabel = ` (@${username})`;
471
- }
472
- } catch (err) {
473
- if (getTelegramRuntime().logging.shouldLogVerbose()) {
474
- ctx.log?.debug?.(`[${account.accountId}] bot probe failed: ${String(err)}`);
475
- }
476
- }
477
- ctx.log?.info(`[${account.accountId}] starting provider${telegramBotLabel}`);
478
- return getTelegramRuntime().channel.telegram.monitorTelegramProvider({
479
- token,
480
- accountId: account.accountId,
481
- config: ctx.cfg,
482
- runtime: ctx.runtime,
483
- abortSignal: ctx.abortSignal,
484
- useWebhook: Boolean(account.config.webhookUrl),
485
- webhookUrl: account.config.webhookUrl,
486
- webhookSecret: account.config.webhookSecret,
487
- webhookPath: account.config.webhookPath,
488
- webhookHost: account.config.webhookHost,
489
- });
490
- },
491
- logoutAccount: async ({ accountId, cfg }) => {
492
- const envToken = process.env.TELEGRAM_BOT_TOKEN?.trim() ?? "";
493
- const nextCfg = { ...cfg } as SymiConfig;
494
- const nextTelegram = cfg.channels?.telegram ? { ...cfg.channels.telegram } : undefined;
495
- let cleared = false;
496
- let changed = false;
497
- if (nextTelegram) {
498
- if (accountId === DEFAULT_ACCOUNT_ID && nextTelegram.botToken) {
499
- delete nextTelegram.botToken;
500
- cleared = true;
501
- changed = true;
502
- }
503
- const accounts =
504
- nextTelegram.accounts && typeof nextTelegram.accounts === "object"
505
- ? { ...nextTelegram.accounts }
506
- : undefined;
507
- if (accounts && accountId in accounts) {
508
- const entry = accounts[accountId];
509
- if (entry && typeof entry === "object") {
510
- const nextEntry = { ...entry } as Record<string, unknown>;
511
- if ("botToken" in nextEntry) {
512
- const token = nextEntry.botToken;
513
- if (typeof token === "string" ? token.trim() : token) {
514
- cleared = true;
515
- }
516
- delete nextEntry.botToken;
517
- changed = true;
518
- }
519
- if (Object.keys(nextEntry).length === 0) {
520
- delete accounts[accountId];
521
- changed = true;
522
- } else {
523
- accounts[accountId] = nextEntry as typeof entry;
524
- }
525
- }
526
- }
527
- if (accounts) {
528
- if (Object.keys(accounts).length === 0) {
529
- delete nextTelegram.accounts;
530
- changed = true;
531
- } else {
532
- nextTelegram.accounts = accounts;
533
- }
534
- }
535
- }
536
- if (changed) {
537
- if (nextTelegram && Object.keys(nextTelegram).length > 0) {
538
- nextCfg.channels = { ...nextCfg.channels, telegram: nextTelegram };
539
- } else {
540
- const nextChannels = { ...nextCfg.channels };
541
- delete nextChannels.telegram;
542
- if (Object.keys(nextChannels).length > 0) {
543
- nextCfg.channels = nextChannels;
544
- } else {
545
- delete nextCfg.channels;
546
- }
547
- }
548
- }
549
- const resolved = resolveTelegramAccount({
550
- cfg: changed ? nextCfg : cfg,
551
- accountId,
552
- });
553
- const loggedOut = resolved.tokenSource === "none";
554
- if (changed) {
555
- await getTelegramRuntime().config.writeConfigFile(nextCfg);
556
- }
557
- return { cleared, envToken: Boolean(envToken), loggedOut };
558
- },
559
- },
560
- };
@@ -1,14 +0,0 @@
1
- import type { PluginRuntime } from "symi/plugin-sdk";
2
-
3
- let runtime: PluginRuntime | null = null;
4
-
5
- export function setTelegramRuntime(next: PluginRuntime) {
6
- runtime = next;
7
- }
8
-
9
- export function getTelegramRuntime(): PluginRuntime {
10
- if (!runtime) {
11
- throw new Error("Telegram runtime not initialized");
12
- }
13
- return runtime;
14
- }
@@ -1,9 +0,0 @@
1
- {
2
- "id": "telegram",
3
- "channels": ["telegram"],
4
- "configSchema": {
5
- "type": "object",
6
- "additionalProperties": false,
7
- "properties": {}
8
- }
9
- }
@@ -1,17 +0,0 @@
1
- import type { SymiPluginApi } from "symi/plugin-sdk";
2
- import { emptyPluginConfigSchema } from "symi/plugin-sdk";
3
- import { whatsappPlugin } from "./src/channel.js";
4
- import { setWhatsAppRuntime } from "./src/runtime.js";
5
-
6
- const plugin = {
7
- id: "whatsapp",
8
- name: "WhatsApp",
9
- description: "WhatsApp channel plugin",
10
- configSchema: emptyPluginConfigSchema(),
11
- register(api: SymiPluginApi) {
12
- setWhatsAppRuntime(api.runtime);
13
- api.registerChannel({ plugin: whatsappPlugin });
14
- },
15
- };
16
-
17
- export default plugin;
@@ -1,21 +0,0 @@
1
- #!/bin/sh
2
- basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
-
4
- case `uname` in
5
- *CYGWIN*|*MINGW*|*MSYS*)
6
- if command -v cygpath > /dev/null 2>&1; then
7
- basedir=`cygpath -w "$basedir"`
8
- fi
9
- ;;
10
- esac
11
-
12
- if [ -z "$NODE_PATH" ]; then
13
- export NODE_PATH="/home/symi/projects/symi/node_modules:/home/symi/projects/node_modules:/home/symi/node_modules:/home/node_modules:/node_modules:/home/symi/projects/symi/node_modules/.pnpm/node_modules"
14
- else
15
- export NODE_PATH="/home/symi/projects/symi/node_modules:/home/symi/projects/node_modules:/home/symi/node_modules:/home/node_modules:/node_modules:/home/symi/projects/symi/node_modules/.pnpm/node_modules:$NODE_PATH"
16
- fi
17
- if [ -x "$basedir/node" ]; then
18
- exec "$basedir/node" "$basedir/../@symerian/symi/symi.mjs" "$@"
19
- else
20
- exec node "$basedir/../@symerian/symi/symi.mjs" "$@"
21
- fi
@@ -1,15 +0,0 @@
1
- {
2
- "name": "@symi/whatsapp",
3
- "version": "3.0.9",
4
- "private": true,
5
- "description": "Symi WhatsApp channel plugin",
6
- "type": "module",
7
- "devDependencies": {
8
- "@symerian/symi": "workspace:*"
9
- },
10
- "symi": {
11
- "extensions": [
12
- "./index.ts"
13
- ]
14
- }
15
- }