"""Background sync loop: watches bot_drafts for updates from Web Wizard or external API. If a draft was updated in the Wizard: - If status == 'active': re-renders review text & keyboard in Bale so chat reflects edits. - If status == 'committed': edits Bale message to show it was committed and removes buttons. - If status == 'cancelled': edits Bale message to show it was cancelled and removes buttons. """ import asyncio import logging from app import drafts as draft_store from app.handlers import quote logger = logging.getLogger("bot.sync") async def sync_drafts_loop(ctx) -> None: while True: try: pending = await draft_store.get_pending_bale_updates() for draft in pending: try: if not draft.review_message_id: await draft_store.set_bale_updated_at(draft.id) continue if draft.status == "committed": payload = draft.payload or {} quote_id = payload.get("committed_quote_id") or "" msg = "✅ این پیشنهاد با موفقیت در سیستم ثبت نهایی شد." if quote_id: msg += f"\nشناسه پیشنهاد: {quote_id}" await ctx.bale.edit_message_text(draft.chat_id, draft.review_message_id, msg, reply_markup=None) await draft_store.set_bale_updated_at(draft.id) logger.info("Synced committed draft %s to Bale message %s", draft.id, draft.review_message_id) elif draft.status == "cancelled": msg = "❌ این پیش‌نویس لغو شد." await ctx.bale.edit_message_text(draft.chat_id, draft.review_message_id, msg, reply_markup=None) await draft_store.set_bale_updated_at(draft.id) logger.info("Synced cancelled draft %s to Bale message %s", draft.id, draft.review_message_id) elif draft.status == "active" and draft.kind == draft_store.KIND_QUOTE: await quote.render(ctx, draft.chat_id, draft, fresh=False) await draft_store.set_bale_updated_at(draft.id) logger.info("Synced active draft %s edits to Bale message %s", draft.id, draft.review_message_id) else: await draft_store.set_bale_updated_at(draft.id) except Exception as exc: logger.warning("Failed to sync draft %s to Bale: %s", draft.id, exc) await draft_store.set_bale_updated_at(draft.id) except asyncio.CancelledError: break except Exception: logger.exception("Error in sync_drafts_loop") await asyncio.sleep(1.5)