cloud cloud cloud cloud

Шутка дня с ИИ-переводом: создаём умного XMPP-бота на Alpine Linux

Сейчас я занят разработкой сайта: данные собираются в статические страницы и отдельный JSON-файл, который лежит в открытом доступе. Параллельно крутится идея Telegram-бота, который будет парсить этот JSON, фильтровать события по дате и кидать анонсы в канал. Но это планы на будущее.

API-Ninjas и их эндпоинт [Joke of the Day]

А пока решил «повайтибать» и сделать что-то быстрое из открытых источников. Наткнулся на API-Ninjas и их эндпоинт Joke of the Day . Он возвращает одну шутку в день. Шутки попадаются умные, но есть нюанс — всё на английском.

andrey@31350: ~
[andrey@31350 ~]$ curl -H "X-Api-Key: тут вставляем ключ" https://api.api-ninjas.com/v1/jokeoftheday
[{"joke": "What did Virginia get when she walked into the pet shop? A New Hampshire"}]

Можно, конечно, прогнать текст через translate-shell. Но английский юмор часто строится на игре слов, двойных смыслах или культурном контексте, который при прямом переводе просто исчезает. Получается набор букв, над которым никто не смеётся.

andrey@31350: ~
[andrey@31350 ~]$ curl -s -H "X-Api-Key: тут вставляем ключ" https://api.api-ninjas.com/v1/jokeoftheday | jq -r '.[0].joke' | trans :ru
What did Virginia get when she walked into the pet shop?  A New Hampshire

Что получила Вирджиния, когда зашла в зоомагазин? Нью-Гэмпшир
(Chto poluchila Virdzhiniya, kogda zashla v zoomagazin? N'yu-Gempshir)

Translations of What did Virginia get when she walked into the pet shop?  A New Hampshire
[ English -> Русский ]

What did Virginia get when she walked into the pet shop?
    Что получила Вирджиния, когда зашла в зоомагазин?, Что Вирджиния получила, когда зашла в зоомагазин?
A New Hampshire
    Нью-Гэмпшир, Нью Хэмпшир
[andrey@31350 ~]$

Тут родилась идея: а что если подключить LLM и дать ей промпт не просто перевести, а объяснить шутку «для тупых»? Чтобы она расписала, где именно соль.

Архитектура решения

Схема получилась максимально легкой, без тяжелых фреймворков и Docker-контейнеров. Чистый Bash, curl, jq и минимум зависимостей. Идеально для моего HP t430 на Alpine Linux.

  1. Bash-скрипт забирает сырую шутку у API-Ninjas.
  2. Формирует умный промпт и стучится в RouterAI API (OpenAI-совместимый шлюз).
  3. Получает связку: перевод + объяснение юмора на русском.
  4. Отправляет результат в XMPP-чат (MUC) через утилиту go-sendxmpp.
  5. Всё это дело висит в cron и будит меня каждое утро.

Подводные камни реализации

Казалось бы, всё просто, но дьявол кроется в деталях.

1. Проблема валидного JSON

Обычное склеивание строк в Bash ломается на спецсимволах, вызывая ошибку Invalid JSON format, потому что экранирование в Bash — та ещё боль.

2. Промпт-инжиниринг

Без жестких инструкций модель gpt-4o-mini иногда ленится и отвечает на английском или дает слишком академичное объяснение. Пришлось добавить правила:

  • Перевести на русский.
  • Объяснить суть на русском.
  • Начать с фразы «Почему это смешно:».
  • Никакого английского в ответе.

Результат

Получается, что каждое утро в 9:00 в мой XMPP-чат будет присылать мне сообщение такого вида:

Gajim

Если API искусственного интеллекта вдруг упадет или закончится баланс, скрипт не сломается. Он автоматически переключится на резервный вариант: простой перевод через translate-shell и пометку об ошибке. А мне в личку придет уведомление, что что-то пошло не так.

Что дальше?

Архитектура получилась универсальной. Заменить XMPP на Telegram Bot API — дело пяти минут: достаточно поменять функцию отправки. Можно добавить реакцию на команды в чате (!joke, !stats) или генерацию картинок.

Но пока меня устраивает эта минималистичная версия. Она делает ровно то, что нужно, потребляет копейки ресурсов и не ломается. (Надеюсь!).

Завтра утром жду результатов. Получу заряд британского юмора, а если не пойму игру слов — ИИ всё разъяснит.