diff --git a/skills/paradiz/SKILL.md b/skills/paradiz/SKILL.md index 763f65b..7ac886a 100644 --- a/skills/paradiz/SKILL.md +++ b/skills/paradiz/SKILL.md @@ -118,6 +118,28 @@ python3 {baseDir}/scripts/calc_quote.py \ `Спасибо за бронирование 🤍 Ваша бронь подтверждена.` `За 3–5 дней до заезда я напомню вам о деталях.` +После подтверждения брони обязательно сохранить запись и отправить уведомление в Telegram: + +```bash +python3 {baseDir}/scripts/save_booking.py \ + --guest "Ильин Виталий Игоревич" \ + --phone "+79787434318" \ + --email "keeper78@inbox.ru" \ + --checkin "2026-07-28" \ + --checkout "2026-08-04" \ + --guests 5 \ + --room "Двухкомнатный номер" \ + --total "54 600 ₽" \ + --prepay "7 800 ₽" \ + --notes "трансфер нужен" \ + --notify +``` + +Файлы бронирований: +- текстовый журнал: `{baseDir}/data/bookings.txt` +- структурированный журнал: `{baseDir}/data/bookings.jsonl` + + ### Этап 9 — Во время и после проживания - Через 1 день после заселения: diff --git a/skills/paradiz/data/bookings.jsonl b/skills/paradiz/data/bookings.jsonl new file mode 100644 index 0000000..2753de0 --- /dev/null +++ b/skills/paradiz/data/bookings.jsonl @@ -0,0 +1,2 @@ +{"created_at": "2026-02-21 20:02:13", "guest": "ТЕСТ Бронь", "phone": "+70000000000", "email": "test@example.com", "checkin": "2026-07-28", "checkout": "2026-08-04", "guests": 5, "room": "Двухкомнатный номер", "total": "54 600 ₽", "prepay": "7 800 ₽", "notes": "проверка интеграции"} +{"created_at": "2026-02-21 20:03:28", "guest": "ТЕСТ Бронь 2", "phone": "+70000000000", "email": "test@example.com", "checkin": "2026-07-28", "checkout": "2026-08-04", "guests": 5, "room": "Двухкомнатный номер", "total": "54 600 ₽", "prepay": "7 800 ₽", "notes": "проверка уведомления"} diff --git a/skills/paradiz/data/bookings.txt b/skills/paradiz/data/bookings.txt new file mode 100644 index 0000000..b49fdf3 --- /dev/null +++ b/skills/paradiz/data/bookings.txt @@ -0,0 +1,25 @@ +# Бронирования Парадиз +# Формат записи добавляется скриптом save_booking.py + +[2026-02-21 20:02:13] БРОНЬ +Гость: ТЕСТ Бронь +Телефон: +70000000000 +Email: test@example.com +Период: 2026-07-28 → 2026-08-04 +Гостей: 5 +Номер: Двухкомнатный номер +Итого: 54 600 ₽ +Предоплата: 7 800 ₽ +Комментарий: проверка интеграции +--- +[2026-02-21 20:03:28] БРОНЬ +Гость: ТЕСТ Бронь 2 +Телефон: +70000000000 +Email: test@example.com +Период: 2026-07-28 → 2026-08-04 +Гостей: 5 +Номер: Двухкомнатный номер +Итого: 54 600 ₽ +Предоплата: 7 800 ₽ +Комментарий: проверка уведомления +--- diff --git a/skills/paradiz/scripts/save_booking.py b/skills/paradiz/scripts/save_booking.py new file mode 100755 index 0000000..d899776 --- /dev/null +++ b/skills/paradiz/scripts/save_booking.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python3 +import argparse +import json +import os +from datetime import datetime +from pathlib import Path +from urllib import parse, request + + +def send_telegram(bot_token: str, chat_id: str, text: str) -> None: + url = f"https://api.telegram.org/bot{bot_token}/sendMessage" + payload = parse.urlencode({ + "chat_id": chat_id, + "text": text, + "disable_web_page_preview": "true", + }).encode("utf-8") + req = request.Request(url, data=payload, method="POST") + with request.urlopen(req, timeout=15) as resp: + if resp.status != 200: + raise RuntimeError(f"Telegram HTTP {resp.status}") + + +def load_telegram_from_config(): + cfg = Path('/home/openclaw/.openclaw/openclaw.json') + if not cfg.exists(): + return "", "" + try: + j = json.loads(cfg.read_text(encoding='utf-8')) + except Exception: + return "", "" + + bot = "" + chat = "" + + # 1) dedicated env for paradiz skill + try: + env = j.get('skills', {}).get('entries', {}).get('paradiz', {}).get('env', {}) + bot = (env.get('PARADIZ_TG_BOT_TOKEN') or "").strip() + chat = str(env.get('PARADIZ_TG_CHAT_ID') or "").strip() + except Exception: + pass + + # 2) fallback to channel token format + if not bot: + bt = str(j.get('channels', {}).get('telegram', {}).get('botToken', '')).strip() + if bt.startswith('https://api.telegram.org/bot'): + bt = bt.replace('https://api.telegram.org/bot', '', 1) + bot = bt + + return bot, chat + + +def main(): + p = argparse.ArgumentParser(description="Сохранить бронь и отправить уведомление в Telegram") + p.add_argument("--guest", required=True, help="ФИО гостя") + p.add_argument("--phone", required=True, help="Телефон") + p.add_argument("--email", required=True, help="E-mail") + p.add_argument("--checkin", required=True, help="Дата заезда YYYY-MM-DD") + p.add_argument("--checkout", required=True, help="Дата выезда YYYY-MM-DD") + p.add_argument("--guests", required=True, type=int, help="Количество гостей") + p.add_argument("--room", required=True, help="Категория номера") + p.add_argument("--total", required=True, help="Итоговая сумма") + p.add_argument("--prepay", required=True, help="Сумма предоплаты") + p.add_argument("--notes", default="", help="Комментарий") + p.add_argument("--file", default="/home/openclaw/.openclaw/workspace/skills/paradiz/data/bookings.txt") + p.add_argument("--notify", action="store_true", help="Отправить Telegram-уведомление") + args = p.parse_args() + + now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + entry = { + "created_at": now, + "guest": args.guest, + "phone": args.phone, + "email": args.email, + "checkin": args.checkin, + "checkout": args.checkout, + "guests": args.guests, + "room": args.room, + "total": args.total, + "prepay": args.prepay, + "notes": args.notes, + } + + out = Path(args.file) + out.parent.mkdir(parents=True, exist_ok=True) + + human = ( + f"[{now}] БРОНЬ\n" + f"Гость: {args.guest}\n" + f"Телефон: {args.phone}\n" + f"Email: {args.email}\n" + f"Период: {args.checkin} → {args.checkout}\n" + f"Гостей: {args.guests}\n" + f"Номер: {args.room}\n" + f"Итого: {args.total}\n" + f"Предоплата: {args.prepay}\n" + f"Комментарий: {args.notes or '-'}\n" + f"---\n" + ) + + with out.open("a", encoding="utf-8") as f: + f.write(human) + + jsonl = out.with_suffix(".jsonl") + with jsonl.open("a", encoding="utf-8") as jf: + jf.write(json.dumps(entry, ensure_ascii=False) + "\n") + + sent = False + err = None + if args.notify: + bot_token = os.getenv("PARADIZ_TG_BOT_TOKEN", "").strip() + chat_id = os.getenv("PARADIZ_TG_CHAT_ID", "").strip() + if not (bot_token and chat_id): + cfg_bot, cfg_chat = load_telegram_from_config() + bot_token = bot_token or cfg_bot + chat_id = chat_id or cfg_chat + + if bot_token and chat_id: + text = ( + "📌 Новая бронь Парадиз\n" + f"Гость: {args.guest}\n" + f"Телефон: {args.phone}\n" + f"Email: {args.email}\n" + f"Период: {args.checkin} → {args.checkout}\n" + f"Гостей: {args.guests}\n" + f"Номер: {args.room}\n" + f"Итого: {args.total}\n" + f"Предоплата: {args.prepay}\n" + f"Комментарий: {args.notes or '-'}" + ) + try: + send_telegram(bot_token, chat_id, text) + sent = True + except Exception as e: + err = str(e) + else: + err = "PARADIZ_TG_BOT_TOKEN / PARADIZ_TG_CHAT_ID не заданы" + + print(json.dumps({"ok": True, "saved": str(out), "jsonl": str(jsonl), "telegram_sent": sent, "telegram_error": err}, ensure_ascii=False)) + + +if __name__ == "__main__": + main()