Skip to content

Repository files navigation

Radioekat Message Broadcaster

Скрипт и HTTP API для отправки Markdown-сообщения в канал MAX и, при наличии Telegram-настроек, в Telegram.

Настройка

  1. Создайте бота в MAX и получите токен.
  2. Добавьте бота в нужный канал/чат MAX и дайте ему права на публикацию.
  3. Скопируйте .env.example в .env и заполните значения:
BOT_TOKEN=your_bot_token_here
TELEGRAM_BOT_TOKEN=your_telegram_bot_token_here
API_PORT=3000
HOST_PORT=3000
API_TOKEN=change_me
ROUTES_FILE=routes.json

Если API_TOKEN задан, API требует заголовок Authorization: Bearer API_TOKEN.

Маршруты настраиваются в routes.json:

{
  "defaultRoute": "main",
  "routes": {
    "main": {
      "title": "Основной раздел",
      "max": { "chatId": 123456789 },
      "telegram": {
        "chatId": -1001234567890,
        "messageThreadId": null
      }
    },
    "roundtable": {
      "title": "Круглые столы",
      "max": { "chatId": 123456789 },
      "telegram": {
        "chatId": -1001234567890,
        "messageThreadId": 2
      }
    }
  }
}

messageThreadId нужен для Telegram-темы в forum-группе. Для обычного канала/чата укажите null. Если маршрут должен отправлять только в MAX или только в Telegram, удалите ненужный блок max или telegram.

Для API текст сообщения передаётся прямо в запросе. Первая строка с # используется как заголовок, остальной Markdown отправляется как тело сообщения.

# Заголовок сообщения

Текст сообщения.
Можно использовать **Markdown**.

API

Запуск:

npm run api

Docker

Сборка образа:

docker build -t radioekat-message-broadcaster .

Запуск контейнера:

docker run --rm \
  --env-file .env \
  -e API_PORT=3000 \
  -p 3000:3000 \
  -v "$(pwd)/routes.json:/app/routes.json:ro" \
  radioekat-message-broadcaster

Запуск через Docker Compose:

docker compose up -d --build

В Docker Compose контейнер всегда слушает API_PORT=3000, а наружный порт задаётся через HOST_PORT.

После запуска Swagger-документация открывается по умолчанию:

http://localhost:3000/

OpenAPI JSON доступен по адресу:

http://localhost:3000/openapi.json

Страница со всеми маршрутами доступна по адресу:

http://localhost:3000/routes

Публичный JSON со списком маршрутов доступен по адресу:

http://localhost:3000/routes.json

Формат ответа:

{
  "defaultRoute": "general",
  "routes": [
    { "title": "УКВ раздел", "route": "vhf_section" },
    { "title": "Общее радиолюбительское", "route": "general" }
  ]
}

В Swagger ссылка на список маршрутов указана в описании параметра route.

Отправка сообщения:

curl -X POST "http://localhost:3000/send?route=roundtable" \
  -H "Content-Type: text/markdown" \
  -H "Authorization: Bearer change_me" \
  --data-binary $'# [Заголовок](https://example.com)\n\nТекст сообщения\n\n1. **Первый пункт**\n2. [Ссылка](https://example.com)'

Если параметр route не передан, используется defaultRoute из routes.json.

Отправка с картинкой и встроенной URL-кнопкой:

curl -X POST "http://localhost:3000/send?route=roundtable&imageUrl=https%3A%2F%2Fexample.com%2Fimage.jpg&buttonUrl=https%3A%2F%2Fexample.com%2Fpost&buttonText=Открыть%20запись" \
  -H "Content-Type: text/markdown" \
  -H "Authorization: Bearer change_me" \
  --data-binary $'# Заголовок\n\nТекст сообщения'

Если imageUrl не передан, сообщение уйдёт без картинки. Если buttonUrl не передан, кнопка не добавится.

Минимальный body запроса:

# Заголовок

Текст сообщения

MAX использует bot.api.sendMessageToChat(chatId, text, { format: 'markdown' }). В Telegram используется sendMessage или sendPhoto с parse_mode: 'HTML'; поддерживаются заголовок, **bold**, *italic*, code, ссылки вида [text](https://example.com), опциональная картинка и URL-кнопка.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages