template
This commit is contained in:
parent
dcae960928
commit
a7e6ed2e4b
3 changed files with 107 additions and 14 deletions
|
|
@ -12,7 +12,19 @@ from sqlalchemy.orm import Session, selectinload
|
|||
|
||||
from .config import settings
|
||||
from .models import UserAccount, WhatsAppBusinessAccount, WhatsAppMessage, WhatsAppMessageTemplate, WhatsAppMetaConnection
|
||||
from .whatsapp_onboarding import _graph, _graph_error_message, _owned_account, _quality_label, _token_app_id
|
||||
from .whatsapp_onboarding import (
|
||||
_apply_phones,
|
||||
_debug_token,
|
||||
_graph,
|
||||
_graph_error_message,
|
||||
_load_phones,
|
||||
_load_waba,
|
||||
_owned_account,
|
||||
_phone_ids_from_debug,
|
||||
_quality_label,
|
||||
_token_app_id,
|
||||
_waba_ids_from_debug,
|
||||
)
|
||||
|
||||
_NAME = re.compile(r"^[a-z0-9_]{1,512}$")
|
||||
_LANG = re.compile(r"^[a-z]{2}(_[A-Z]{2})?$")
|
||||
|
|
@ -510,6 +522,62 @@ async def _pull_templates(db: Session, account: WhatsAppBusinessAccount, token:
|
|||
return seen
|
||||
|
||||
|
||||
def _wrong_template_node(exc: HTTPException) -> bool:
|
||||
detail = str(exc.detail).lower()
|
||||
return "message_templates" in detail and "nonexisting field" in detail
|
||||
|
||||
|
||||
async def _correct_waba_id(db: Session, account: WhatsAppBusinessAccount, token: str) -> bool:
|
||||
"""Replace a stored phone-number ID with the WABA ID from the embedded-signup token."""
|
||||
try:
|
||||
debug = await _debug_token(db, token)
|
||||
except HTTPException:
|
||||
return False
|
||||
wabas = _waba_ids_from_debug(debug)
|
||||
phone_ids = set(_phone_ids_from_debug(debug))
|
||||
stored = str(account.waba_id)
|
||||
if not wabas or stored in wabas:
|
||||
return False
|
||||
real = wabas[0] if len(wabas) == 1 else None
|
||||
if real is None:
|
||||
for waba in wabas:
|
||||
try:
|
||||
rows = await _load_phones(token, waba)
|
||||
except HTTPException:
|
||||
continue
|
||||
ids = {str(row.get("id")) for row in rows if row.get("id")}
|
||||
if stored in ids or phone_ids.intersection(ids):
|
||||
real = waba
|
||||
break
|
||||
if not real or real == stored:
|
||||
return False
|
||||
taken = db.scalar(
|
||||
select(WhatsAppBusinessAccount.id).where(
|
||||
WhatsAppBusinessAccount.waba_id == real,
|
||||
WhatsAppBusinessAccount.id != account.id,
|
||||
)
|
||||
)
|
||||
if taken is not None:
|
||||
return False
|
||||
account.waba_id = real
|
||||
try:
|
||||
info = await _load_waba(token, real)
|
||||
name = str(info.get("name") or "").strip()
|
||||
if name:
|
||||
account.name = name[:200]
|
||||
except HTTPException:
|
||||
pass
|
||||
user = db.get(UserAccount, account.user_id)
|
||||
if user is not None:
|
||||
try:
|
||||
rows = await _load_phones(token, real)
|
||||
_apply_phones(db, user, account, rows, None)
|
||||
except HTTPException:
|
||||
pass
|
||||
db.flush()
|
||||
return True
|
||||
|
||||
|
||||
async def sync_account_templates(db: Session, account: WhatsAppBusinessAccount) -> str | None:
|
||||
tokens = _candidate_tokens(db, account)
|
||||
if not tokens:
|
||||
|
|
@ -519,7 +587,13 @@ async def sync_account_templates(db: Session, account: WhatsAppBusinessAccount)
|
|||
last_error: str | None = None
|
||||
for index, token in enumerate(tokens):
|
||||
try:
|
||||
seen = await _pull_templates(db, account, token)
|
||||
try:
|
||||
seen = await _pull_templates(db, account, token)
|
||||
except HTTPException as exc:
|
||||
db.rollback()
|
||||
if not _wrong_template_node(exc) or not await _correct_waba_id(db, account, token):
|
||||
raise
|
||||
seen = await _pull_templates(db, account, token)
|
||||
except HTTPException as exc:
|
||||
db.rollback()
|
||||
last_error = str(exc.detail)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue