@kieksme/csp-plugin-telegram 0.11.0 → 0.12.1

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
@@ -11,3 +11,5 @@ pnpm dlx @kieksme/csp-cli plugin add @kieksme/csp-plugin-telegram
11
11
  Offene Webseiten verwenden `chatSupport: { "mode": "telegram", "auth": "anonymous" }`; alternativ Entra-Login. Bot-Token und Webhook-Secret gehören ausschließlich auf den API-Host. Genau ein Supporttransport je Instanz.
12
12
 
13
13
  [Einrichtung, Rechte, Architektur und Grenzen](https://github.com/kieksme/csp/wiki/telegram-support). Reale Telegram-Verbindung **noch ungetestet**; automatisierte Prüfungen verwenden synthetische Antworten.
14
+
15
+ Explicit human requests use the shared persistent waiting state and directed notifications, with current support membership checks. See [shared chat behaviour](../../docs/chat.md).
package/dist/browser.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  cspPlugin
3
- } from "./chunk-PGRFWYJH.js";
3
+ } from "./chunk-5OGZJ4WO.js";
4
4
 
5
5
  // src/browser.tsx
6
6
  var browser_default = {
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var cspPlugin = {
3
3
  id: "telegram",
4
- sdkVersion: "^0.11.0",
4
+ sdkVersion: "^0.12.1",
5
5
  browser: "./browser",
6
6
  server: "./server",
7
7
  requires: [
package/dist/server.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  cspPlugin
3
- } from "./chunk-PGRFWYJH.js";
3
+ } from "./chunk-5OGZJ4WO.js";
4
4
 
5
5
  // src/server.ts
6
6
  import {
@@ -81,6 +81,7 @@ import { z as z2 } from "zod";
81
81
  import {
82
82
  action,
83
83
  supportReply,
84
+ requestNotice,
84
85
  ChatError
85
86
  } from "@kieksme/csp-core/support";
86
87
 
@@ -225,7 +226,7 @@ function chunks(text, limit) {
225
226
  return result;
226
227
  }
227
228
  function card(c) {
228
- const status = c.status === "bot" ? "Digitaler Assistent" : c.status === "closed" ? c.resolution ? "Problem gel\xF6st" : "Abgeschlossen" : `Support: ${c.support?.name}`;
229
+ const status = c.status === "bot" || c.status === "waiting" ? c.status === "waiting" ? "Pers\xF6nlicher Support angefragt \xB7 KI pausiert" : "Digitaler Assistent" : c.status === "closed" ? c.resolution ? "Problem gel\xF6st" : "Abgeschlossen" : `Support: ${c.support?.name}`;
229
230
  return {
230
231
  text: `Portal-Support
231
232
  Portal-Nutzer: ${c.owner.name}
@@ -233,7 +234,7 @@ Gespr\xE4ch: ${c.id}
233
234
  Status: ${status}`,
234
235
  reply_markup: {
235
236
  inline_keyboard: c.status === "closed" ? [] : [
236
- (c.status === "bot" ? [
237
+ (c.status === "bot" || c.status === "waiting" ? [
237
238
  ["take", "\xDCbernehmen"],
238
239
  ["resolve", "Problem gel\xF6st"]
239
240
  ] : [
@@ -328,7 +329,7 @@ async function createTelegramBridge(app, store, config, fetcher = fetch, onTake
328
329
  409,
329
330
  "Gespr\xE4chslimit erreicht. Bitte abschlie\xDFen."
330
331
  );
331
- const transition = job.action === "take" && c.status === "bot" || job.action === "resolve" && c.status !== "closed";
332
+ const transition = job.action === "take" && (c.status === "bot" || c.status === "waiting") || job.action === "resolve" && c.status !== "closed";
332
333
  action(c, job.action, person, queue);
333
334
  c.supportActionAt = job.timestamp;
334
335
  if (job.action === "take" && transition)
@@ -393,7 +394,7 @@ async function createTelegramBridge(app, store, config, fetcher = fetch, onTake
393
394
  const match = /^(take|release|close|resolve):([a-f0-9-]{36})$/.exec(
394
395
  callback.data ?? ""
395
396
  );
396
- if (!match || match[2] !== c.id || String(m.message_id) !== c.thread?.serviceUrl || m.from?.id !== bot.id)
397
+ if (!match || match[2] !== c.id || String(m.message_id) !== c.thread?.serviceUrl && String(m.message_id) !== c.supportRequest?.messageId || m.from?.id !== bot.id)
397
398
  return { ok: true };
398
399
  command = match[1];
399
400
  } else if (!m.text?.trim()) return { ok: true };
@@ -439,7 +440,41 @@ async function createTelegramBridge(app, store, config, fetcher = fetch, onTake
439
440
  chat_id: config.CSP_TELEGRAM_CHAT_ID,
440
441
  message_thread_id: Number(c.thread.rootId)
441
442
  };
442
- if (job.kind === "create" || job.kind === "card") {
443
+ if (job.kind === "request") {
444
+ if (c.status !== "waiting" || c.supportRequest?.id !== job.id || c.supportRequest.messageId)
445
+ return;
446
+ const targets = [];
447
+ for (const id of job.targets ?? []) {
448
+ const person = await authorize(id);
449
+ if (person) targets.push({ id, name: person.name });
450
+ }
451
+ const names = targets.map((p) => p.name).join(", ");
452
+ const text = names + (names ? ": " : "") + "Pers\xF6nlicher Support angefragt. Bitte \xFCbernehmen.";
453
+ let offset = 0;
454
+ const entities = targets.map((p) => {
455
+ const entity = {
456
+ type: "text_mention",
457
+ offset,
458
+ length: p.name.length,
459
+ user: { id: Number(p.id) }
460
+ };
461
+ offset += p.name.length + 2;
462
+ return entity;
463
+ });
464
+ const result = z2.object({ message_id: integer.positive() }).parse(
465
+ await api("sendMessage", {
466
+ ...base,
467
+ text,
468
+ entities,
469
+ reply_markup: card(c).reply_markup,
470
+ link_preview_options: { is_disabled: true }
471
+ })
472
+ );
473
+ await store.change(c.id, (current) => {
474
+ if (current.supportRequest?.id === job.id)
475
+ current.supportRequest.messageId = String(result.message_id);
476
+ });
477
+ } else if (job.kind === "create" || job.kind === "card") {
443
478
  if (c.thread.serviceUrl) {
444
479
  await api("editMessageText", {
445
480
  chat_id: base.chat_id,
@@ -452,6 +487,13 @@ async function createTelegramBridge(app, store, config, fetcher = fetch, onTake
452
487
  current.thread.serviceUrl = String(result.message_id);
453
488
  });
454
489
  }
490
+ if (c.supportRequest?.messageId && c.status !== "waiting")
491
+ await api("editMessageText", {
492
+ chat_id: base.chat_id,
493
+ message_id: Number(c.supportRequest.messageId),
494
+ text: requestNotice(c),
495
+ reply_markup: { inline_keyboard: [] }
496
+ });
455
497
  } else if (job.message) {
456
498
  const m = job.message, text = `${m.kind === "user" ? c.owner.name : m.kind === "bot" ? "Digitaler Assistent" : m.name ?? "Support"}
457
499
  ${m.content}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kieksme/csp-plugin-telegram",
3
- "version": "0.11.0",
3
+ "version": "0.12.1",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -22,8 +22,8 @@
22
22
  "registry": "https://registry.npmjs.org"
23
23
  },
24
24
  "dependencies": {
25
- "@kieksme/csp-sdk": "^0.11.0",
26
- "@kieksme/csp-core": "^0.11.0",
25
+ "@kieksme/csp-sdk": "^0.12.1",
26
+ "@kieksme/csp-core": "^0.12.1",
27
27
  "zod": "^3.25.76",
28
28
  "fastify": "^5.6.1"
29
29
  },
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "cspPlugin": {
34
34
  "id": "telegram",
35
- "sdkVersion": "^0.11.0",
35
+ "sdkVersion": "^0.12.1",
36
36
  "browser": "./browser",
37
37
  "server": "./server",
38
38
  "requires": [