Files
openclaw/skills/paradiz/scripts/save_booking.py
2026-02-21 20:14:15 +00:00

211 lines
7.9 KiB
Python
Executable File

#!/usr/bin/env python3
import argparse
import json
import os
from datetime import datetime
from pathlib import Path
from urllib import parse, request
import re
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 _extract_amount(s: str) -> float:
cleaned = re.sub(r"[^0-9,\.]", "", s or "").replace(",", ".")
if not cleaned:
return 0.0
try:
return float(cleaned)
except Exception:
return 0.0
def render_booking_rtf(template_path: Path, output_path: Path, data: dict) -> None:
if not template_path.exists():
return
txt = template_path.read_text(encoding="utf-8", errors="ignore")
total_num = _extract_amount(data.get("total", ""))
prepay_num = _extract_amount(data.get("prepay", ""))
rest_num = max(0.0, total_num - prepay_num)
repl = {
"BKGNFIO": data.get("guest", ""),
"BKGNNUMBER": data.get("booking_number", ""),
"BKGNDATE": data.get("created_at", ""),
"BKGNBEGINDATE": data.get("checkin", ""),
"BKGNENDDATE": data.get("checkout", ""),
"BKGNCATEGORY": data.get("room", ""),
"BKGNNPEOPLE": str(data.get("guests", "")),
"BKGNCOSTFULL": data.get("total", ""),
"BKGNCOSTPAYFULL": data.get("prepay", ""),
"BKGNCOSTRESTFULL": f"{rest_num:,.0f}".replace(",", " "),
"BKGNNUMDAYS": str(data.get("nights", "")),
"CICLSERVICENAME": data.get("room", ""),
"CICLNUMDAYS": str(data.get("nights", "")),
"CICLDAYDICOST": data.get("day_price", ""),
}
for k, v in repl.items():
txt = txt.replace(k, str(v))
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(txt, encoding="utf-8")
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-уведомление")
p.add_argument("--template", default="/home/openclaw/.openclaw/workspace/skills/paradiz/data/shablon_broni.rtf", help="Путь к шаблону RTF")
p.add_argument("--rtf-out", default="", help="Путь сохранения заполненного листа брони (.rtf)")
args = p.parse_args()
dt_now = datetime.now()
now = dt_now.strftime("%Y-%m-%d %H:%M:%S")
booking_number = dt_now.strftime("PDZ-%Y%m%d-%H%M%S")
d1 = datetime.strptime(args.checkin, "%Y-%m-%d")
d2 = datetime.strptime(args.checkout, "%Y-%m-%d")
nights = max(0, (d2 - d1).days)
total_num = _extract_amount(args.total)
day_price = f"{(total_num / nights):,.0f}".replace(",", " ") if nights else ""
entry = {
"created_at": now,
"booking_number": booking_number,
"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,
"nights": nights,
"day_price": day_price,
}
out = Path(args.file)
out.parent.mkdir(parents=True, exist_ok=True)
human = (
f"[{now}] БРОНЬ {booking_number}\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")
# Генерируем клиентский лист брони из шаблона RTF
default_rtf_dir = out.parent / "listbroni"
rtf_out = args.rtf_out.strip() if args.rtf_out else str(default_rtf_dir / f"booking_{booking_number}.rtf")
try:
render_booking_rtf(Path(args.template), Path(rtf_out), entry)
except Exception:
pass
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"Номер брони: {booking_number}\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, "booking_number": booking_number, "saved": str(out), "jsonl": str(jsonl), "rtf": str(rtf_out), "telegram_sent": sent, "telegram_error": err}, ensure_ascii=False))
if __name__ == "__main__":
main()