paperclip-plugin-telegram 0.2.1 → 0.2.2

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 (61) hide show
  1. package/dist/acp-bridge.d.ts +34 -0
  2. package/dist/acp-bridge.js +805 -0
  3. package/dist/acp-bridge.js.map +1 -0
  4. package/dist/adapter.d.ts +35 -0
  5. package/dist/adapter.js +75 -0
  6. package/dist/adapter.js.map +1 -0
  7. package/dist/command-registry.d.ts +3 -0
  8. package/dist/command-registry.js +273 -0
  9. package/dist/command-registry.js.map +1 -0
  10. package/dist/commands.d.ts +10 -0
  11. package/dist/commands.js +213 -0
  12. package/dist/commands.js.map +1 -0
  13. package/dist/constants.d.ts +44 -0
  14. package/dist/constants.js +48 -0
  15. package/dist/constants.js.map +1 -0
  16. package/dist/escalation.d.ts +41 -0
  17. package/dist/escalation.js +254 -0
  18. package/dist/escalation.js.map +1 -0
  19. package/dist/formatters.d.ts +13 -0
  20. package/dist/formatters.js +130 -0
  21. package/dist/formatters.js.map +1 -0
  22. package/dist/index.js +4 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/manifest.d.ts +3 -0
  25. package/dist/manifest.js +230 -0
  26. package/dist/manifest.js.map +1 -0
  27. package/dist/media-pipeline.d.ts +46 -0
  28. package/dist/media-pipeline.js +161 -0
  29. package/dist/media-pipeline.js.map +1 -0
  30. package/dist/telegram-api.d.ts +28 -0
  31. package/dist/telegram-api.js +147 -0
  32. package/dist/telegram-api.js.map +1 -0
  33. package/dist/watch-registry.d.ts +9 -0
  34. package/dist/watch-registry.js +272 -0
  35. package/dist/watch-registry.js.map +1 -0
  36. package/dist/worker.d.ts +1 -0
  37. package/dist/worker.js +548 -0
  38. package/dist/worker.js.map +1 -0
  39. package/package.json +7 -3
  40. package/src/acp-bridge.ts +0 -1273
  41. package/src/adapter.ts +0 -129
  42. package/src/command-registry.ts +0 -482
  43. package/src/commands.ts +0 -346
  44. package/src/constants.ts +0 -51
  45. package/src/escalation.ts +0 -421
  46. package/src/formatters.ts +0 -148
  47. package/src/manifest.ts +0 -246
  48. package/src/media-pipeline.ts +0 -234
  49. package/src/telegram-api.ts +0 -202
  50. package/src/watch-registry.ts +0 -369
  51. package/src/worker.ts +0 -783
  52. package/tests/acp-bridge.test.ts +0 -314
  53. package/tests/command-registry.test.ts +0 -283
  54. package/tests/commands.test.ts +0 -213
  55. package/tests/escalation.test.ts +0 -550
  56. package/tests/formatters.test.ts +0 -185
  57. package/tests/media-pipeline.test.ts +0 -324
  58. package/tests/telegram-api.test.ts +0 -108
  59. package/tests/watch-registry.test.ts +0 -404
  60. package/tsconfig.json +0 -16
  61. /package/{src/index.ts → dist/index.d.ts} +0 -0
