fix(whatsapp-cloud): review follow-ups for #43921
- nous_subscription: gate the STT managed-default flip on openai-audio
entitlement and skip when a local backend (faster-whisper or custom
command) works; new _local_stt_backend_available() helper + tests
- whatsapp_cloud: WHATSAPP_CLOUD_{DM_POLICY,ALLOW_FROM,GROUP_POLICY,
GROUP_ALLOW_FROM} env overrides so both adapters can run in parallel;
normalize allowlist entries (JID/punctuation) to bare wa_id
- whatsapp_cloud: wrap per-message event build in try/except (dedup-marked
wamids would be silently dropped on Meta's batch retry otherwise)
- whatsapp_cloud: validate media_id before URL/filename interpolation,
delete transient .ogg after voice upload, FIFO-cap interactive-button
state dicts and per-chat wamid cache
- whatsapp_common: '# **Title**' headers no longer double-wrap asterisks
- setup wizard: read access token / app secret via getpass on TTYs
- docs: new WHATSAPP_CLOUD_* gating env vars
This commit is contained in:
parent
2ecb4e62bb
commit
52c7976f40
8 changed files with 319 additions and 35 deletions
|
|
@ -162,17 +162,25 @@ def _validate_access_token(value: str) -> tuple[bool, Optional[str]]:
|
|||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def _prompt(message: str, default: Optional[str] = None) -> str:
|
||||
def _prompt(message: str, default: Optional[str] = None, secret: bool = False) -> str:
|
||||
"""Read one line of input. Returns "" on EOF / Ctrl+C / empty input.
|
||||
|
||||
The ``default`` parameter is shown to the user but NOT auto-applied
|
||||
on empty input — callers handle the "user kept existing" case
|
||||
explicitly so they can distinguish between a real value and a
|
||||
display preview (e.g. ``"abc12345..."`` for masked secrets).
|
||||
|
||||
``secret=True`` reads via ``getpass`` so credentials are not echoed
|
||||
to the terminal (or left in scrollback).
|
||||
"""
|
||||
try:
|
||||
suffix = f" [{default}]" if default else ""
|
||||
raw = input(f"{message}{suffix}: ").strip()
|
||||
if secret and sys.stdin.isatty():
|
||||
import getpass
|
||||
|
||||
raw = getpass.getpass(f"{message}{suffix} (input hidden): ").strip()
|
||||
else:
|
||||
raw = input(f"{message}{suffix}: ").strip()
|
||||
except (EOFError, KeyboardInterrupt):
|
||||
print()
|
||||
return ""
|
||||
|
|
@ -185,6 +193,7 @@ def _prompt_validated(
|
|||
*,
|
||||
current: Optional[str] = None,
|
||||
help_text: Optional[str] = None,
|
||||
secret: bool = False,
|
||||
) -> Optional[str]:
|
||||
"""Repeat the prompt until the user enters a valid value or aborts.
|
||||
|
||||
|
|
@ -198,7 +207,7 @@ def _prompt_validated(
|
|||
attempts = 0
|
||||
while True:
|
||||
attempts += 1
|
||||
value = _prompt(f" → {message}", default=current)
|
||||
value = _prompt(f" → {message}", default=current, secret=secret)
|
||||
if not value:
|
||||
return None
|
||||
ok, reason = validator(value)
|
||||
|
|
@ -295,6 +304,7 @@ def run_whatsapp_cloud_setup() -> int:
|
|||
"Access Token",
|
||||
_validate_access_token,
|
||||
current=current_display,
|
||||
secret=True,
|
||||
help_text=(
|
||||
"Two options for getting one:\n\n"
|
||||
" (a) TEMP — App Dashboard → WhatsApp → API Setup →\n"
|
||||
|
|
@ -335,6 +345,7 @@ def run_whatsapp_cloud_setup() -> int:
|
|||
"App Secret",
|
||||
_validate_app_secret,
|
||||
current=current_secret_display,
|
||||
secret=True,
|
||||
help_text=(
|
||||
"Found in: App Dashboard → Settings → Basic →\n"
|
||||
"'App secret' field (click 'Show', enter your Facebook password).\n\n"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue