@yaebal/panel 0.0.2 → 0.0.5

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 CHANGED
@@ -1,14 +1,19 @@
1
1
  # @yaebal/panel
2
2
 
3
- an operator panel for [yaebal](https://github.com/neverlane/yaebal) bots: view
4
- incoming private-chat messages and reply from the browser, live. ships as a
5
- self-contained `fetch` handler mount it on any HTTP framework.
3
+ framework-agnostic operator panel for Telegram bots. view incoming private chats, inspect
4
+ media, callbacks and UI events, and reply from the browser. ships as a self-contained
5
+ `fetch` handler, so it mounts on Node, Bun, Deno, edge runtimes, Hono, Fastify, Express
6
+ adapters, grammY, GramIO, puregram, or any other bot stack.
6
7
 
7
- - **login page** on the panel root — paste your token, no secrets in the url
8
- - **realtime** updates over server-sent events, with a polling safety net
9
- - **media**: photos, docs, voice, video and albums — both directions, in the browser
10
- - **persistence** via a pluggable `PanelStore` (in-memory + sqlite included)
11
- - CORS, basePath mounting and failed-auth rate limiting
8
+ ## 0.0.3 highlights
9
+
10
+ - framework-neutral recording with `recordTelegramUpdate(store, update)`
11
+ - `createPanelApi(token)` for text replies, file proxying and operator media uploads
12
+ - redesigned SVG-only UI: avatars, identity sidebar, rich text/media previews
13
+ - media viewer dialog, polished voice cards, video cards, albums and documents
14
+ - inline/reply keyboard previews plus callback, reaction, poll and member-event rows
15
+ - persistence via pluggable `PanelStore` (in-memory + sqlite included)
16
+ - CORS, `basePath` mounting and failed-auth rate limiting
12
17
 
13
18
  ## install
14
19
 
@@ -16,150 +21,205 @@ self-contained `fetch` handler — mount it on any HTTP framework.
16
21
  pnpm add @yaebal/panel
17
22
  ```
18
23
 
19
- ## usage
24
+ ## quick start: yaebal
20
25
 
21
26
  ```ts
22
27
  import { Bot } from "@yaebal/core";
23
- import { MemoryPanelStore, recorder, panelHandler } from "@yaebal/panel";
28
+ import { MemoryPanelStore, panelHandler, recordOutgoing, recorder } from "@yaebal/panel";
24
29
  import { serve } from "@yaebal/panel/serve";
25
30
 
26
- const bot = new Bot(token);
31
+ const bot = new Bot(process.env.BOT_TOKEN!);
27
32
  const store = new MemoryPanelStore();
28
33
 
29
- bot.install(recorder(store)); // log incoming private messages
30
- bot.start();
34
+ bot.install(recorder(store));
35
+ recordOutgoing(bot.api, store);
36
+
37
+ const handler = panelHandler(bot.api, store, {
38
+ token: process.env.PANEL_TOKEN!,
39
+ recordSends: false,
40
+ });
31
41
 
32
- // serve the panel — a fetch handler: (Request) => Promise<Response>
33
- const handler = panelHandler(bot.api, store, { token: process.env.PANEL_TOKEN! });
34
42
  serve(handler, { port: 8080 });
35
- // open http://localhost:8080 and paste your token on the login screen
43
+ bot.start();
36
44
  ```
37
45
 
38
- The panel root serves a small SPA: a centered login (token input + **authorize**
39
- button), then the live chat view. The token is kept in `sessionStorage` and sent as
40
- `Authorization: Bearer …` it never rides in the page url.
46
+ open `http://localhost:8080` and paste `PANEL_TOKEN`. the token is kept in
47
+ `sessionStorage` and sent as `Authorization: Bearer ...`; it is not placed in page URLs
48
+ except for the EventSource stream, where browsers cannot set headers.
41
49
 
42
- ## mounting
50
+ ## quick start: any framework
43
51
 
44
- `panelHandler` returns a plain `(Request) => Promise<Response>` it binds no port of
45
- its own. pick a port when you wire it into a server.
52
+ use your existing framework for updates. use `@yaebal/panel` for the store, panel HTTP
53
+ handler, and a Bot API client that understands panel uploads.
46
54
 
47
55
  ```ts
48
- // node 20+ — `serve` ships in the box (native `node:http`, no deps)
56
+ import {
57
+ MemoryPanelStore,
58
+ createPanelApi,
59
+ panelHandler,
60
+ recordTelegramUpdate,
61
+ } from "@yaebal/panel";
49
62
  import { serve } from "@yaebal/panel/serve";
50
63
 
51
- serve(handler, { port: 8080, onListen: ({ port }) => console.log(`panel on :${port}`) });
64
+ const store = new MemoryPanelStore();
65
+ const panelApi = createPanelApi(process.env.BOT_TOKEN!);
52
66
 
53
- // bun
54
- Bun.serve({ port: 8080, fetch: handler });
67
+ // call this from your framework middleware for every raw Telegram update
68
+ await recordTelegramUpdate(store, rawTelegramUpdate);
55
69
 
56
- // deno
57
- Deno.serve({ port: 8080 }, handler);
58
-
59
- // hono / any fetch framework
60
- app.all("/panel/*", (c) => handler(c.req.raw)); // pair with basePath: "/panel"
70
+ const handler = panelHandler(panelApi, store, { token: process.env.PANEL_TOKEN! });
71
+ serve(handler, { port: 8080 });
61
72
  ```
62
73
 
63
- `serve` is a separate entry (`@yaebal/panel/serve`) so the main module stays free of
64
- `node:` imports for edge bundles. on cloudflare workers, deno deploy or vercel edge
65
- just export the handler as the `fetch` entry — same handler, no port:
74
+ ### grammY
66
75
 
67
76
  ```ts
68
- export default { fetch: handler };
77
+ import { Bot } from "grammy";
78
+ import { MemoryPanelStore, createPanelApi, panelHandler, recordTelegramUpdate } from "@yaebal/panel";
79
+
80
+ const bot = new Bot(process.env.BOT_TOKEN!);
81
+ const store = new MemoryPanelStore();
82
+
83
+ bot.use(async (ctx, next) => {
84
+ await recordTelegramUpdate(store, ctx.update);
85
+ await next();
86
+ });
87
+
88
+ const handler = panelHandler(createPanelApi(process.env.BOT_TOKEN!), store, {
89
+ token: process.env.PANEL_TOKEN!,
90
+ });
69
91
  ```
70
92
 
71
- ## options
93
+ ### GramIO
72
94
 
73
95
  ```ts
74
- panelHandler(bot.api, store, {
75
- token: process.env.PANEL_TOKEN!, // required shared secret
76
- basePath: "/panel", // mount under a sub-path (default: root)
77
- cors: "https://ops.example", // allow a browser origin (or a list, or "*")
78
- rateLimit: { max: 10, windowMs: 60_000 }, // throttle failed auth (default); false to disable
96
+ import { Bot } from "gramio";
97
+ import { MemoryPanelStore, createPanelApi, panelHandler, recordTelegramUpdate } from "@yaebal/panel";
98
+
99
+ const bot = new Bot(process.env.BOT_TOKEN!);
100
+ const store = new MemoryPanelStore();
101
+
102
+ bot.use(async (ctx, next) => {
103
+ await recordTelegramUpdate(store, ctx.update);
104
+ return next();
105
+ });
106
+
107
+ const handler = panelHandler(createPanelApi(process.env.BOT_TOKEN!), store, {
108
+ token: process.env.PANEL_TOKEN!,
79
109
  });
80
110
  ```
81
111
 
82
- - **`basePath`** — the UI builds its api urls from this, so no extra rewriting is
83
- needed when you mount under a prefix.
84
- - **`rateLimit`** — after `max` bad tokens within `windowMs`, a client gets `429`
85
- with `Retry-After` until the window passes. keyed by `x-forwarded-for` / `x-real-ip`
86
- by default; override with `clientKey`.
112
+ ### puregram
87
113
 
88
- ## persistence
114
+ ```ts
115
+ import { Telegram } from "puregram";
116
+ import { MemoryPanelStore, createPanelApi, panelHandler, recordTelegramUpdate } from "@yaebal/panel";
89
117
 
90
- implement `PanelStore` (`record` / `chats` / `history`, optional `subscribe` for
91
- realtime) to keep conversations in redis, postgres, etc. a sqlite-backed store built
92
- on node's native `node:sqlite` ships in the box:
118
+ const telegram = new Telegram({ token: process.env.BOT_TOKEN! });
119
+ const store = new MemoryPanelStore();
93
120
 
94
- ```ts
95
- import { SqlitePanelStore } from "@yaebal/panel/sqlite";
121
+ telegram.updates.use(async (ctx, next) => {
122
+ await recordTelegramUpdate(store, ctx.update);
123
+ return next();
124
+ });
96
125
 
97
- const store = new SqlitePanelStore({ path: "./panel.db" }); // or ":memory:"
98
- bot.install(recorder(store));
99
- const handler = panelHandler(bot.api, store, { token: process.env.PANEL_TOKEN! });
126
+ const handler = panelHandler(createPanelApi(process.env.BOT_TOKEN!), store, {
127
+ token: process.env.PANEL_TOKEN!,
128
+ });
100
129
  ```
101
130
 
102
- `subscribe` is what powers the SSE stream — a store without it still works, the UI
103
- just falls back to polling.
131
+ ### other frameworks
104
132
 
105
- ## media
133
+ if your framework exposes raw Telegram updates, pass them to `recordTelegramUpdate`. if it
134
+ does not, record manually with `store.record({ id, firstName, lastName, username }, message)`.
135
+ the panel only needs `PanelMessage` objects and a `PanelApi` implementation.
106
136
 
107
- photos, documents, voice notes, video and **albums** flow both ways:
137
+ ## mounting
108
138
 
109
- - **incoming** the recorder stores each attachment's `file_id` (and album id). the
110
- browser renders them inline: images, `<video>`, `<audio>`, or a download link for
111
- documents. consecutive messages sharing a `media_group_id` are shown as one album.
112
- - **outgoing** — the 📎 button in the composer uploads a file; the panel picks
113
- `sendPhoto` / `sendVideo` / `sendVoice` / `sendDocument` / … from its mime type
114
- (the text box becomes the caption).
139
+ `panelHandler` returns `(Request) => Promise<Response>` and binds no port of its own.
115
140
 
116
- media bytes are **proxied** through `GET /api/file?id=<file_id>` (the panel calls
117
- `getFile` and streams the result) so the bot token never reaches the browser. this
118
- needs an api with `call()` / `fileUrl()` — the real `@yaebal/core` `Api` has both;
119
- without them, media routes answer `501` and text still works.
141
+ ```ts
142
+ // node 20+, native node:http helper
143
+ import { serve } from "@yaebal/panel/serve";
144
+ serve(handler, { port: 8080 });
120
145
 
121
- ## what the recorder captures
146
+ // bun
147
+ Bun.serve({ port: 8080, fetch: handler });
122
148
 
123
- incoming **private-chat** messages only. text and captions are stored verbatim;
124
- a media-only message is previewed in the chat list as a `[photo]` / `[document]` /
125
- `[voice]` / … placeholder. when you reply with text from the panel, the api accepts
126
- `text` plus optional `parse_mode`, `reply_to_message_id` and `reply_parameters`,
127
- forwarded to `sendMessage`.
149
+ // deno
150
+ Deno.serve({ port: 8080 }, handler);
128
151
 
129
- `recorder` only sees **incoming** updates. to also capture replies the bot sends
130
- *elsewhere* (e.g. `ctx.reply(...)` in your own handlers), hook the api with
131
- `recordOutgoing` — and tell the panel to stop recording its own sends so they
132
- aren't logged twice:
152
+ // hono / any fetch framework, pair with basePath: "/panel"
153
+ app.all("/panel/*", (c) => handler(c.req.raw));
133
154
 
134
- ```ts
135
- import { recordOutgoing } from "@yaebal/panel";
155
+ // cloudflare workers / deno deploy / vercel edge
156
+ export default { fetch: handler };
157
+ ```
136
158
 
137
- recordOutgoing(bot.api, store); // logs every outgoing sendMessage to a private chat
138
- const handler = panelHandler(bot.api, store, {
159
+ ## options
160
+
161
+ ```ts
162
+ panelHandler(api, store, {
139
163
  token: process.env.PANEL_TOKEN!,
140
- recordSends: false, // recordOutgoing already covers panel replies
164
+ basePath: "/panel",
165
+ cors: "https://ops.example",
166
+ rateLimit: { max: 10, windowMs: 60_000 },
167
+ clientKey: (req) => req.headers.get("x-real-ip") ?? "shared",
168
+ recordSends: true,
141
169
  });
142
170
  ```
143
171
 
144
- ## api routes
172
+ ## persistence
173
+
174
+ ```ts
175
+ import { SqlitePanelStore } from "@yaebal/panel/sqlite";
176
+
177
+ const store = new SqlitePanelStore({ path: "./panel.db" });
178
+ ```
145
179
 
146
- mounted relative to `basePath` (default root). all but the page require the token.
180
+ implement `PanelStore` (`record`, `chats`, `history`, optional `subscribe`) for Redis,
181
+ Postgres or any other persistence layer. `subscribe` powers SSE; without it the UI still
182
+ works through polling.
183
+
184
+ ## what gets recorded
185
+
186
+ - private message text and captions
187
+ - photos, videos, animations, audio, voice, video notes, documents, stickers and albums
188
+ - inline and reply keyboards attached to messages
189
+ - callback queries as timeline event rows
190
+ - message reactions, reaction counts, poll answers and private member-status changes
191
+ - outgoing `send*` results when you install `recordOutgoing(api, store)`
192
+
193
+ `recordTelegramUpdate` and `recorder` ignore group chat messages by design. The panel is an
194
+ operator inbox for private support-style conversations.
195
+
196
+ ## media
197
+
198
+ incoming media is stored by `file_id`; the browser loads bytes through
199
+ `GET /api/file?id=<file_id>`, so the bot token never reaches the browser. Operator uploads
200
+ use multipart `POST /api/chats/:id/send`; the panel infers `sendPhoto`, `sendVideo`,
201
+ `sendVoice`, `sendAudio` or `sendDocument` from the file MIME type.
202
+
203
+ `createPanelApi(token)` uses the yaebal Bot API encoder internally, so media proxying and
204
+ operator uploads work even when the bot itself runs on grammY, GramIO, puregram or another
205
+ framework.
206
+
207
+ ## api routes
147
208
 
148
209
  ```text
149
- GET / login + chat SPA (public)
150
- GET /api/chats PanelChat[] (sorted by lastDate desc)
151
- GET /api/chats/:id PanelMessage[] (?before=&limit= to page)
152
- GET /api/stream text/event-stream of record events
153
- GET /api/file?id=<file_id> proxied file bytes (getFile + stream)
154
- POST /api/chats/:id/send json { text, } sendMessage
155
- multipart { file, caption?, type? } → sendPhoto/Document/…
210
+ GET / -> login + chat SPA (public)
211
+ GET /api/chats -> PanelChat[]
212
+ GET /api/chats/:id -> PanelMessage[] (?before=&limit=)
213
+ GET /api/stream -> text/event-stream of record events
214
+ GET /api/file?id=<file_id> -> proxied file bytes
215
+ POST /api/chats/:id/send -> json { text, reply_markup?, ... } or multipart { file, caption?, type? }
156
216
  ```
157
217
 
158
218
  ## example
159
219
 
160
- a runnable, full-featured bot lives in
161
- [`examples/panel`](https://github.com/neverlane/yaebal/tree/master/examples/panel) —
162
- media both ways, `recordOutgoing`, login page and SSE, served on node.
220
+ run [`examples/panel`](https://github.com/neverlane/yaebal/tree/master/examples/panel) for
221
+ the complete demo: keyboards, callbacks, event rows, media viewer, styled voice/video
222
+ messages, albums, outgoing logging, login and SSE.
163
223
 
164
224
  ---
165
225
 
package/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Context, Plugin } from "@yaebal/core";
1
+ import type { ApiOptions, Context, Plugin } from "@yaebal/core";
2
2
  export { PANEL_HTML } from "./panel-html.js";
3
3
  /** downloadable file kinds carried by a message (each maps to one `file_id`). */
4
4
  export type AttachmentType = "photo" | "video" | "animation" | "audio" | "voice" | "video_note" | "document" | "sticker";
@@ -9,21 +9,54 @@ export interface PanelAttachment {
9
9
  fileName?: string;
10
10
  mimeType?: string;
11
11
  }
12
+ export interface PanelKeyboardButton {
13
+ text: string;
14
+ kind?: "callback" | "url" | "web_app" | "login_url" | "switch_inline" | "pay" | "unknown";
15
+ callbackData?: string;
16
+ url?: string;
17
+ }
18
+ export interface PanelKeyboard {
19
+ type: "inline" | "reply";
20
+ rows: PanelKeyboardButton[][];
21
+ }
22
+ export type PanelMessageEventType = "callback" | "reaction" | "reaction_count" | "poll_answer" | "chat_member";
23
+ export interface PanelMessageEvent {
24
+ type: PanelMessageEventType;
25
+ title: string;
26
+ detail?: string;
27
+ data?: string;
28
+ }
29
+ export interface PanelChatRecord {
30
+ id: number;
31
+ name?: string;
32
+ firstName?: string;
33
+ lastName?: string;
34
+ username?: string;
35
+ }
12
36
  export interface PanelMessage {
13
37
  direction: "in" | "out";
14
38
  /** caption / text, or a `[kind]` placeholder when the message is media-only. */
15
39
  text: string;
16
40
  date: number;
17
- /** downloadable attachments, fetched lazily through `GET /api/file?id=…`. */
41
+ /** downloadable attachments, fetched lazily through `GET /api/file?id=...`. */
18
42
  attachments?: PanelAttachment[];
19
43
  /** telegram album id — consecutive messages sharing it are one media group. */
20
44
  mediaGroupId?: string;
45
+ /** inline/reply keyboard attached to the telegram message, rendered as a compact preview. */
46
+ keyboard?: PanelKeyboard;
47
+ /** non-message update rendered in the timeline (callback, reaction, poll answer, member event). */
48
+ event?: PanelMessageEvent;
21
49
  }
22
50
  export interface PanelChat {
23
51
  id: number;
24
52
  name: string;
53
+ firstName?: string;
54
+ lastName?: string;
55
+ username?: string;
25
56
  lastText: string;
26
57
  lastDate: number;
58
+ lastAttachmentType?: AttachmentType;
59
+ lastEventType?: PanelMessageEventType;
27
60
  }
28
61
  /** options for reading a slice of a conversation. */
29
62
  export interface HistoryOptions {
@@ -40,10 +73,7 @@ export interface PanelEvent {
40
73
  }
41
74
  /** where conversations are kept for the panel to read. implement for persistence. */
42
75
  export interface PanelStore {
43
- record(chat: {
44
- id: number;
45
- name?: string;
46
- }, message: PanelMessage): void | Promise<void>;
76
+ record(chat: PanelChatRecord, message: PanelMessage): void | Promise<void>;
47
77
  chats(): PanelChat[] | Promise<PanelChat[]>;
48
78
  history(chatId: number, options?: HistoryOptions): PanelMessage[] | Promise<PanelMessage[]>;
49
79
  /** optional realtime hook — return an unsubscribe fn. enables the panel's SSE stream. */
@@ -52,26 +82,27 @@ export interface PanelStore {
52
82
  /** defaults to in-memory store. Lost on restart — swap for a persistent one in production. */
53
83
  export declare class MemoryPanelStore implements PanelStore {
54
84
  #private;
55
- record(chat: {
56
- id: number;
57
- name?: string;
58
- }, message: PanelMessage): void;
85
+ record(chat: PanelChatRecord, message: PanelMessage): void;
59
86
  chats(): PanelChat[];
60
87
  history(chatId: number, options?: HistoryOptions): PanelMessage[];
61
88
  subscribe(listener: (event: PanelEvent) => void): () => void;
62
89
  }
63
- /** records incoming private-chat text into the store so the panel can show it. */
90
+ /** records a raw Telegram update into the store; useful from any bot framework. */
91
+ export declare function recordTelegramUpdate(store: PanelStore, update: unknown): Promise<boolean>;
92
+ /** records incoming private-chat updates into the store so the panel can show them. */
64
93
  export declare function recorder(store: PanelStore): Plugin<Context, Record<never, never>>;
65
94
  /**
66
95
  * what {@link panelHandler} needs from the api. `sendMessage` is required; `call` and
67
96
  * `fileUrl` unlock media (file proxying + operator uploads) and are present on the real
68
97
  * `@yaebal/core` `Api`. without them, media routes answer `501`.
69
98
  */
70
- interface PanelApi {
99
+ export interface PanelApi {
71
100
  sendMessage(params: Record<string, unknown>): Promise<unknown>;
72
101
  call?<T = unknown>(method: string, params?: Record<string, unknown>): Promise<T>;
73
102
  fileUrl?(filePath: string): string;
74
103
  }
104
+ /** create a small Bot API client that satisfies {@link PanelApi}; useful with any framework. */
105
+ export declare function createPanelApi(token: string, options?: ApiOptions): PanelApi;
75
106
  /** the slice of `@yaebal/core`'s `Api` that {@link recordOutgoing} needs. */
76
107
  interface AfterHookApi {
77
108
  after(hook: (method: string, result: unknown) => unknown): unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}