@adriangalilea/utils 0.8.0 → 0.10.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/README.md +29 -1
- package/dist/bot/access-control.d.ts +17 -6
- package/dist/bot/access-control.d.ts.map +1 -1
- package/dist/bot/access-control.js +155 -76
- package/dist/bot/access-control.js.map +1 -1
- package/dist/bot/kit.d.ts +32 -0
- package/dist/bot/kit.d.ts.map +1 -1
- package/dist/bot/kit.js +32 -0
- package/dist/bot/kit.js.map +1 -1
- package/dist/bot/language.d.ts +28 -2
- package/dist/bot/language.d.ts.map +1 -1
- package/dist/bot/language.js +59 -18
- package/dist/bot/language.js.map +1 -1
- package/dist/bot/llm-stream.d.ts +2 -0
- package/dist/bot/llm-stream.d.ts.map +1 -1
- package/dist/bot/llm-stream.js +7 -0
- package/dist/bot/llm-stream.js.map +1 -1
- package/dist/bot/menu.d.ts +15 -1
- package/dist/bot/menu.d.ts.map +1 -1
- package/dist/bot/menu.js +76 -24
- package/dist/bot/menu.js.map +1 -1
- package/dist/bot/message-history.d.ts +41 -21
- package/dist/bot/message-history.d.ts.map +1 -1
- package/dist/bot/message-history.js +60 -29
- package/dist/bot/message-history.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/say/index.d.ts +62 -0
- package/dist/say/index.d.ts.map +1 -0
- package/dist/say/index.js +59 -0
- package/dist/say/index.js.map +1 -0
- package/package.json +5 -1
package/dist/bot/menu.js
CHANGED
|
@@ -67,10 +67,14 @@
|
|
|
67
67
|
* .extend(menu.plugin)
|
|
68
68
|
*/
|
|
69
69
|
import { CallbackData, InlineKeyboard, Plugin, } from 'gramio';
|
|
70
|
+
import { say } from '../say/index.js';
|
|
71
|
+
import { inThread } from './kit.js';
|
|
72
|
+
const FALLBACK_LANG = 'en';
|
|
73
|
+
const ctxLang = (ctx) => ctx.session?.language ?? FALLBACK_LANG;
|
|
70
74
|
const DEFAULT_COMMAND = 'settings';
|
|
71
75
|
const DEFAULT_DESCRIPTION = 'Open settings menu';
|
|
72
76
|
const DEFAULT_PRIVACY_URL = 'https://telegram.org/privacy-tpa';
|
|
73
|
-
const DEFAULT_HEADER = '⚙️ Settings';
|
|
77
|
+
const DEFAULT_HEADER = { en: '⚙️ Settings', es: '⚙️ Ajustes' };
|
|
74
78
|
const DEFAULT_SESSION_KEY = (userId) => String(userId);
|
|
75
79
|
// ─── callback data schemas ─────────────────────────────────────────
|
|
76
80
|
const navCb = new CallbackData('mNav').string('path');
|
|
@@ -111,7 +115,12 @@ export class BotMenu {
|
|
|
111
115
|
}
|
|
112
116
|
export const botMenu = (opts) => new BotMenu(opts);
|
|
113
117
|
// ─── internal: rendering + plugin ──────────────────────────────────
|
|
114
|
-
const labelOf = (l, ctx) =>
|
|
118
|
+
const labelOf = (l, ctx) => {
|
|
119
|
+
const resolved = typeof l === 'function' ? l(ctx) : l;
|
|
120
|
+
if (typeof resolved === 'string')
|
|
121
|
+
return resolved;
|
|
122
|
+
return say(resolved, ctxLang(ctx));
|
|
123
|
+
};
|
|
115
124
|
const itemsForPath = (root, path) => {
|
|
116
125
|
if (path.length === 0)
|
|
117
126
|
return root;
|
|
@@ -155,28 +164,29 @@ const renderKeyboard = (menu, items, ctx, parentPath) => {
|
|
|
155
164
|
}
|
|
156
165
|
kb.row();
|
|
157
166
|
}
|
|
167
|
+
const lang = ctxLang(ctx);
|
|
158
168
|
if (parentPath.length === 0) {
|
|
159
169
|
// GDPR rights buttons at the root view.
|
|
160
170
|
if (menu._opts.personalData) {
|
|
161
|
-
kb.text('🗑 Forget my data', actCb.pack({ path: '_forget' }));
|
|
171
|
+
kb.text(say({ en: '🗑 Forget my data', es: '🗑 Olvidar mis datos' }, lang), actCb.pack({ path: '_forget' }));
|
|
162
172
|
kb.row();
|
|
163
|
-
kb.text('📥 Export my data', exportCb.pack({}));
|
|
173
|
+
kb.text(say({ en: '📥 Export my data', es: '📥 Exportar mis datos' }, lang), exportCb.pack({}));
|
|
164
174
|
kb.row();
|
|
165
175
|
}
|
|
166
176
|
// Privacy link.
|
|
167
|
-
kb.url('📖 Privacy', menu._opts.privacy);
|
|
177
|
+
kb.url(say({ en: '📖 Privacy', es: '📖 Privacidad' }, lang), menu._opts.privacy);
|
|
168
178
|
kb.row();
|
|
169
179
|
}
|
|
170
180
|
else {
|
|
171
181
|
const backPath = parentPath.slice(0, -1).join('.');
|
|
172
|
-
kb.text('⬅️ Back', navCb.pack({ path: backPath || '_root' }));
|
|
182
|
+
kb.text(say({ en: '⬅️ Back', es: '⬅️ Volver' }, lang), navCb.pack({ path: backPath || '_root' }));
|
|
173
183
|
}
|
|
174
184
|
return kb;
|
|
175
185
|
};
|
|
176
|
-
const renderConfirmForget = () => new InlineKeyboard()
|
|
177
|
-
.text('✅ Confirm delete', forgetConfirmCb.pack({}))
|
|
186
|
+
const renderConfirmForget = (lang) => new InlineKeyboard()
|
|
187
|
+
.text(say({ en: '✅ Confirm delete', es: '✅ Confirmar borrado' }, lang), forgetConfirmCb.pack({}))
|
|
178
188
|
.row()
|
|
179
|
-
.text('⬅️ Cancel', forgetCancelCb.pack({}));
|
|
189
|
+
.text(say({ en: '⬅️ Cancel', es: '⬅️ Cancelar' }, lang), forgetCancelCb.pack({}));
|
|
180
190
|
const buildMenuPlugin = (menu) => {
|
|
181
191
|
const { command, description, header, personalData, adminContact } = menu._opts;
|
|
182
192
|
return new Plugin('@adriangalilea/utils/bot/menu')
|
|
@@ -186,11 +196,14 @@ const buildMenuPlugin = (menu) => {
|
|
|
186
196
|
})
|
|
187
197
|
// Navigate (root / submenu)
|
|
188
198
|
.callbackQuery(navCb, async (ctx) => {
|
|
199
|
+
const lang = ctxLang(ctx);
|
|
189
200
|
const raw = ctx.queryData.path;
|
|
190
201
|
const segments = raw === '_root' ? [] : raw.split('.');
|
|
191
202
|
const items = itemsForPath(menu._items, segments);
|
|
192
203
|
if (!items) {
|
|
193
|
-
await ctx.answer({
|
|
204
|
+
await ctx.answer({
|
|
205
|
+
text: say({ en: 'Menu out of date.', es: 'Menú obsoleto.' }, lang),
|
|
206
|
+
});
|
|
194
207
|
return;
|
|
195
208
|
}
|
|
196
209
|
await ctx.answer({});
|
|
@@ -204,13 +217,19 @@ const buildMenuPlugin = (menu) => {
|
|
|
204
217
|
})
|
|
205
218
|
// Action items + the forget pre-confirmation
|
|
206
219
|
.callbackQuery(actCb, async (ctx) => {
|
|
220
|
+
const lang = ctxLang(ctx);
|
|
207
221
|
const raw = ctx.queryData.path;
|
|
208
222
|
if (raw === '_forget') {
|
|
209
223
|
await ctx.answer({});
|
|
210
224
|
try {
|
|
211
|
-
await ctx.editText(
|
|
212
|
-
'
|
|
213
|
-
|
|
225
|
+
await ctx.editText(say({
|
|
226
|
+
en: '⚠️ Delete all your data?\n\n' +
|
|
227
|
+
'This removes the session record we keep about you ' +
|
|
228
|
+
'(preferences, history, access state). Not reversible.',
|
|
229
|
+
es: '⚠️ ¿Borrar todos tus datos?\n\n' +
|
|
230
|
+
'Esto elimina el registro de sesión que guardamos sobre ti ' +
|
|
231
|
+
'(preferencias, historial, estado de acceso). No se puede deshacer.',
|
|
232
|
+
}, lang), { reply_markup: renderConfirmForget(lang) });
|
|
214
233
|
}
|
|
215
234
|
catch {
|
|
216
235
|
/* ignore */
|
|
@@ -219,7 +238,9 @@ const buildMenuPlugin = (menu) => {
|
|
|
219
238
|
}
|
|
220
239
|
const item = itemForPath(menu._items, raw.split('.'));
|
|
221
240
|
if (!item || !('action' in item)) {
|
|
222
|
-
await ctx.answer({
|
|
241
|
+
await ctx.answer({
|
|
242
|
+
text: say({ en: 'Item not found.', es: 'Elemento no encontrado.' }, lang),
|
|
243
|
+
});
|
|
223
244
|
return;
|
|
224
245
|
}
|
|
225
246
|
await ctx.answer({});
|
|
@@ -227,18 +248,29 @@ const buildMenuPlugin = (menu) => {
|
|
|
227
248
|
})
|
|
228
249
|
// Forget — confirm path
|
|
229
250
|
.callbackQuery(forgetConfirmCb, async (ctx) => {
|
|
251
|
+
const lang = ctxLang(ctx);
|
|
230
252
|
if (!personalData) {
|
|
231
|
-
await ctx.answer({
|
|
253
|
+
await ctx.answer({
|
|
254
|
+
text: say({ en: 'Not configured.', es: 'No configurado.' }, lang),
|
|
255
|
+
show_alert: true,
|
|
256
|
+
});
|
|
232
257
|
return;
|
|
233
258
|
}
|
|
234
259
|
const userId = ctx.from?.id;
|
|
235
260
|
if (userId === undefined)
|
|
236
|
-
return ctx.answer({
|
|
261
|
+
return ctx.answer({
|
|
262
|
+
text: say({ en: 'No user.', es: 'Sin usuario.' }, lang),
|
|
263
|
+
});
|
|
237
264
|
try {
|
|
238
265
|
await personalData.storage.delete(personalData.sessionKey(userId));
|
|
239
|
-
await ctx.answer({
|
|
266
|
+
await ctx.answer({
|
|
267
|
+
text: say({ en: 'Deleted.', es: 'Borrado.' }, lang),
|
|
268
|
+
});
|
|
240
269
|
try {
|
|
241
|
-
await ctx.editText(
|
|
270
|
+
await ctx.editText(say({
|
|
271
|
+
en: '✅ Your data has been deleted.',
|
|
272
|
+
es: '✅ Tus datos han sido borrados.',
|
|
273
|
+
}, lang));
|
|
242
274
|
}
|
|
243
275
|
catch {
|
|
244
276
|
/* ignore */
|
|
@@ -246,8 +278,13 @@ const buildMenuPlugin = (menu) => {
|
|
|
246
278
|
}
|
|
247
279
|
catch (e) {
|
|
248
280
|
console.error('[menu] /forget failed', e);
|
|
249
|
-
await ctx.answer({
|
|
250
|
-
|
|
281
|
+
await ctx.answer({
|
|
282
|
+
text: say({ en: 'Failed.', es: 'Falló.' }, lang),
|
|
283
|
+
});
|
|
284
|
+
await ctx.send(say({
|
|
285
|
+
en: `❌ Could not delete your data.\n\nPlease contact ${adminContact}.`,
|
|
286
|
+
es: `❌ No se han podido borrar tus datos.\n\nContacta con ${adminContact}.`,
|
|
287
|
+
}, lang));
|
|
251
288
|
}
|
|
252
289
|
})
|
|
253
290
|
.callbackQuery(forgetCancelCb, async (ctx) => {
|
|
@@ -262,22 +299,37 @@ const buildMenuPlugin = (menu) => {
|
|
|
262
299
|
})
|
|
263
300
|
// Export — JSON file with the user's whole session record
|
|
264
301
|
.callbackQuery(exportCb, async (ctx) => {
|
|
302
|
+
const lang = ctxLang(ctx);
|
|
265
303
|
if (!personalData) {
|
|
266
|
-
await ctx.answer({
|
|
304
|
+
await ctx.answer({
|
|
305
|
+
text: say({ en: 'Not configured.', es: 'No configurado.' }, lang),
|
|
306
|
+
show_alert: true,
|
|
307
|
+
});
|
|
267
308
|
return;
|
|
268
309
|
}
|
|
269
310
|
const userId = ctx.from?.id;
|
|
270
311
|
if (userId === undefined)
|
|
271
|
-
return ctx.answer({
|
|
312
|
+
return ctx.answer({
|
|
313
|
+
text: say({ en: 'No user.', es: 'Sin usuario.' }, lang),
|
|
314
|
+
});
|
|
272
315
|
const record = (await personalData.storage.get(personalData.sessionKey(userId))) ?? {};
|
|
273
316
|
const file = new File([JSON.stringify({ userId, exportedAt: Date.now(), data: record }, null, 2)], `my-data-${userId}-${Date.now()}.json`, { type: 'application/json' });
|
|
274
317
|
await ctx.answer({});
|
|
275
318
|
try {
|
|
276
|
-
await ctx.sendDocument(file, {
|
|
319
|
+
await ctx.sendDocument(file, {
|
|
320
|
+
caption: say({ en: '📥 Your data export', es: '📥 Exportación de tus datos' }, lang),
|
|
321
|
+
// Land the file in the same thread the menu was opened from.
|
|
322
|
+
// Callback ctx exposes the thread via ctx.message.threadId;
|
|
323
|
+
// inThread() handles both shapes.
|
|
324
|
+
...inThread(ctx),
|
|
325
|
+
});
|
|
277
326
|
}
|
|
278
327
|
catch (e) {
|
|
279
328
|
console.error('[menu] /export sendDocument failed', e);
|
|
280
|
-
await ctx.send(
|
|
329
|
+
await ctx.send(say({
|
|
330
|
+
en: `❌ Could not send your data export.\n\nPlease contact ${adminContact}.`,
|
|
331
|
+
es: `❌ No se ha podido enviar la exportación de tus datos.\n\nContacta con ${adminContact}.`,
|
|
332
|
+
}, lang));
|
|
281
333
|
}
|
|
282
334
|
});
|
|
283
335
|
};
|
package/dist/bot/menu.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/bot/menu.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/bot/menu.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Per-user rolling message history for GramIO bots — opt-in, with
|
|
3
|
-
* retention
|
|
3
|
+
* retention, **sharded by thread**.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Each user has one session record. Inside that record, `history` keeps
|
|
6
|
+
* a separate ring buffer per thread:
|
|
7
|
+
*
|
|
8
|
+
* storage[userId].history.shards = {
|
|
9
|
+
* 'general': [ ...entries from no-thread messages ],
|
|
10
|
+
* '12345': [ ...entries from message_thread_id=12345 ],
|
|
11
|
+
* '98765': [ ...entries from message_thread_id=98765 ],
|
|
12
|
+
* }
|
|
13
|
+
*
|
|
14
|
+
* This makes the plugin compatible with both forum-supergroup topics
|
|
15
|
+
* and BotFather's Threaded Mode for private chats (which is the whole
|
|
16
|
+
* point of those features: parallel conversations with separate
|
|
17
|
+
* context). `ctx.history` returns ONLY the slice for the current
|
|
18
|
+
* thread; `ctx.allHistory` returns the full sharded map when you need
|
|
19
|
+
* a cross-thread view (e.g. for `/export`).
|
|
20
|
+
*
|
|
21
|
+
* Thread key: `String(ctx.threadId)`, or `'general'` when no thread.
|
|
9
22
|
*
|
|
10
23
|
* ## What this plugin owns
|
|
11
24
|
*
|
|
12
|
-
* - Appends each incoming user message to
|
|
13
|
-
* - Prunes
|
|
14
|
-
* - Exposes
|
|
25
|
+
* - Appends each incoming user message to the shard for its thread
|
|
26
|
+
* - Prunes per-shard by `retentionDays` and `maxMessages`
|
|
27
|
+
* - Exposes `ctx.history` (current thread's pruned slice) and
|
|
28
|
+
* `ctx.allHistory` (full map) to handlers
|
|
15
29
|
*
|
|
16
30
|
* ## GDPR caveat — retention IS personal data
|
|
17
31
|
*
|
|
@@ -29,15 +43,6 @@
|
|
|
29
43
|
* These are not enforced by this plugin (would couple it to menu); they
|
|
30
44
|
* are documented as the bot author's legal responsibility.
|
|
31
45
|
*
|
|
32
|
-
* ## Storage layout
|
|
33
|
-
*
|
|
34
|
-
* Lives entirely inside the shared session record:
|
|
35
|
-
*
|
|
36
|
-
* storage[String(senderId)] = {
|
|
37
|
-
* ...other plugins' fields,
|
|
38
|
-
* history: { items: [HistoryEntry, ...] }
|
|
39
|
-
* }
|
|
40
|
-
*
|
|
41
46
|
* Peer deps: `gramio`, `@gramio/session`.
|
|
42
47
|
*
|
|
43
48
|
* @example
|
|
@@ -50,7 +55,7 @@
|
|
|
50
55
|
*
|
|
51
56
|
* const history = messageHistory({
|
|
52
57
|
* session: userSession,
|
|
53
|
-
* maxMessages: 100,
|
|
58
|
+
* maxMessages: 100, // cap per-thread
|
|
54
59
|
* retentionDays: 7,
|
|
55
60
|
* })
|
|
56
61
|
*
|
|
@@ -59,7 +64,7 @@
|
|
|
59
64
|
* .extend(history.plugin)
|
|
60
65
|
* .command('replay', (ctx) => {
|
|
61
66
|
* const last = ctx.history.slice(-3).map((e) => e.text).join('\n---\n')
|
|
62
|
-
* return ctx.send(last || '(no history)')
|
|
67
|
+
* return ctx.send(last || '(no history in this thread)')
|
|
63
68
|
* })
|
|
64
69
|
*/
|
|
65
70
|
import { type DeriveDefinitions, Plugin } from 'gramio';
|
|
@@ -72,8 +77,15 @@ export type HistoryEntry = {
|
|
|
72
77
|
/** Message text, or empty string if non-text. */
|
|
73
78
|
text: string;
|
|
74
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* Per-thread shards. Key is `String(ctx.threadId)` or `'general'`
|
|
82
|
+
* when no thread. Each shard is an independently capped + pruned
|
|
83
|
+
* ring buffer.
|
|
84
|
+
*/
|
|
75
85
|
export type HistoryRecord = {
|
|
76
|
-
|
|
86
|
+
shards: {
|
|
87
|
+
[threadKey: string]: HistoryEntry[];
|
|
88
|
+
};
|
|
77
89
|
};
|
|
78
90
|
/** Loose session shape — this plugin only touches the `history` field. */
|
|
79
91
|
type SessionLike = {
|
|
@@ -87,7 +99,7 @@ export type MessageHistoryOptions = {
|
|
|
87
99
|
* gramio's runtime dedup ensures it only runs once per update.
|
|
88
100
|
*/
|
|
89
101
|
session: HistorySessionPluginRef;
|
|
90
|
-
/** Ring buffer cap
|
|
102
|
+
/** Ring buffer cap **per thread**. Oldest entries dropped when exceeded. */
|
|
91
103
|
maxMessages: number;
|
|
92
104
|
/** Entries older than this (in days) are dropped on read. */
|
|
93
105
|
retentionDays: number;
|
|
@@ -96,7 +108,15 @@ export type MessageHistoryFeature = {
|
|
|
96
108
|
plugin: ReturnType<typeof buildHistoryPlugin>;
|
|
97
109
|
};
|
|
98
110
|
type HistoryDerives = {
|
|
111
|
+
/** Pruned snapshot for the CURRENT thread only. */
|
|
99
112
|
history: ReadonlyArray<HistoryEntry>;
|
|
113
|
+
/**
|
|
114
|
+
* Pruned snapshot of all threads, keyed by thread (`'general'` or
|
|
115
|
+
* stringified threadId). Use for cross-thread views (e.g. /export).
|
|
116
|
+
*/
|
|
117
|
+
allHistory: Readonly<{
|
|
118
|
+
[threadKey: string]: ReadonlyArray<HistoryEntry>;
|
|
119
|
+
}>;
|
|
100
120
|
};
|
|
101
121
|
export declare const messageHistory: (opts: MessageHistoryOptions) => MessageHistoryFeature;
|
|
102
122
|
declare const buildHistoryPlugin: (args: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-history.d.ts","sourceRoot":"","sources":["../../src/bot/message-history.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"message-history.d.ts","sourceRoot":"","sources":["../../src/bot/message-history.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AACH,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAIzC,MAAM,MAAM,YAAY,GAAG;IACzB,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAA;IACZ,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE;QAAE,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,EAAE,CAAA;KAAE,CAAA;CAChD,CAAA;AAaD,0EAA0E;AAC1E,KAAK,WAAW,GAAG;IAAE,OAAO,CAAC,EAAE,aAAa,CAAA;CAAE,CAAA;AAE9C,wEAAwE;AACxE,KAAK,uBAAuB,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAA;AAEjF,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;OAGG;IACH,OAAO,EAAE,uBAAuB,CAAA;IAChC,4EAA4E;IAC5E,WAAW,EAAE,MAAM,CAAA;IACnB,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAA;CAC9C,CAAA;AAID,KAAK,cAAc,GAAG;IACpB,mDAAmD;IACnD,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAA;IACpC;;;OAGG;IACH,UAAU,EAAE,QAAQ,CAAC;QAAE,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAAC,YAAY,CAAC,CAAA;KAAE,CAAC,CAAA;CAC3E,CAAA;AA6BD,eAAO,MAAM,cAAc,GAAI,MAAM,qBAAqB,KAAG,qBAW5D,CAAA;AAID,QAAA,MAAM,kBAAkB,GAAI,MAAM;IAChC,aAAa,EAAE,uBAAuB,CAAA;IACtC,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;CACtB;YAGqD,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAqCnE,CAAA"}
|
|
@@ -1,17 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Per-user rolling message history for GramIO bots — opt-in, with
|
|
3
|
-
* retention
|
|
3
|
+
* retention, **sharded by thread**.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Each user has one session record. Inside that record, `history` keeps
|
|
6
|
+
* a separate ring buffer per thread:
|
|
7
|
+
*
|
|
8
|
+
* storage[userId].history.shards = {
|
|
9
|
+
* 'general': [ ...entries from no-thread messages ],
|
|
10
|
+
* '12345': [ ...entries from message_thread_id=12345 ],
|
|
11
|
+
* '98765': [ ...entries from message_thread_id=98765 ],
|
|
12
|
+
* }
|
|
13
|
+
*
|
|
14
|
+
* This makes the plugin compatible with both forum-supergroup topics
|
|
15
|
+
* and BotFather's Threaded Mode for private chats (which is the whole
|
|
16
|
+
* point of those features: parallel conversations with separate
|
|
17
|
+
* context). `ctx.history` returns ONLY the slice for the current
|
|
18
|
+
* thread; `ctx.allHistory` returns the full sharded map when you need
|
|
19
|
+
* a cross-thread view (e.g. for `/export`).
|
|
20
|
+
*
|
|
21
|
+
* Thread key: `String(ctx.threadId)`, or `'general'` when no thread.
|
|
9
22
|
*
|
|
10
23
|
* ## What this plugin owns
|
|
11
24
|
*
|
|
12
|
-
* - Appends each incoming user message to
|
|
13
|
-
* - Prunes
|
|
14
|
-
* - Exposes
|
|
25
|
+
* - Appends each incoming user message to the shard for its thread
|
|
26
|
+
* - Prunes per-shard by `retentionDays` and `maxMessages`
|
|
27
|
+
* - Exposes `ctx.history` (current thread's pruned slice) and
|
|
28
|
+
* `ctx.allHistory` (full map) to handlers
|
|
15
29
|
*
|
|
16
30
|
* ## GDPR caveat — retention IS personal data
|
|
17
31
|
*
|
|
@@ -29,15 +43,6 @@
|
|
|
29
43
|
* These are not enforced by this plugin (would couple it to menu); they
|
|
30
44
|
* are documented as the bot author's legal responsibility.
|
|
31
45
|
*
|
|
32
|
-
* ## Storage layout
|
|
33
|
-
*
|
|
34
|
-
* Lives entirely inside the shared session record:
|
|
35
|
-
*
|
|
36
|
-
* storage[String(senderId)] = {
|
|
37
|
-
* ...other plugins' fields,
|
|
38
|
-
* history: { items: [HistoryEntry, ...] }
|
|
39
|
-
* }
|
|
40
|
-
*
|
|
41
46
|
* Peer deps: `gramio`, `@gramio/session`.
|
|
42
47
|
*
|
|
43
48
|
* @example
|
|
@@ -50,7 +55,7 @@
|
|
|
50
55
|
*
|
|
51
56
|
* const history = messageHistory({
|
|
52
57
|
* session: userSession,
|
|
53
|
-
* maxMessages: 100,
|
|
58
|
+
* maxMessages: 100, // cap per-thread
|
|
54
59
|
* retentionDays: 7,
|
|
55
60
|
* })
|
|
56
61
|
*
|
|
@@ -59,16 +64,31 @@
|
|
|
59
64
|
* .extend(history.plugin)
|
|
60
65
|
* .command('replay', (ctx) => {
|
|
61
66
|
* const last = ctx.history.slice(-3).map((e) => e.text).join('\n---\n')
|
|
62
|
-
* return ctx.send(last || '(no history)')
|
|
67
|
+
* return ctx.send(last || '(no history in this thread)')
|
|
63
68
|
* })
|
|
64
69
|
*/
|
|
65
70
|
import { Plugin } from 'gramio';
|
|
71
|
+
const GENERAL_THREAD = 'general';
|
|
72
|
+
const threadKey = (ctx) => {
|
|
73
|
+
// Message events: ctx.threadId. Callback events: ctx.message.threadId.
|
|
74
|
+
const tid = ctx.threadId ?? ctx.message?.threadId;
|
|
75
|
+
return tid !== undefined ? String(tid) : GENERAL_THREAD;
|
|
76
|
+
};
|
|
66
77
|
// ─── helpers ───────────────────────────────────────────────────────
|
|
67
78
|
const prune = (items, maxMessages, retentionDays) => {
|
|
68
79
|
const cutoffSec = Math.floor(Date.now() / 1000) - retentionDays * 86400;
|
|
69
80
|
const fresh = items.filter((e) => e.date >= cutoffSec);
|
|
70
81
|
return fresh.slice(-maxMessages);
|
|
71
82
|
};
|
|
83
|
+
const pruneAll = (shards, maxMessages, retentionDays) => {
|
|
84
|
+
const out = {};
|
|
85
|
+
for (const k of Object.keys(shards)) {
|
|
86
|
+
const pruned = prune(shards[k], maxMessages, retentionDays);
|
|
87
|
+
if (pruned.length > 0)
|
|
88
|
+
out[k] = pruned;
|
|
89
|
+
}
|
|
90
|
+
return out;
|
|
91
|
+
};
|
|
72
92
|
// ─── feature factory ───────────────────────────────────────────────
|
|
73
93
|
export const messageHistory = (opts) => {
|
|
74
94
|
if (opts.maxMessages <= 0)
|
|
@@ -87,8 +107,9 @@ const buildHistoryPlugin = (args) => {
|
|
|
87
107
|
const { sessionPlugin, maxMessages, retentionDays } = args;
|
|
88
108
|
return new Plugin('@adriangalilea/utils/bot/message-history')
|
|
89
109
|
.extend(sessionPlugin)
|
|
90
|
-
// Record incoming messages with text
|
|
91
|
-
// and callback queries don't append —
|
|
110
|
+
// Record incoming messages with text into their thread's shard.
|
|
111
|
+
// Service messages, edits, and callback queries don't append —
|
|
112
|
+
// only direct user input.
|
|
92
113
|
.on('message', async (ctx, next) => {
|
|
93
114
|
if (ctx.text !== undefined) {
|
|
94
115
|
const entry = {
|
|
@@ -96,16 +117,26 @@ const buildHistoryPlugin = (args) => {
|
|
|
96
117
|
date: ctx.payload.date,
|
|
97
118
|
text: ctx.text,
|
|
98
119
|
};
|
|
99
|
-
const
|
|
100
|
-
ctx.session.history
|
|
101
|
-
|
|
102
|
-
|
|
120
|
+
const key = threadKey(ctx);
|
|
121
|
+
const shards = { ...(ctx.session.history?.shards ?? {}) };
|
|
122
|
+
const cur = shards[key] ?? [];
|
|
123
|
+
shards[key] = [
|
|
124
|
+
...prune(cur, maxMessages, retentionDays),
|
|
125
|
+
entry,
|
|
126
|
+
].slice(-maxMessages);
|
|
127
|
+
ctx.session.history = { shards };
|
|
103
128
|
}
|
|
104
129
|
return next();
|
|
105
130
|
})
|
|
106
|
-
//
|
|
107
|
-
.derive(['message', 'callback_query'], (ctx) =>
|
|
108
|
-
|
|
109
|
-
|
|
131
|
+
// Read-only views for handlers downstream.
|
|
132
|
+
.derive(['message', 'callback_query'], (ctx) => {
|
|
133
|
+
const shards = ctx.session.history?.shards ?? {};
|
|
134
|
+
const allPruned = pruneAll(shards, maxMessages, retentionDays);
|
|
135
|
+
const key = threadKey(ctx);
|
|
136
|
+
return {
|
|
137
|
+
history: (allPruned[key] ?? []),
|
|
138
|
+
allHistory: allPruned,
|
|
139
|
+
};
|
|
140
|
+
});
|
|
110
141
|
};
|
|
111
142
|
//# sourceMappingURL=message-history.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-history.js","sourceRoot":"","sources":["../../src/bot/message-history.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"message-history.js","sourceRoot":"","sources":["../../src/bot/message-history.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export * from './universal/log.js';
|
|
|
8
8
|
export * from './universal/format.js';
|
|
9
9
|
export * from './universal/currency/index.js';
|
|
10
10
|
export * from './offensive.js';
|
|
11
|
+
export * from './say/index.js';
|
|
11
12
|
export * from './platform/file.js';
|
|
12
13
|
export * from './platform/dir.js';
|
|
13
14
|
export * from './platform/path.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,YAAY,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAGvD,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,+BAA+B,CAAA;AAG7C,cAAc,gBAAgB,CAAA;AAI9B,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,sBAAsB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,YAAY,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAGvD,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,+BAA+B,CAAA;AAG7C,cAAc,gBAAgB,CAAA;AAG9B,cAAc,gBAAgB,CAAA;AAI9B,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,sBAAsB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,8 @@ export * from './universal/format.js';
|
|
|
10
10
|
export * from './universal/currency/index.js';
|
|
11
11
|
// Offensive programming - pure throws, zero dependencies
|
|
12
12
|
export * from './offensive.js';
|
|
13
|
+
// Polyglot strings — TS-enforced multi-language values
|
|
14
|
+
export * from './say/index.js';
|
|
13
15
|
// Platform-specific utilities
|
|
14
16
|
// These will throw helpful errors in browser environment when used
|
|
15
17
|
export * from './platform/file.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,8CAA8C;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAGtC,wCAAwC;AACxC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,+BAA+B,CAAA;AAE7C,yDAAyD;AACzD,cAAc,gBAAgB,CAAA;AAE9B,8BAA8B;AAC9B,mEAAmE;AACnE,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,sBAAsB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,8CAA8C;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAGtC,wCAAwC;AACxC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,+BAA+B,CAAA;AAE7C,yDAAyD;AACzD,cAAc,gBAAgB,CAAA;AAE9B,uDAAuD;AACvD,cAAc,gBAAgB,CAAA;AAE9B,8BAA8B;AAC9B,mEAAmE;AACnE,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `say` — TypeScript-enforced polyglot strings, framework-agnostic.
|
|
3
|
+
*
|
|
4
|
+
* A "polyglot value" is a plain object literal with one string per
|
|
5
|
+
* supported language:
|
|
6
|
+
*
|
|
7
|
+
* { en: 'Hello', es: 'Hola' }
|
|
8
|
+
*
|
|
9
|
+
* The keys are the source of truth. There is no JSON file, no key
|
|
10
|
+
* registry, no extraction tool, no namespaces. The TS compiler
|
|
11
|
+
* enforces completeness: add a language to the plugin's `supported`
|
|
12
|
+
* list and every call site without that key becomes a compile error.
|
|
13
|
+
*
|
|
14
|
+
* Two entry points:
|
|
15
|
+
*
|
|
16
|
+
* `say(value, lang)` — pure resolver, no context, returns string.
|
|
17
|
+
* Use it for 3rd-party SDKs / cron / email
|
|
18
|
+
* / anything outside a bot ctx.
|
|
19
|
+
*
|
|
20
|
+
* `ctx.say(value)` — bot-bound; uses `ctx.lang`. Provided by
|
|
21
|
+
* `bot/language` (see that plugin for the
|
|
22
|
+
* `ctx.say.send / .edit / .answer` methods).
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* import { say, type Polyglot } from '@adriangalilea/utils/say'
|
|
26
|
+
*
|
|
27
|
+
* await pushover.send({
|
|
28
|
+
* message: say({ en: 'Drop!', es: '¡Drop!' }, user.lang),
|
|
29
|
+
* })
|
|
30
|
+
*
|
|
31
|
+
* // typing your own adapter:
|
|
32
|
+
* const notify = (msg: string | Polyglot<'en' | 'es'>, lang: 'en' | 'es') =>
|
|
33
|
+
* transport.send(typeof msg === 'string' ? msg : say(msg, lang))
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* A value that exists in N languages. `L` is the union of supported
|
|
37
|
+
* language tags (typically inferred from the object literal's keys).
|
|
38
|
+
*
|
|
39
|
+
* Authoring: `{ en: 'Hi', es: 'Hola' }` — TS infers `L = 'en' | 'es'`.
|
|
40
|
+
*
|
|
41
|
+
* Typing your own API: `function notify(msg: Polyglot<'en' | 'es'>)`
|
|
42
|
+
* — callers must provide both keys.
|
|
43
|
+
*/
|
|
44
|
+
export type Polyglot<L extends string> = Readonly<Record<L, string>>;
|
|
45
|
+
/**
|
|
46
|
+
* Resolve a polyglot value to a string at `lang`.
|
|
47
|
+
*
|
|
48
|
+
* If `lang` is missing from `value`, returns the first available key
|
|
49
|
+
* (lexicographic). This is a structural fallback — it should never
|
|
50
|
+
* happen when `lang` is constrained by the same `L` as `value`'s
|
|
51
|
+
* keys; it exists only for the dynamic-string escape hatch.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* say({ en: 'Hi', es: 'Hola' }, 'es') // → 'Hola'
|
|
55
|
+
* say({ en: 'Hi', es: 'Hola' }, 'fr') // TS error: '"fr"' not in '"en" | "es"'
|
|
56
|
+
*
|
|
57
|
+
* @example // typing-loose escape hatch with `as Polyglot<string>`
|
|
58
|
+
* const raw: Polyglot<string> = JSON.parse(blob)
|
|
59
|
+
* say(raw, userLang) // dynamic, falls back if missing
|
|
60
|
+
*/
|
|
61
|
+
export declare const say: <L extends string>(value: Polyglot<L>, lang: L) => string;
|
|
62
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/say/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH;;;;;;;;GAQG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAA;AAEpE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,GAAG,GAAI,CAAC,SAAS,MAAM,EAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,KAAG,MAKnE,CAAA"}
|