ДескусДескус · Документация
Все разделыРецепты

Telegram-бот для команды поверх API

Небольшой бот для чата поддержки в Telegram: сообщает о новом тикете и отвечает клиенту командой /reply T-1042 текст. Пример — для команды, не для клиентов.

Клиенты пишут в Telegram?

Для этого бот не нужен — подключите канал Telegram в кабинете, сообщения клиентов сразу станут тикетами: Мессенджеры, формы и приём по API.

Что понадобится

  • Бот от @BotFather и id чата команды.

  • Ключ API с правами tickets:read, tickets:write, webhooks от сотрудника, от имени которого бот будет отвечать.

  • Сервер с адресом https для вебхуков Дескуса и Telegram.

Код на Node.js

import crypto from "node:crypto";
import express from "express";

const { DESKUS_KEY, DESKUS_WEBHOOK_SECRET, TG_TOKEN, TG_CHAT } = process.env;
const deskus = (path, init = {}) =>
  fetch(`https://app.deskus.ru/api/v1${path}`, {
    ...init,
    headers: { Authorization: `Bearer ${DESKUS_KEY}`, "Content-Type": "application/json", ...init.headers },
  });
const tg = (method, body) =>
  fetch(`https://api.telegram.org/bot${TG_TOKEN}/${method}`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(body),
  });

const app = express();

// 1. Новый тикет → сообщение в чат команды
app.post("/deskus", express.raw({ type: "application/json" }), async (req, res) => {
  const sign = "sha256=" + crypto.createHmac("sha256", DESKUS_WEBHOOK_SECRET).update(req.body).digest("hex");
  const got = Buffer.from(req.get("X-Deskus-Signature") || "");
  if (got.length !== sign.length || !crypto.timingSafeEqual(got, Buffer.from(sign))) return res.sendStatus(401);
  res.sendStatus(200);

  const event = JSON.parse(req.body.toString("utf8"));
  if (event.type === "ticket.created") {
    const { ticket, client } = event.data;
    await tg("sendMessage", {
      chat_id: TG_CHAT,
      text: `Новый тикет ${ticket.number}: ${ticket.subject}\nОт: ${client?.name ?? "—"}\n${ticket.url}`,
    });
  }
});

// 2. /reply T-1042 текст → ответ клиенту
app.post("/telegram", express.json(), async (req, res) => {
  res.sendStatus(200);
  const text = req.body.message?.text ?? "";
  const match = /^\/reply\s+(\S+)\s+([\s\S]+)/.exec(text);
  if (!match || String(req.body.message.chat.id) !== TG_CHAT) return;
  const [, number, reply] = match;
  const answer = await deskus(`/tickets/${encodeURIComponent(number)}/messages`, {
    method: "POST",
    headers: { "Idempotency-Key": `tg-${req.body.message.message_id}` },
    body: JSON.stringify({ type: "reply", text: reply }),
  });
  await tg("sendMessage", {
    chat_id: TG_CHAT,
    text: answer.ok ? `Ответ в ${number} отправлен` : `Не отправлен: ${(await answer.json()).error.message}`,
  });
});

app.listen(3000);

Подключить

  1. Подпишите бота на события Дескуса: POST /webhooks с адресом https://ваш-сервер/deskus и событием ticket.created. Секрет из ответа — в DESKUS_WEBHOOK_SECRET.

  2. Направьте Telegram на https://ваш-сервер/telegram — метод setWebhook Bot API.

  3. Напишите в чат /reply T-1042 Посылка в пути — клиент получит ответ, а в ленте тикета он будет подписан сотрудником ключа.

Отвечать через бота может любой участник чата: ключ один на всех. Держите чат закрытым или сверяйте from.id отправителя со списком сотрудников.

Не нашли ответ? Напишите нам
Поддержка ответит в рабочее время.
Вы сотрудник «Дескус»?Изменить статью в Дескусе