@@ -0,0 +1,147 @@
1
+ import { METRIC_NAMES } from "./constants.js";
2
+ const TELEGRAM_API = "https://api.telegram.org";
3
+ export async function sendMessage(ctx, token, chatId, text, options = {}) {
4
+ const body = {
5
+ chat_id: chatId,
6
+ text,
7
+ };
8
+ if (options.parseMode)
9
+ body.parse_mode = options.parseMode;
10
+ if (options.replyToMessageId)
11
+ body.reply_to_message_id = options.replyToMessageId;
12
+ if (options.messageThreadId)
13
+ body.message_thread_id = options.messageThreadId;
14
+ if (options.disableNotification)
15
+ body.disable_notification = true;
16
+ if (options.inlineKeyboard) {
17
+ body.reply_markup = {
18
+ inline_keyboard: options.inlineKeyboard,
19
+ };
20
+ }
21
+ for (let attempt = 0; attempt < 3; attempt++) {
22
+ try {
23
+ const res = await ctx.http.fetch(`${TELEGRAM_API}/bot${token}/sendMessage`, {
24
+ method: "POST",
25
+ headers: { "Content-Type": "application/json" },
26
+ body: JSON.stringify(body),
27
+ });
28
+ const data = (await res.json());
29
+ if (!data.ok) {
30
+ if (data.parameters?.retry_after && attempt < 2) {
31
+ const wait = data.parameters.retry_after * 1000;
32
+ ctx.logger.warn("Telegram rate limited, retrying", { retryAfter: data.parameters.retry_after, attempt });
33
+ await new Promise((r) => setTimeout(r, wait));
34
+ continue;
35
+ }
36
+ if (options.parseMode === "MarkdownV2") {
37
+ ctx.logger.warn("MarkdownV2 send failed, retrying as plain text", {
38
+ error: data.description,
39
+ });
40
+ return sendMessage(ctx, token, chatId, stripMarkdown(text), {
41
+ ...options,
42
+ parseMode: undefined,
43
+ });
44
+ }
45
+ ctx.logger.error("Telegram sendMessage failed", { error: data.description });
46
+ await ctx.metrics.write(METRIC_NAMES.failed, 1);
47
+ return null;
48
+ }
49
+ await ctx.metrics.write(METRIC_NAMES.sent, 1);
50
+ return data.result?.message_id ?? null;
51
+ }
52
+ catch (err) {
53
+ ctx.logger.error("Telegram API error", { error: String(err) });
54
+ await ctx.metrics.write(METRIC_NAMES.failed, 1);
55
+ return null;
56
+ }
57
+ }
58
+ return null;
59
+ }
60
+ export async function editMessage(ctx, token, chatId, messageId, text, options = {}) {
61
+ const body = {
62
+ chat_id: chatId,
63
+ message_id: messageId,
64
+ text,
65
+ };
66
+ if (options.parseMode)
67
+ body.parse_mode = options.parseMode;
68
+ if (options.inlineKeyboard) {
69
+ body.reply_markup = { inline_keyboard: options.inlineKeyboard };
70
+ }
71
+ else {
72
+ body.reply_markup = { inline_keyboard: [] };
73
+ }
74
+ try {
75
+ const res = await ctx.http.fetch(`${TELEGRAM_API}/bot${token}/editMessageText`, {
76
+ method: "POST",
77
+ headers: { "Content-Type": "application/json" },
78
+ body: JSON.stringify(body),
79
+ });
80
+ const data = (await res.json());
81
+ return data.ok;
82
+ }
83
+ catch (err) {
84
+ ctx.logger.error("Telegram editMessage failed", { error: String(err) });
85
+ return false;
86
+ }
87
+ }
88
+ export async function answerCallbackQuery(ctx, token, callbackQueryId, text) {
89
+ try {
90
+ await ctx.http.fetch(`${TELEGRAM_API}/bot${token}/answerCallbackQuery`, {
91
+ method: "POST",
92
+ headers: { "Content-Type": "application/json" },
93
+ body: JSON.stringify({
94
+ callback_query_id: callbackQueryId,
95
+ text,
96
+ }),
97
+ });
98
+ }
99
+ catch (err) {
100
+ ctx.logger.error("Telegram answerCallbackQuery failed", { error: String(err) });
101
+ }
102
+ }
103
+ export async function setMyCommands(ctx, token, commands) {
104
+ try {
105
+ const res = await ctx.http.fetch(`${TELEGRAM_API}/bot${token}/setMyCommands`, {
106
+ method: "POST",
107
+ headers: { "Content-Type": "application/json" },
108
+ body: JSON.stringify({ commands }),
109
+ });
110
+ const data = (await res.json());
111
+ return data.ok;
112
+ }
113
+ catch (err) {
114
+ ctx.logger.error("Telegram setMyCommands failed", { error: String(err) });
115
+ return false;
116
+ }
117
+ }
118
+ export async function sendChatAction(ctx, token, chatId, action = "typing") {
119
+ try {
120
+ await ctx.http.fetch(`${TELEGRAM_API}/bot${token}/sendChatAction`, {
121
+ method: "POST",
122
+ headers: { "Content-Type": "application/json" },
123
+ body: JSON.stringify({ chat_id: chatId, action }),
124
+ });
125
+ }
126
+ catch {
127
+ // Typing indicator failures are non-critical
128
+ }
129
+ }
130
+ // MarkdownV2 requires escaping these characters
131
+ const MD_ESCAPE_CHARS = /([_*\[\]()~`>#+\-=|{}.!\\])/g;
132
+ export function escapeMarkdownV2(text) {
133
+ return text.replace(MD_ESCAPE_CHARS, "\\$1");
134
+ }
135
+ export function truncateAtWord(text, maxLen) {
136
+ if (text.length <= maxLen)
137
+ return text;
138
+ const truncated = text.slice(0, maxLen);
139
+ const lastSpace = truncated.lastIndexOf(" ");
140
+ return (lastSpace > maxLen * 0.7 ? truncated.slice(0, lastSpace) : truncated) + "...";
141
+ }
142
+ function stripMarkdown(text) {
143
+ return text
144
+ .replace(/\\([_*\[\]()~`>#+\-=|{}.!\\])/g, "$1")
145
+ .replace(/[*_`~]/g, "");
146
+ }
147
+ //# sourceMappingURL=telegram-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-api.js","sourceRoot":"","sources":["../src/telegram-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { PluginContext } from "@paperclipai/plugin-sdk";
2
+ export declare function handleRegisterWatch(ctx: PluginContext, params: Record<string, unknown>, companyId: string): Promise<{
3
+ content?: string;
4
+ error?: string;
5
+ }>;
6
+ export declare function checkWatches(ctx: PluginContext, token: string, config: {
7
+ maxSuggestionsPerHourPerCompany: number;
8
+ watchDeduplicationWindowMs: number;
9
+ }): Promise<void>;
@@ -0,0 +1,272 @@
1
+ import { sendMessage, escapeMarkdownV2 } from "./telegram-api.js";
2
+ import { METRIC_NAMES } from "./constants.js";
3
+ // Built-in watch templates
4
+ const BUILTIN_TEMPLATES = {
5
+ "invoice-overdue": {
6
+ name: "Invoice Overdue",
7
+ description: "Alert when invoices are past due",
8
+ entityType: "custom",
9
+ conditions: [
10
+ { field: "dueDate", operator: "lt", value: "{{now}}" },
11
+ { field: "status", operator: "ne", value: "paid" },
12
+ ],
13
+ template: "Invoice {{entityId}} is overdue (due: {{dueDate}}). Consider sending a follow-up.",
14
+ },
15
+ "lead-stale": {
16
+ name: "Stale Lead",
17
+ description: "Alert when leads have no activity for 7+ days",
18
+ entityType: "custom",
19
+ conditions: [
20
+ { field: "lastActivityAt", operator: "lt", value: "{{7daysAgo}}" },
21
+ { field: "status", operator: "eq", value: "active" },
22
+ ],
23
+ template: "Lead {{entityId}} has been inactive for 7+ days. Consider re-engagement.",
24
+ },
25
+ };
26
+ // --- Register watch tool handler ---
27
+ export async function handleRegisterWatch(ctx, params, companyId) {
28
+ const name = String(params.name ?? "");
29
+ const description = String(params.description ?? "");
30
+ const entityType = String(params.entityType ?? "custom");
31
+ const conditions = params.conditions ?? [];
32
+ const template = String(params.template ?? "");
33
+ const chatId = String(params.chatId ?? "");
34
+ const threadId = params.threadId ? Number(params.threadId) : undefined;
35
+ const useBuiltin = params.builtinTemplate ? String(params.builtinTemplate) : undefined;
36
+ if (!name && !useBuiltin) {
37
+ return { error: "Either 'name' or 'builtinTemplate' is required" };
38
+ }
39
+ if (!chatId) {
40
+ return { error: "'chatId' is required" };
41
+ }
42
+ let watch;
43
+ const watchId = `watch_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
44
+ if (useBuiltin && BUILTIN_TEMPLATES[useBuiltin]) {
45
+ const builtin = BUILTIN_TEMPLATES[useBuiltin];
46
+ watch = {
47
+ ...builtin,
48
+ watchId,
49
+ chatId,
50
+ threadId,
51
+ companyId,
52
+ createdBy: "agent",
53
+ createdAt: new Date().toISOString(),
54
+ };
55
+ }
56
+ else {
57
+ if (!template) {
58
+ return { error: "'template' is required for custom watches" };
59
+ }
60
+ watch = {
61
+ watchId,
62
+ name,
63
+ description,
64
+ entityType,
65
+ conditions,
66
+ template,
67
+ chatId,
68
+ threadId,
69
+ companyId,
70
+ createdBy: "agent",
71
+ createdAt: new Date().toISOString(),
72
+ };
73
+ }
74
+ const watches = await getWatchRegistry(ctx, companyId);
75
+ watches.push(watch);
76
+ await saveWatchRegistry(ctx, companyId, watches);
77
+ return { content: JSON.stringify({ status: "registered", watchId, name: watch.name }) };
78
+ }
79
+ // --- Check watches job ---
80
+ export async function checkWatches(ctx, token, config) {
81
+ // Get all companies that have watches
82
+ const companies = await ctx.companies.list();
83
+ for (const company of companies) {
84
+ try {
85
+ await checkWatchesForCompany(ctx, token, company.id, config);
86
+ }
87
+ catch (err) {
88
+ ctx.logger.error("Watch check failed for company", { companyId: company.id, error: String(err) });
89
+ }
90
+ }
91
+ }
92
+ async function checkWatchesForCompany(ctx, token, companyId, config) {
93
+ const watches = await getWatchRegistry(ctx, companyId);
94
+ if (watches.length === 0)
95
+ return;
96
+ // Rate limiting: check how many suggestions we've sent this hour
97
+ const hourlyCount = await getHourlySuggestionCount(ctx, companyId);
98
+ if (hourlyCount >= config.maxSuggestionsPerHourPerCompany) {
99
+ ctx.logger.info("Watch suggestions rate-limited for company", { companyId, hourlyCount });
100
+ return;
101
+ }
102
+ let sentThisRun = 0;
103
+ for (const watch of watches) {
104
+ if (hourlyCount + sentThisRun >= config.maxSuggestionsPerHourPerCompany)
105
+ break;
106
+ try {
107
+ const entities = await evaluateWatch(ctx, watch, companyId);
108
+ for (const entity of entities) {
109
+ if (hourlyCount + sentThisRun >= config.maxSuggestionsPerHourPerCompany)
110
+ break;
111
+ // Dedup check
112
+ const isDuplicate = await checkDedup(ctx, watch.watchId, entity.id, config.watchDeduplicationWindowMs);
113
+ if (isDuplicate)
114
+ continue;
115
+ // Send suggestion
116
+ const message = interpolateTemplate(watch.template, entity);
117
+ await sendMessage(ctx, token, watch.chatId, `${escapeMarkdownV2("\ud83d\udca1")} *Suggestion:* ${escapeMarkdownV2(watch.name)}\n\n${escapeMarkdownV2(message)}`, {
118
+ parseMode: "MarkdownV2",
119
+ messageThreadId: watch.threadId,
120
+ });
121
+ // Record dedup
122
+ await recordSuggestion(ctx, watch.watchId, entity.id);
123
+ sentThisRun++;
124
+ // Update watch last triggered
125
+ watch.lastTriggeredAt = new Date().toISOString();
126
+ }
127
+ }
128
+ catch (err) {
129
+ ctx.logger.error("Watch evaluation failed", { watchId: watch.watchId, error: String(err) });
130
+ }
131
+ }
132
+ // Persist updated watches
133
+ if (sentThisRun > 0) {
134
+ await saveWatchRegistry(ctx, companyId, watches);
135
+ await ctx.metrics.write(METRIC_NAMES.suggestionsEmitted, sentThisRun);
136
+ await incrementHourlySuggestionCount(ctx, companyId, sentThisRun);
137
+ }
138
+ }
139
+ // --- Watch evaluation ---
140
+ async function evaluateWatch(ctx, watch, companyId) {
141
+ const matches = [];
142
+ switch (watch.entityType) {
143
+ case "issue": {
144
+ const issues = await ctx.issues.list({ companyId, limit: 100 });
145
+ for (const issue of issues) {
146
+ const record = issue;
147
+ if (matchesConditions(record, watch.conditions)) {
148
+ matches.push({ id: issue.id, ...record });
149
+ }
150
+ }
151
+ break;
152
+ }
153
+ case "agent": {
154
+ const agents = await ctx.agents.list({ companyId });
155
+ for (const agent of agents) {
156
+ const record = agent;
157
+ if (matchesConditions(record, watch.conditions)) {
158
+ matches.push({ id: agent.id, ...record });
159
+ }
160
+ }
161
+ break;
162
+ }
163
+ case "custom": {
164
+ // Custom watches check state-stored data
165
+ const customData = await ctx.state.get({
166
+ scopeKind: "company",
167
+ scopeId: companyId,
168
+ stateKey: `watch_data_${watch.watchId}`,
169
+ });
170
+ if (customData) {
171
+ for (const item of customData) {
172
+ if (matchesConditions(item, watch.conditions)) {
173
+ matches.push({ id: String(item.id ?? "unknown"), ...item });
174
+ }
175
+ }
176
+ }
177
+ break;
178
+ }
179
+ }
180
+ return matches;
181
+ }
182
+ function matchesConditions(record, conditions) {
183
+ const now = Date.now();
184
+ const sevenDaysAgo = now - 7 * 24 * 60 * 60 * 1000;
185
+ for (const condition of conditions) {
186
+ const fieldValue = record[condition.field];
187
+ let compareValue = condition.value;
188
+ if (compareValue === "{{now}}")
189
+ compareValue = new Date().toISOString();
190
+ if (compareValue === "{{7daysAgo}}")
191
+ compareValue = new Date(sevenDaysAgo).toISOString();
192
+ switch (condition.operator) {
193
+ case "eq":
194
+ if (fieldValue !== compareValue)
195
+ return false;
196
+ break;
197
+ case "ne":
198
+ if (fieldValue === compareValue)
199
+ return false;
200
+ break;
201
+ case "gt":
202
+ if (!(Number(fieldValue) > Number(compareValue)))
203
+ return false;
204
+ break;
205
+ case "lt":
206
+ if (!(String(fieldValue) < String(compareValue)))
207
+ return false;
208
+ break;
209
+ case "contains":
210
+ if (!String(fieldValue ?? "").includes(String(compareValue)))
211
+ return false;
212
+ break;
213
+ case "exists":
214
+ if ((fieldValue == null) !== !compareValue)
215
+ return false;
216
+ break;
217
+ }
218
+ }
219
+ return true;
220
+ }
221
+ function interpolateTemplate(template, entity) {
222
+ let result = template;
223
+ for (const [key, value] of Object.entries(entity)) {
224
+ result = result.replace(new RegExp(`\\{\\{${key}\\}\\}`, "g"), String(value ?? ""));
225
+ }
226
+ return result;
227
+ }
228
+ // --- Dedup & rate limiting ---
229
+ async function checkDedup(ctx, watchId, entityId, windowMs) {
230
+ const log = await ctx.state.get({
231
+ scopeKind: "instance",
232
+ stateKey: `suggestion_log_${watchId}_${entityId}`,
233
+ });
234
+ if (!log)
235
+ return false;
236
+ const sentAt = new Date(log.sentAt).getTime();
237
+ return Date.now() - sentAt < windowMs;
238
+ }
239
+ async function recordSuggestion(ctx, watchId, entityId) {
240
+ const log = {
241
+ watchId,
242
+ entityId,
243
+ sentAt: new Date().toISOString(),
244
+ };
245
+ await ctx.state.set({ scopeKind: "instance", stateKey: `suggestion_log_${watchId}_${entityId}` }, log);
246
+ }
247
+ async function getHourlySuggestionCount(ctx, companyId) {
248
+ const key = `suggestion_hourly_${companyId}_${new Date().toISOString().slice(0, 13)}`;
249
+ const count = await ctx.state.get({
250
+ scopeKind: "instance",
251
+ stateKey: key,
252
+ });
253
+ return count ?? 0;
254
+ }
255
+ async function incrementHourlySuggestionCount(ctx, companyId, amount) {
256
+ const key = `suggestion_hourly_${companyId}_${new Date().toISOString().slice(0, 13)}`;
257
+ const current = await getHourlySuggestionCount(ctx, companyId);
258
+ await ctx.state.set({ scopeKind: "instance", stateKey: key }, current + amount);
259
+ }
260
+ // --- State helpers ---
261
+ async function getWatchRegistry(ctx, companyId) {
262
+ const watches = await ctx.state.get({
263
+ scopeKind: "company",
264
+ scopeId: companyId,
265
+ stateKey: `watches_${companyId}`,
266
+ });
267
+ return watches ?? [];
268
+ }
269
+ async function saveWatchRegistry(ctx, companyId, watches) {
270
+ await ctx.state.set({ scopeKind: "company", scopeId: companyId, stateKey: `watches_${companyId}` }, watches);
271
+ }
272
+ //# sourceMappingURL=watch-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-registry.js","sourceRoot":"","sources":["../src/watch-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};