75 lines
3.0 KiB
Python
75 lines
3.0 KiB
Python
from typing import List, Optional, Union
|
|
from pydantic import BaseModel, Field
|
|
|
|
class TextMessage(BaseModel):
|
|
body: str
|
|
|
|
class ButtonMessage(BaseModel):
|
|
# O WhatsApp envia 'id' e 'title' para as respostas de botões,
|
|
# mas o Pydantic pode esperar 'payload' e 'text' se for para envio.
|
|
# Para *recebimento*, precisamos mapear o que vem.
|
|
# O payload que você recebeu mostra 'id' e 'title'.
|
|
|
|
# Para a *resposta* de um botão:
|
|
id: str # O ID do botão clicado (que você definiu no seu código)
|
|
title: str # O texto do botão clicado
|
|
|
|
# No seu handle_button_response, você espera 'payload'.
|
|
# Isso indica que ButtonMessage foi usado para ENVIO antes.
|
|
# Para *recebimento*, a Meta envia 'id' e 'title'.
|
|
# A melhor prática é ter dois modelos, um para envio e um para recebimento,
|
|
# ou usar aliases condicionais.
|
|
|
|
# Pela sua mensagem de erro, o Pydantic (na validação do WebhookEvent)
|
|
# esperava 'payload' e 'text' para o `button_reply`.
|
|
# Vamos renomear e usar aliases para compatibilidade com o que a Meta envia E o que o seu handler espera.
|
|
# O `id` do botão clicado é o `payload` que você espera no seu handler.
|
|
# O `title` do botão clicado é o `text` que você espera.
|
|
|
|
# Modelagem para RECEBIMENTO de resposta de botão:
|
|
payload: str = Field(alias="id") # Mapeia 'id' do JSON recebido para 'payload' no Python
|
|
text: str = Field(alias="title") # Mapeia 'title' do JSON recebido para 'text' no Python
|
|
|
|
class ListReply(BaseModel):
|
|
id: str
|
|
title: str
|
|
|
|
class InteractiveMessage(BaseModel):
|
|
type: str # 'list_reply', 'button_reply', etc.
|
|
list_reply: Optional[ListReply] = None
|
|
button_reply: Optional[ButtonMessage] = None # Renomeado para button_reply para consistência
|
|
|
|
class Message(BaseModel): # ESTA É A CLASSE 'Message' QUE ESTAVA FALTANDO!
|
|
from_: str = Field(alias="from") # 'from' é palavra reservada em Python, então usamos alias
|
|
id: str
|
|
timestamp: str
|
|
type: str # 'text', 'image', 'button', 'interactive', etc.
|
|
text: Optional[TextMessage] = None
|
|
button: Optional[ButtonMessage] = None # <-- AQUI! Garanta que está usando o ButtonMessage ajustado
|
|
interactive: Optional[InteractiveMessage] = None
|
|
# Adicione outros tipos de mensagem aqui se precisar processá-los (image, audio, video, etc.)
|
|
|
|
class Status(BaseModel):
|
|
id: str
|
|
status: str # 'sent', 'delivered', 'read', 'failed'
|
|
timestamp: str
|
|
recipient_id: str
|
|
# Adicione outros campos de status se necessário
|
|
|
|
class ChangeValue(BaseModel):
|
|
messaging_product: str
|
|
metadata: dict # Pode conter phone_number_id, display_phone_number
|
|
messages: Optional[List[Message]] = None
|
|
statuses: Optional[List[Status]] = None # Para atualizações de status
|
|
|
|
class Change(BaseModel):
|
|
field: str # 'messages' ou 'statuses'
|
|
value: ChangeValue
|
|
|
|
class Entry(BaseModel):
|
|
id: str
|
|
changes: List[Change]
|
|
|
|
class WebhookEvent(BaseModel): # Este é o seu modelo principal do evento
|
|
object: str # 'whatsapp_business_account'
|
|
entry: List[Entry] |