ultra-telegram-framework 1.0.3
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/LICENSE +21 -0
- package/README.md +174 -0
- package/dist/adapters/gas.d.ts +10 -0
- package/dist/adapters/gas.js +90 -0
- package/dist/adapters/node.d.ts +52 -0
- package/dist/adapters/node.js +150 -0
- package/dist/adapters/web.d.ts +4 -0
- package/dist/adapters/web.js +90 -0
- package/dist/core/base-api.d.ts +40 -0
- package/dist/core/base-api.js +26 -0
- package/dist/core/bot.d.ts +1828 -0
- package/dist/core/bot.js +2753 -0
- package/dist/core/composer.d.ts +87 -0
- package/dist/core/composer.js +164 -0
- package/dist/core/context/base-context.d.ts +24 -0
- package/dist/core/context/base-context.js +56 -0
- package/dist/core/context/reply-context.d.ts +234 -0
- package/dist/core/context/reply-context.js +528 -0
- package/dist/core/context.d.ts +8 -0
- package/dist/core/context.js +34 -0
- package/dist/core/keyboard.d.ts +76 -0
- package/dist/core/keyboard.js +182 -0
- package/dist/core/menu.d.ts +58 -0
- package/dist/core/menu.js +87 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +24 -0
- package/dist/scenes/scene-manager.d.ts +39 -0
- package/dist/scenes/scene-manager.js +65 -0
- package/dist/scenes/stage.d.ts +8 -0
- package/dist/scenes/stage.js +34 -0
- package/dist/scenes/wizard.d.ts +18 -0
- package/dist/scenes/wizard.js +32 -0
- package/dist/session/gas-cache-storage.d.ts +34 -0
- package/dist/session/gas-cache-storage.js +49 -0
- package/dist/session/gas-hybrid-storage.d.ts +27 -0
- package/dist/session/gas-hybrid-storage.js +49 -0
- package/dist/session/gas-storage.d.ts +24 -0
- package/dist/session/gas-storage.js +47 -0
- package/dist/session/index.d.ts +28 -0
- package/dist/session/index.js +43 -0
- package/dist/session/memory-storage.d.ts +28 -0
- package/dist/session/memory-storage.js +35 -0
- package/dist/session/storage.d.ts +18 -0
- package/dist/session/storage.js +2 -0
- package/dist/types/telegram.d.ts +7560 -0
- package/dist/types/telegram.js +4 -0
- package/package.json +42 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { PropertiesStorage } from './gas-storage';
|
|
2
|
+
import { CacheStorage } from './gas-cache-storage';
|
|
3
|
+
/**
|
|
4
|
+
* Hybrid storage for Google Apps Script (CacheService + PropertiesService).
|
|
5
|
+
* Combines cache speed and properties reliability.
|
|
6
|
+
*/
|
|
7
|
+
export class GasHybridStorage {
|
|
8
|
+
/**
|
|
9
|
+
* Hybrid storage for Google Apps Script (CacheService + PropertiesService).
|
|
10
|
+
* Combines cache speed and properties reliability.
|
|
11
|
+
* @param options Configuration options
|
|
12
|
+
* @param options.cache Which cache service to use (ScriptCache by default)
|
|
13
|
+
* @param options.properties Which properties service to use (ScriptProperties by default)
|
|
14
|
+
* @param options.ttl Time to live in seconds (21600 - 6 hours by default)
|
|
15
|
+
* @param options.prefix Prefix for keys
|
|
16
|
+
*/
|
|
17
|
+
constructor(options) {
|
|
18
|
+
this.cache = new CacheStorage(options === null || options === void 0 ? void 0 : options.cache, options === null || options === void 0 ? void 0 : options.ttl, options === null || options === void 0 ? void 0 : options.prefix);
|
|
19
|
+
this.properties = new PropertiesStorage(options === null || options === void 0 ? void 0 : options.properties, options === null || options === void 0 ? void 0 : options.prefix);
|
|
20
|
+
}
|
|
21
|
+
async get(key) {
|
|
22
|
+
// 1. Try to get from the fast cache
|
|
23
|
+
let data = await Promise.resolve(this.cache.get(key));
|
|
24
|
+
if (data != null) {
|
|
25
|
+
return data;
|
|
26
|
+
}
|
|
27
|
+
// 2. If not in cache, go to slow properties
|
|
28
|
+
data = await Promise.resolve(this.properties.get(key));
|
|
29
|
+
// 3. If found in properties, update cache for next time
|
|
30
|
+
if (data !== null && data !== undefined) {
|
|
31
|
+
this.cache.set(key, data);
|
|
32
|
+
}
|
|
33
|
+
return data;
|
|
34
|
+
}
|
|
35
|
+
async set(key, value) {
|
|
36
|
+
// Write to both storages
|
|
37
|
+
await Promise.all([
|
|
38
|
+
Promise.resolve(this.cache.set(key, value)),
|
|
39
|
+
Promise.resolve(this.properties.set(key, value))
|
|
40
|
+
]);
|
|
41
|
+
}
|
|
42
|
+
async delete(key) {
|
|
43
|
+
// Delete from both places
|
|
44
|
+
await Promise.all([
|
|
45
|
+
Promise.resolve(this.cache.delete(key)),
|
|
46
|
+
Promise.resolve(this.properties.delete(key))
|
|
47
|
+
]);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Storage } from './storage';
|
|
2
|
+
/**
|
|
3
|
+
* Session storage for Google Apps Script based on PropertiesService.
|
|
4
|
+
* Allows storing state between different requests (doPost).
|
|
5
|
+
*
|
|
6
|
+
* ✅ Pros: reliable, no 6-hour limit, well-suited for large data
|
|
7
|
+
* ❌ Cons: slower than CacheService, has a limit of 500 requests/day
|
|
8
|
+
*/
|
|
9
|
+
export declare class PropertiesStorage<T> implements Storage<T> {
|
|
10
|
+
private service;
|
|
11
|
+
private prefix;
|
|
12
|
+
/**
|
|
13
|
+
* @param service Which service to use (ScriptProperties by default)
|
|
14
|
+
* @param prefix Prefix for keys in storage (to avoid mixing with other settings)
|
|
15
|
+
*/
|
|
16
|
+
constructor(service?: GoogleAppsScript.Properties.Properties, prefix?: string);
|
|
17
|
+
get(key: string): T | undefined;
|
|
18
|
+
set(key: string, value: T): void;
|
|
19
|
+
delete(key: string): void;
|
|
20
|
+
/**
|
|
21
|
+
* Clear ALL sessions with this prefix
|
|
22
|
+
*/
|
|
23
|
+
clearAll(): void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session storage for Google Apps Script based on PropertiesService.
|
|
3
|
+
* Allows storing state between different requests (doPost).
|
|
4
|
+
*
|
|
5
|
+
* ✅ Pros: reliable, no 6-hour limit, well-suited for large data
|
|
6
|
+
* ❌ Cons: slower than CacheService, has a limit of 500 requests/day
|
|
7
|
+
*/
|
|
8
|
+
export class PropertiesStorage {
|
|
9
|
+
/**
|
|
10
|
+
* @param service Which service to use (ScriptProperties by default)
|
|
11
|
+
* @param prefix Prefix for keys in storage (to avoid mixing with other settings)
|
|
12
|
+
*/
|
|
13
|
+
constructor(service = PropertiesService.getScriptProperties(), prefix = 'session:') {
|
|
14
|
+
this.service = service;
|
|
15
|
+
this.prefix = prefix;
|
|
16
|
+
}
|
|
17
|
+
get(key) {
|
|
18
|
+
const raw = this.service.getProperty(this.prefix + key);
|
|
19
|
+
if (!raw)
|
|
20
|
+
return undefined;
|
|
21
|
+
try {
|
|
22
|
+
return JSON.parse(raw);
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
console.error(`Error parsing session for key ${key}:`, e);
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
set(key, value) {
|
|
30
|
+
const raw = JSON.stringify(value);
|
|
31
|
+
this.service.setProperty(this.prefix + key, raw);
|
|
32
|
+
}
|
|
33
|
+
delete(key) {
|
|
34
|
+
this.service.deleteProperty(this.prefix + key);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Clear ALL sessions with this prefix
|
|
38
|
+
*/
|
|
39
|
+
clearAll() {
|
|
40
|
+
const all = this.service.getProperties();
|
|
41
|
+
for (const key in all) {
|
|
42
|
+
if (key.startsWith(this.prefix)) {
|
|
43
|
+
this.service.deleteProperty(key);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Context } from '../core/context';
|
|
2
|
+
import { Storage } from './storage';
|
|
3
|
+
export interface SessionData extends Record<string, unknown> {
|
|
4
|
+
}
|
|
5
|
+
declare module '../core/context' {
|
|
6
|
+
interface Context {
|
|
7
|
+
session?: SessionData;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export interface SessionOptions<S extends SessionData> {
|
|
11
|
+
/** Data storage (MemoryStorage by default) */
|
|
12
|
+
storage?: Storage<S>;
|
|
13
|
+
/** Key generation function ("chatId:userId" by default) */
|
|
14
|
+
getSessionKey?: (ctx: Context) => string | undefined;
|
|
15
|
+
/** Empty session initialization function (if data doesn't exist yet) */
|
|
16
|
+
initial: () => S;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Middleware for adding sessions to the context.
|
|
20
|
+
*/
|
|
21
|
+
export declare function SessionManager<S extends SessionData>(options: SessionOptions<S>): (ctx: Context & {
|
|
22
|
+
session: S;
|
|
23
|
+
}, next: () => Promise<void>) => Promise<void>;
|
|
24
|
+
export * from './storage';
|
|
25
|
+
export * from './memory-storage';
|
|
26
|
+
export * from './gas-storage';
|
|
27
|
+
export * from './gas-cache-storage';
|
|
28
|
+
export * from './gas-hybrid-storage';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { MemoryStorage } from './memory-storage';
|
|
2
|
+
/**
|
|
3
|
+
* Middleware for adding sessions to the context.
|
|
4
|
+
*/
|
|
5
|
+
export function SessionManager(options) {
|
|
6
|
+
const storage = options.storage || new MemoryStorage();
|
|
7
|
+
const getSessionKey = options.getSessionKey || ((ctx) => {
|
|
8
|
+
var _a;
|
|
9
|
+
const chatId = ctx.chatId;
|
|
10
|
+
const fromId = (_a = ctx.from) === null || _a === void 0 ? void 0 : _a.id;
|
|
11
|
+
if (chatId == null || fromId == null) {
|
|
12
|
+
return undefined; // If this is an event without chat/user, the session will not work
|
|
13
|
+
}
|
|
14
|
+
return `${chatId}:${fromId}`;
|
|
15
|
+
});
|
|
16
|
+
return async (ctx, next) => {
|
|
17
|
+
const key = getSessionKey(ctx);
|
|
18
|
+
// If the key is not generated (e.g., system update), just proceed further
|
|
19
|
+
if (!key) {
|
|
20
|
+
return next();
|
|
21
|
+
}
|
|
22
|
+
// 1. Get data from storage
|
|
23
|
+
let sessionData = await Promise.resolve(storage.get(key));
|
|
24
|
+
// 2. If data is missing, call initial() or create an empty object
|
|
25
|
+
if (sessionData == null) {
|
|
26
|
+
sessionData = options.initial();
|
|
27
|
+
}
|
|
28
|
+
// 3. Put the session into the context
|
|
29
|
+
ctx.session = sessionData;
|
|
30
|
+
await next();
|
|
31
|
+
if (ctx.session == null) {
|
|
32
|
+
await Promise.resolve(storage.delete(key));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
await Promise.resolve(storage.set(key, ctx.session));
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export * from './storage';
|
|
40
|
+
export * from './memory-storage';
|
|
41
|
+
export * from './gas-storage';
|
|
42
|
+
export * from './gas-cache-storage';
|
|
43
|
+
export * from './gas-hybrid-storage';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Storage } from './storage';
|
|
2
|
+
/**
|
|
3
|
+
* In-memory session storage (Map).
|
|
4
|
+
* Fastest option, but data is lost when the bot restarts.
|
|
5
|
+
*
|
|
6
|
+
* ✅ Pros: very fast, no configuration required
|
|
7
|
+
* ❌ Cons: data is not persistent between restarts
|
|
8
|
+
*/
|
|
9
|
+
export declare class MemoryStorage<T> implements Storage<T> {
|
|
10
|
+
private store;
|
|
11
|
+
/**
|
|
12
|
+
* Retrieves a session.
|
|
13
|
+
* @param key Session key
|
|
14
|
+
* @returns `T | undefined`
|
|
15
|
+
*/
|
|
16
|
+
get(key: string): T | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Saves a session.
|
|
19
|
+
* @param key Session key
|
|
20
|
+
* @param value Session value
|
|
21
|
+
*/
|
|
22
|
+
set(key: string, value: T): void;
|
|
23
|
+
/**
|
|
24
|
+
* Deletes a session.
|
|
25
|
+
* @param key Session key
|
|
26
|
+
*/
|
|
27
|
+
delete(key: string): void;
|
|
28
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory session storage (Map).
|
|
3
|
+
* Fastest option, but data is lost when the bot restarts.
|
|
4
|
+
*
|
|
5
|
+
* ✅ Pros: very fast, no configuration required
|
|
6
|
+
* ❌ Cons: data is not persistent between restarts
|
|
7
|
+
*/
|
|
8
|
+
export class MemoryStorage {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.store = new Map();
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Retrieves a session.
|
|
14
|
+
* @param key Session key
|
|
15
|
+
* @returns `T | undefined`
|
|
16
|
+
*/
|
|
17
|
+
get(key) {
|
|
18
|
+
return this.store.get(key);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Saves a session.
|
|
22
|
+
* @param key Session key
|
|
23
|
+
* @param value Session value
|
|
24
|
+
*/
|
|
25
|
+
set(key, value) {
|
|
26
|
+
this.store.set(key, value);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Deletes a session.
|
|
30
|
+
* @param key Session key
|
|
31
|
+
*/
|
|
32
|
+
delete(key) {
|
|
33
|
+
this.store.delete(key);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for session storage.
|
|
3
|
+
* T - type of session data we store.
|
|
4
|
+
*/
|
|
5
|
+
export interface Storage<T> {
|
|
6
|
+
/**
|
|
7
|
+
* Get session data by key.
|
|
8
|
+
*/
|
|
9
|
+
get(key: string): Promise<T | undefined> | T | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Save session data by key.
|
|
12
|
+
*/
|
|
13
|
+
set(key: string, value: T): Promise<void> | void;
|
|
14
|
+
/**
|
|
15
|
+
* Delete session (e.g., if the user finished the dialogue).
|
|
16
|
+
*/
|
|
17
|
+
delete(key: string): Promise<void> | void;
|
|
18
|
+
}
|