paperclip-plugin-telegram 0.1.0

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/dist/worker.js ADDED
@@ -0,0 +1,300 @@
1
+ import { definePlugin, runWorker, } from "@paperclipai/plugin-sdk";
2
+ import { sendMessage, editMessage, answerCallbackQuery, setMyCommands, escapeMarkdownV2, } from "./telegram-api.js";
3
+ import { formatIssueCreated, formatIssueDone, formatApprovalCreated, formatAgentError, formatAgentRunStarted, formatAgentRunFinished, } from "./formatters.js";
4
+ import { handleCommand, getTopicForProject, BOT_COMMANDS } from "./commands.js";
5
+ import { routeMessageToAcp, handleAcpOutput } from "./acp-bridge.js";
6
+ import { METRIC_NAMES } from "./constants.js";
7
+ const TELEGRAM_API = "https://api.telegram.org";
8
+ async function resolveChat(ctx, companyId, fallback) {
9
+ const override = await ctx.state.get({
10
+ scopeKind: "company",
11
+ scopeId: companyId,
12
+ stateKey: "telegram-chat",
13
+ });
14
+ return override ?? fallback ?? null;
15
+ }
16
+ const plugin = definePlugin({
17
+ async setup(ctx) {
18
+ const rawConfig = await ctx.config.get();
19
+ ctx.logger.info("Telegram plugin config loaded");
20
+ const config = rawConfig;
21
+ const baseUrl = config.paperclipBaseUrl || "http://localhost:3100";
22
+ if (!config.telegramBotTokenRef) {
23
+ ctx.logger.warn("No telegramBotTokenRef configured, plugin disabled");
24
+ return;
25
+ }
26
+ const token = await ctx.secrets.resolve(config.telegramBotTokenRef);
27
+ // --- Register bot commands with Telegram ---
28
+ if (config.enableCommands) {
29
+ const registered = await setMyCommands(ctx, token, BOT_COMMANDS);
30
+ if (registered) {
31
+ ctx.logger.info("Bot commands registered with Telegram");
32
+ }
33
+ }
34
+ // --- Long polling for inbound messages ---
35
+ let pollingActive = true;
36
+ let lastUpdateId = 0;
37
+ async function pollUpdates() {
38
+ while (pollingActive) {
39
+ try {
40
+ const res = await ctx.http.fetch(`${TELEGRAM_API}/bot${token}/getUpdates?offset=${lastUpdateId + 1}&timeout=30&allowed_updates=["message","callback_query"]`, { method: "GET" });
41
+ const data = (await res.json());
42
+ if (data.ok && data.result) {
43
+ for (const update of data.result) {
44
+ lastUpdateId = Math.max(lastUpdateId, update.update_id);
45
+ await handleUpdate(ctx, token, config, update, baseUrl);
46
+ }
47
+ }
48
+ }
49
+ catch (err) {
50
+ ctx.logger.error("Telegram polling error", { error: String(err) });
51
+ await new Promise((r) => setTimeout(r, 5000));
52
+ }
53
+ }
54
+ }
55
+ // Start polling in background
56
+ if (config.enableCommands || config.enableInbound) {
57
+ pollUpdates().catch((err) => ctx.logger.error("Polling loop crashed", { error: String(err) }));
58
+ }
59
+ // Stop polling on plugin shutdown
60
+ ctx.events.on("plugin.stopping", async () => {
61
+ pollingActive = false;
62
+ });
63
+ // --- Event subscriptions ---
64
+ const notify = async (event, formatter, overrideChatId) => {
65
+ const chatId = await resolveChat(ctx, event.companyId, overrideChatId || config.defaultChatId);
66
+ if (!chatId)
67
+ return;
68
+ const msg = formatter(event);
69
+ // Topic routing: check if event has a project mapping
70
+ let messageThreadId;
71
+ if (config.topicRouting) {
72
+ const payload = event.payload;
73
+ const projectName = payload.projectName ? String(payload.projectName) : undefined;
74
+ messageThreadId = await getTopicForProject(ctx, chatId, projectName);
75
+ }
76
+ if (messageThreadId) {
77
+ msg.options.messageThreadId = messageThreadId;
78
+ }
79
+ const messageId = await sendMessage(ctx, token, chatId, msg.text, msg.options);
80
+ if (messageId) {
81
+ await ctx.state.set({
82
+ scopeKind: "instance",
83
+ stateKey: `msg_${chatId}_${messageId}`,
84
+ }, {
85
+ entityId: event.entityId,
86
+ entityType: event.entityType,
87
+ companyId: event.companyId,
88
+ eventType: event.eventType,
89
+ });
90
+ await ctx.activity.log({
91
+ companyId: event.companyId,
92
+ message: `Forwarded ${event.eventType} to Telegram`,
93
+ entityType: "plugin",
94
+ entityId: event.entityId,
95
+ });
96
+ }
97
+ };
98
+ if (config.notifyOnIssueCreated) {
99
+ ctx.events.on("issue.created", (event) => notify(event, formatIssueCreated));
100
+ }
101
+ if (config.notifyOnIssueDone) {
102
+ ctx.events.on("issue.updated", async (event) => {
103
+ const payload = event.payload;
104
+ if (payload.status !== "done")
105
+ return;
106
+ await notify(event, formatIssueDone);
107
+ });
108
+ }
109
+ if (config.notifyOnApprovalCreated) {
110
+ ctx.events.on("approval.created", (event) => notify(event, formatApprovalCreated, config.approvalsChatId));
111
+ }
112
+ if (config.notifyOnAgentError) {
113
+ ctx.events.on("agent.run.failed", (event) => notify(event, formatAgentError, config.errorsChatId));
114
+ }
115
+ ctx.events.on("agent.run.started", (event) => notify(event, formatAgentRunStarted));
116
+ ctx.events.on("agent.run.finished", (event) => notify(event, formatAgentRunFinished));
117
+ // --- Per-company chat overrides ---
118
+ ctx.data.register("chat-mapping", async (params) => {
119
+ const companyId = String(params.companyId);
120
+ const saved = await ctx.state.get({
121
+ scopeKind: "company",
122
+ scopeId: companyId,
123
+ stateKey: "telegram-chat",
124
+ });
125
+ return { chatId: saved ?? config.defaultChatId };
126
+ });
127
+ ctx.actions.register("set-chat", async (params) => {
128
+ const companyId = String(params.companyId);
129
+ const chatId = String(params.chatId);
130
+ await ctx.state.set({ scopeKind: "company", scopeId: companyId, stateKey: "telegram-chat" }, chatId);
131
+ ctx.logger.info("Updated Telegram chat mapping", { companyId, chatId });
132
+ return { ok: true };
133
+ });
134
+ // --- Daily digest job ---
135
+ if (config.dailyDigestEnabled) {
136
+ ctx.jobs.register("telegram-daily-digest", async () => {
137
+ try {
138
+ const companies = await ctx.companies.list();
139
+ const companyId = companies[0]?.id ?? "";
140
+ const agents = await ctx.agents.list({ companyId });
141
+ const activeAgents = agents.filter((a) => a.status === "active");
142
+ const issues = await ctx.issues.list({ companyId, limit: 50 });
143
+ const now = Date.now();
144
+ const oneDayMs = 24 * 60 * 60 * 1000;
145
+ const completedToday = issues.filter((i) => i.status === "done" && i.completedAt && (now - new Date(i.completedAt).getTime()) < oneDayMs);
146
+ const createdToday = issues.filter((i) => (now - new Date(i.createdAt).getTime()) < oneDayMs);
147
+ const dateStr = new Date().toISOString().split("T")[0];
148
+ const lines = [
149
+ escapeMarkdownV2("📊") + ` *Daily Digest \\- ${escapeMarkdownV2(dateStr)}*`,
150
+ "",
151
+ `${escapeMarkdownV2("✅")} Tasks completed: *${completedToday.length}*`,
152
+ `${escapeMarkdownV2("📋")} Tasks created: *${createdToday.length}*`,
153
+ `${escapeMarkdownV2("🤖")} Active agents: *${activeAgents.length}*/${escapeMarkdownV2(String(agents.length))}`,
154
+ ];
155
+ if (activeAgents.length > 0) {
156
+ const topAgent = activeAgents[0].name;
157
+ lines.push(`${escapeMarkdownV2("⭐")} Top performer: *${escapeMarkdownV2(topAgent)}*`);
158
+ }
159
+ await sendMessage(ctx, token, config.defaultChatId, lines.join("\n"), {
160
+ parseMode: "MarkdownV2",
161
+ });
162
+ }
163
+ catch (err) {
164
+ ctx.logger.error("Daily digest failed", { error: String(err) });
165
+ const text = [
166
+ escapeMarkdownV2("📊") + " *Daily Digest*",
167
+ "",
168
+ escapeMarkdownV2("Could not generate digest. Check plugin logs for details."),
169
+ ].join("\n");
170
+ await sendMessage(ctx, token, config.defaultChatId, text, {
171
+ parseMode: "MarkdownV2",
172
+ });
173
+ }
174
+ });
175
+ }
176
+ // --- ACP output listener ---
177
+ ctx.events.on("plugin.acp-output", async (event) => {
178
+ const acpEvent = event;
179
+ await handleAcpOutput(ctx, token, acpEvent);
180
+ });
181
+ ctx.logger.info("Telegram bot plugin started");
182
+ },
183
+ async onValidateConfig(config) {
184
+ if (!config.telegramBotTokenRef || typeof config.telegramBotTokenRef !== "string") {
185
+ return { ok: false, errors: ["telegramBotTokenRef is required"] };
186
+ }
187
+ if (!config.defaultChatId || typeof config.defaultChatId !== "string") {
188
+ return { ok: false, errors: ["defaultChatId is required"] };
189
+ }
190
+ return { ok: true };
191
+ },
192
+ async onHealth() {
193
+ return { status: "ok" };
194
+ },
195
+ });
196
+ async function handleUpdate(ctx, token, config, update, baseUrl) {
197
+ if (update.callback_query) {
198
+ await handleCallbackQuery(ctx, token, update.callback_query, baseUrl);
199
+ return;
200
+ }
201
+ const msg = update.message;
202
+ if (!msg?.text)
203
+ return;
204
+ const chatId = String(msg.chat.id);
205
+ const text = msg.text;
206
+ const threadId = msg.message_thread_id;
207
+ // Route thread messages to ACP if a session is bound
208
+ if (threadId) {
209
+ const isAcpCommand = text.startsWith("/acp");
210
+ if (!isAcpCommand) {
211
+ const routed = await routeMessageToAcp(ctx, chatId, threadId, text);
212
+ if (routed)
213
+ return;
214
+ }
215
+ }
216
+ const botCommand = msg.entities?.find((e) => e.type === "bot_command" && e.offset === 0);
217
+ if (botCommand && config.enableCommands) {
218
+ const fullCommand = text.slice(botCommand.offset, botCommand.offset + botCommand.length);
219
+ const command = fullCommand.replace(/^\//, "").replace(/@.*$/, "");
220
+ const args = text.slice(botCommand.offset + botCommand.length).trim();
221
+ await handleCommand(ctx, token, chatId, command, args, threadId, baseUrl);
222
+ return;
223
+ }
224
+ if (config.enableInbound && msg.reply_to_message?.from?.is_bot) {
225
+ const replyToId = msg.reply_to_message.message_id;
226
+ const mapping = await ctx.state.get({
227
+ scopeKind: "instance",
228
+ stateKey: `msg_${chatId}_${replyToId}`,
229
+ });
230
+ if (mapping && mapping.entityType === "issue") {
231
+ try {
232
+ await ctx.http.fetch(`${baseUrl}/api/issues/${mapping.entityId}/comments`, {
233
+ method: "POST",
234
+ headers: { "Content-Type": "application/json" },
235
+ body: JSON.stringify({
236
+ body: text,
237
+ authorUserId: `telegram:${msg.from?.username ?? msg.from?.id ?? chatId}`,
238
+ }),
239
+ });
240
+ await ctx.metrics.write(METRIC_NAMES.inboundRouted, 1);
241
+ ctx.logger.info("Routed Telegram reply to issue comment", {
242
+ issueId: mapping.entityId,
243
+ from: msg.from?.username,
244
+ });
245
+ }
246
+ catch (err) {
247
+ ctx.logger.error("Failed to route inbound message", { error: String(err) });
248
+ }
249
+ }
250
+ }
251
+ }
252
+ async function handleCallbackQuery(ctx, token, query, baseUrl) {
253
+ const data = query.data;
254
+ if (!data)
255
+ return;
256
+ const actor = query.from.username ?? query.from.first_name ?? String(query.from.id);
257
+ const chatId = query.message?.chat.id ? String(query.message.chat.id) : null;
258
+ const messageId = query.message?.message_id;
259
+ if (data.startsWith("approve_")) {
260
+ const approvalId = data.replace("approve_", "");
261
+ ctx.logger.info("Approval button clicked", { approvalId, actor });
262
+ try {
263
+ await ctx.http.fetch(`${baseUrl}/api/approvals/${approvalId}/approve`, {
264
+ method: "POST",
265
+ headers: { "Content-Type": "application/json" },
266
+ body: JSON.stringify({ decidedByUserId: `telegram:${actor}` }),
267
+ });
268
+ await answerCallbackQuery(ctx, token, query.id, "Approved");
269
+ if (chatId && messageId) {
270
+ await editMessage(ctx, token, chatId, messageId, `${escapeMarkdownV2("✅")} *Approved* by ${escapeMarkdownV2(actor)}`, { parseMode: "MarkdownV2" });
271
+ }
272
+ }
273
+ catch (err) {
274
+ await answerCallbackQuery(ctx, token, query.id, `Failed: ${String(err)}`);
275
+ }
276
+ return;
277
+ }
278
+ if (data.startsWith("reject_")) {
279
+ const approvalId = data.replace("reject_", "");
280
+ ctx.logger.info("Rejection button clicked", { approvalId, actor });
281
+ try {
282
+ await ctx.http.fetch(`${baseUrl}/api/approvals/${approvalId}/reject`, {
283
+ method: "POST",
284
+ headers: { "Content-Type": "application/json" },
285
+ body: JSON.stringify({ decidedByUserId: `telegram:${actor}` }),
286
+ });
287
+ await answerCallbackQuery(ctx, token, query.id, "Rejected");
288
+ if (chatId && messageId) {
289
+ await editMessage(ctx, token, chatId, messageId, `${escapeMarkdownV2("❌")} *Rejected* by ${escapeMarkdownV2(actor)}`, { parseMode: "MarkdownV2" });
290
+ }
291
+ }
292
+ catch (err) {
293
+ await answerCallbackQuery(ctx, token, query.id, `Failed: ${String(err)}`);
294
+ }
295
+ return;
296
+ }
297
+ await answerCallbackQuery(ctx, token, query.id, "Unknown action");
298
+ }
299
+ runWorker(plugin, import.meta.url);
300
+ //# sourceMappingURL=worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,SAAS,GAMV,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,WAAW,EACX,WAAW,EACX,mBAAmB,EACnB,aAAa,EACb,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AA8C9C,MAAM,YAAY,GAAG,0BAA0B,CAAC;AAEhD,KAAK,UAAU,WAAW,CACxB,GAAkB,EAClB,SAAiB,EACjB,QAAgB;IAEhB,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;QACnC,SAAS,EAAE,SAAS;QACpB,OAAO,EAAE,SAAS;QAClB,QAAQ,EAAE,eAAe;KAC1B,CAAC,CAAC;IACH,OAAQ,QAAmB,IAAI,QAAQ,IAAI,IAAI,CAAC;AAClD,CAAC;AAED,MAAM,MAAM,GAAG,YAAY,CAAC;IAC1B,KAAK,CAAC,KAAK,CAAC,GAAG;QACb,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACzC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,SAAsC,CAAC;QACtD,MAAM,OAAO,GAAG,MAAM,CAAC,gBAAgB,IAAI,uBAAuB,CAAC;QAEnE,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAChC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;YACtE,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;QAEpE,8CAA8C;QAC9C,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;YAC1B,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;YACjE,IAAI,UAAU,EAAE,CAAC;gBACf,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAED,4CAA4C;QAC5C,IAAI,aAAa,GAAG,IAAI,CAAC;QACzB,IAAI,YAAY,GAAG,CAAC,CAAC;QAErB,KAAK,UAAU,WAAW;YACxB,OAAO,aAAa,EAAE,CAAC;gBACrB,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAC9B,GAAG,YAAY,OAAO,KAAK,sBAAsB,YAAY,GAAG,CAAC,0DAA0D,EAC3H,EAAE,MAAM,EAAE,KAAK,EAAE,CAClB,CAAC;oBACF,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAG7B,CAAC;oBAEF,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;wBAC3B,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;4BACjC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;4BACxD,MAAM,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;wBAC1D,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBACnE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;gBAChD,CAAC;YACH,CAAC;QACH,CAAC;QAED,8BAA8B;QAC9B,IAAI,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YAClD,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAC1B,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CACjE,CAAC;QACJ,CAAC;QAED,kCAAkC;QAClC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,iBAAiB,EAAE,KAAK,IAAI,EAAE;YAC1C,aAAa,GAAG,KAAK,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,8BAA8B;QAE9B,MAAM,MAAM,GAAG,KAAK,EAClB,KAAkB,EAClB,SAAwG,EACxG,cAAuB,EACvB,EAAE;YACF,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,GAAG,EACH,KAAK,CAAC,SAAS,EACf,cAAc,IAAI,MAAM,CAAC,aAAa,CACvC,CAAC;YACF,IAAI,CAAC,MAAM;gBAAE,OAAO;YACpB,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YAE7B,sDAAsD;YACtD,IAAI,eAAmC,CAAC;YACxC,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;gBACxB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAkC,CAAC;gBACzD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAClF,eAAe,GAAG,MAAM,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;YACvE,CAAC;YAED,IAAI,eAAe,EAAE,CAAC;gBACpB,GAAG,CAAC,OAAO,CAAC,eAAe,GAAG,eAAe,CAAC;YAChD,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YAE/E,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,CACjB;oBACE,SAAS,EAAE,UAAU;oBACrB,QAAQ,EAAE,OAAO,MAAM,IAAI,SAAS,EAAE;iBACvC,EACD;oBACE,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;iBAC3B,CACF,CAAC;gBAEF,MAAM,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;oBACrB,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,OAAO,EAAE,aAAa,KAAK,CAAC,SAAS,cAAc;oBACnD,UAAU,EAAE,QAAQ;oBACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;iBACzB,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,MAAM,CAAC,oBAAoB,EAAE,CAAC;YAChC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,KAAkB,EAAE,EAAE,CACpD,MAAM,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAClC,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;YAC7B,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,EAAE,KAAkB,EAAE,EAAE;gBAC1D,MAAM,OAAO,GAAG,KAAK,CAAC,OAAkC,CAAC;gBACzD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM;oBAAE,OAAO;gBACtC,MAAM,MAAM,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;YACvC,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,MAAM,CAAC,uBAAuB,EAAE,CAAC;YACnC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC,KAAkB,EAAE,EAAE,CACvD,MAAM,CAAC,KAAK,EAAE,qBAAqB,EAAE,MAAM,CAAC,eAAe,CAAC,CAC7D,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,CAAC,kBAAkB,EAAE,CAAC;YAC9B,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC,KAAkB,EAAE,EAAE,CACvD,MAAM,CAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,CAAC,YAAY,CAAC,CACrD,CAAC;QACJ,CAAC;QAED,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAkB,EAAE,EAAE,CACxD,MAAM,CAAC,KAAK,EAAE,qBAAqB,CAAC,CACrC,CAAC;QACF,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,KAAkB,EAAE,EAAE,CACzD,MAAM,CAAC,KAAK,EAAE,sBAAsB,CAAC,CACtC,CAAC;QAEF,qCAAqC;QAErC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACjD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC3C,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;gBAChC,SAAS,EAAE,SAAS;gBACpB,OAAO,EAAE,SAAS;gBAClB,QAAQ,EAAE,eAAe;aAC1B,CAAC,CAAC;YACH,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAChD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACrC,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,CACjB,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,EACvE,MAAM,CACP,CAAC;YACF,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;YACxE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,2BAA2B;QAE3B,IAAI,MAAM,CAAC,kBAAkB,EAAE,CAAC;YAC9B,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;gBACpD,IAAI,CAAC;oBACH,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;oBAC7C,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC;oBACzC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;oBACpD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;oBACxE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;oBAE/D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBACvB,MAAM,QAAQ,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;oBACrC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAQ,EAAE,EAAE,CAChD,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,QAAQ,CAC7F,CAAC;oBACF,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAQ,EAAE,EAAE,CAC9C,CAAC,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,QAAQ,CACnD,CAAC;oBAEF,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;oBACvD,MAAM,KAAK,GAAG;wBACZ,gBAAgB,CAAC,IAAI,CAAC,GAAG,sBAAsB,gBAAgB,CAAC,OAAQ,CAAC,GAAG;wBAC5E,EAAE;wBACF,GAAG,gBAAgB,CAAC,GAAG,CAAC,sBAAsB,cAAc,CAAC,MAAM,GAAG;wBACtE,GAAG,gBAAgB,CAAC,IAAI,CAAC,oBAAoB,YAAY,CAAC,MAAM,GAAG;wBACnE,GAAG,gBAAgB,CAAC,IAAI,CAAC,oBAAoB,YAAY,CAAC,MAAM,KAAK,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE;qBAC/G,CAAC;oBAEF,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC5B,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC;wBACvC,KAAK,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,oBAAoB,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;oBACxF,CAAC;oBAED,MAAM,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;wBACpE,SAAS,EAAE,YAAY;qBACxB,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBAChE,MAAM,IAAI,GAAG;wBACX,gBAAgB,CAAC,IAAI,CAAC,GAAG,iBAAiB;wBAC1C,EAAE;wBACF,gBAAgB,CAAC,2DAA2D,CAAC;qBAC9E,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAEb,MAAM,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,IAAI,EAAE;wBACxD,SAAS,EAAE,YAAY;qBACxB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAED,8BAA8B;QAC9B,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,mBAAmB,EAAE,KAAK,EAAE,KAAc,EAAE,EAAE;YAC1D,MAAM,QAAQ,GAAG,KAMhB,CAAC;YACF,MAAM,eAAe,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,MAAM;QAC3B,IAAI,CAAC,MAAM,CAAC,mBAAmB,IAAI,OAAO,MAAM,CAAC,mBAAmB,KAAK,QAAQ,EAAE,CAAC;YAClF,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,iCAAiC,CAAC,EAAE,CAAC;QACpE,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;YACtE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,2BAA2B,CAAC,EAAE,CAAC;QAC9D,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC;CACF,CAAC,CAAC;AAEH,KAAK,UAAU,YAAY,CACzB,GAAkB,EAClB,KAAa,EACb,MAAsB,EACtB,MAAsB,EACtB,OAAe;IAEf,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QAC1B,MAAM,mBAAmB,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QACtE,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC;IAC3B,IAAI,CAAC,GAAG,EAAE,IAAI;QAAE,OAAO;IAEvB,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IACtB,MAAM,QAAQ,GAAG,GAAG,CAAC,iBAAiB,CAAC;IAEvC,qDAAqD;IACrD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC7C,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;YACpE,IAAI,MAAM;gBAAE,OAAO;QACrB,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;IACzF,IAAI,UAAU,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QACxC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QACzF,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACnE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QACtE,MAAM,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC1E,OAAO;IACT,CAAC;IAED,IAAI,MAAM,CAAC,aAAa,IAAI,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAC/D,MAAM,SAAS,GAAG,GAAG,CAAC,gBAAgB,CAAC,UAAU,CAAC;QAClD,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;YAClC,SAAS,EAAE,UAAU;YACrB,QAAQ,EAAE,OAAO,MAAM,IAAI,SAAS,EAAE;SACvC,CAAuE,CAAC;QAEzE,IAAI,OAAO,IAAI,OAAO,CAAC,UAAU,KAAK,OAAO,EAAE,CAAC;YAC9C,IAAI,CAAC;gBACH,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAClB,GAAG,OAAO,eAAe,OAAO,CAAC,QAAQ,WAAW,EACpD;oBACE,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;oBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,IAAI,EAAE,IAAI;wBACV,YAAY,EAAE,YAAY,GAAG,CAAC,IAAI,EAAE,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,MAAM,EAAE;qBACzE,CAAC;iBACH,CACF,CAAC;gBACF,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;gBACvD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,wCAAwC,EAAE;oBACxD,OAAO,EAAE,OAAO,CAAC,QAAQ;oBACzB,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ;iBACzB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC9E,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,GAAkB,EAClB,KAAa,EACb,KAAoD,EACpD,OAAe;IAEf,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,IAAI,CAAC,IAAI;QAAE,OAAO;IAElB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpF,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7E,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC;IAE5C,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAChD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;QAElE,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAClB,GAAG,OAAO,kBAAkB,UAAU,UAAU,EAChD;gBACE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,eAAe,EAAE,YAAY,KAAK,EAAE,EAAE,CAAC;aAC/D,CACF,CAAC;YAEF,MAAM,mBAAmB,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YAE5D,IAAI,MAAM,IAAI,SAAS,EAAE,CAAC;gBACxB,MAAM,WAAW,CACf,GAAG,EACH,KAAK,EACL,MAAM,EACN,SAAS,EACT,GAAG,gBAAgB,CAAC,GAAG,CAAC,kBAAkB,gBAAgB,CAAC,KAAK,CAAC,EAAE,EACnE,EAAE,SAAS,EAAE,YAAY,EAAE,CAC5B,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,mBAAmB,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,WAAW,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAC/C,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;QAEnE,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAClB,GAAG,OAAO,kBAAkB,UAAU,SAAS,EAC/C;gBACE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,eAAe,EAAE,YAAY,KAAK,EAAE,EAAE,CAAC;aAC/D,CACF,CAAC;YAEF,MAAM,mBAAmB,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YAE5D,IAAI,MAAM,IAAI,SAAS,EAAE,CAAC;gBACxB,MAAM,WAAW,CACf,GAAG,EACH,KAAK,EACL,MAAM,EACN,SAAS,EACT,GAAG,gBAAgB,CAAC,GAAG,CAAC,kBAAkB,gBAAgB,CAAC,KAAK,CAAC,EAAE,EACnE,EAAE,SAAS,EAAE,YAAY,EAAE,CAC5B,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,mBAAmB,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,WAAW,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO;IACT,CAAC;IAED,MAAM,mBAAmB,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "paperclip-plugin-telegram",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/mvanhorn/paperclip-plugin-telegram.git"
10
+ },
11
+ "keywords": ["paperclip", "plugin", "telegram", "bot", "notifications", "acp"],
12
+ "files": ["dist", "README.md"],
13
+ "paperclipPlugin": {
14
+ "manifest": "./dist/manifest.js",
15
+ "worker": "./dist/worker.js"
16
+ },
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "typecheck": "tsc --noEmit",
20
+ "dev": "tsc --watch",
21
+ "test": "vitest run"
22
+ },
23
+ "peerDependencies": {
24
+ "@paperclipai/plugin-sdk": "^1.0.0",
25
+ "@paperclipai/shared": "^0.3.0"
26
+ },
27
+ "devDependencies": {
28
+ "@paperclipai/plugin-sdk": "^2026.318.0",
29
+ "@paperclipai/shared": "^2026.318.0",
30
+ "typescript": "^5.7.0",
31
+ "vitest": "^3.0.0"
32
+ }
33
+ }