我正在开发一个项目,使用 FastAPI 来处理传入的 WhatsApp 消息并对其进行响应。我已经设置了 webhook,并且可以成功接收消息。但是,我在尝试使用 WhatsApp Business API 将响应发送回用户时遇到了问题。
这是我的代码的相关部分:
from fastapi import FastAPI, Request, HTTPException, Query
from fastapi.responses import JSONResponse
from pydantic import BaseModel
import requests
app = FastAPI()
VERIFY_TOKEN = "tourism"
class WhatsAppEvent(BaseModel):
message: dict
WHATSAPP_API_ENDPOINT = "https://graph.facebook.com/v18.0/***(Entered my phone number ID)/messages"
WHATSAPP_API_TOKEN = "***(Entered my API access token)"
@app.post("/")
async def handle_post_request(request: Request):
# Process the incoming POST request here
data = await request.json()
print("Received POST request data:", data)
# Send a response
return {"status": "success", "message": "POST request received"}
@app.get("/")
def verify(request: Request):
mode = request.query_params.get('hub.mode')
challenge = request.query_params.get('hub.challenge')
token = request.query_params.get('hub.verify_token')
if mode and token:
if mode == 'subscribe' and token == VERIFY_TOKEN:
print("WEBHOOK_VERIFIED")
return JSONResponse(content=int(challenge), status_code=200)
else:
raise HTTPException(status_code=403, detail="Verification failed")
return {"code": 200, 'message': 'test'}
@app.post("/incoming-message")
def receive_message(event: WhatsAppEvent):
try:
user_message = event.message['text']
sender_id = event.message['sender']['id']
bot_response = f'You said: {user_message}' #sending an echo message
# Prepare response for WhatsApp
response_data = {
'recipient': {'id': sender_id},
'message': {'text': bot_response}
}
send_whatsapp_message(sender_id, bot_response)
return JSONResponse(content=response_data, status_code=200)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error processing message: {str(e)}")
def send_whatsapp_message(recipient_id, message_body):
headers = {
'Authorization': f'Bearer {WHATSAPP_API_TOKEN}',
'Content-Type': 'application/json'
}
data = {
'phone': recipient_id,
'message': {
'text': message_body
}
}
try:
response = requests.post(WHATSAPP_API_ENDPOINT, headers=headers, json=data)
response.raise_for_status() # Raises HTTPError for bad responses
print("WhatsApp API response:", response.text) # Add this line for debugging
return response.json() # If you want to return the API response data
except requests.exceptions.HTTPError as errh:
print("HTTP Error:", errh)
raise HTTPException(status_code=response.status_code, detail=f"HTTP Error: {errh}")
except requests.exceptions.RequestException as err:
print("Request Error:", err)
raise HTTPException(status_code=response.status_code, detail=f"Request Error: {err}")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, reload=False, host="0.0.0.0", port=8000)
我已经验证了 webhook 正在工作(控制台中打印了 WEBHOOK_VERIFIED),并且我可以在日志中看到传入的消息。但是,send_whatsapp_message 函数似乎没有成功发送消息。
WhatsApp API 的响应如下:
WEBHOOK_VERIFIED
INFO: 2a03:2880:23ff:5::face:b00c:0 - "GET /?hub.mode=subscribe&hub.challenge=1310749767&hub.verify_token=tourism HTTP/1.1" 200 OK
Received POST request data: {'object': 'whatsapp_business_account', 'entry': [{'id': '**(My ID)', 'changes': [{'value': {'messaging_product': 'whatsapp', 'metadata': {'display_phone_number': '**(My number)', 'phone_number_id': '**(My Phone number ID)'}, 'contacts': [{'profile': {'name': 'Rishikesh Dasari'}, 'wa_id': '**(recipient Number)'}], 'messages': [{'from': '**(recipient Number)', 'id': 'wamid.HBgMOTE5MzkwMzYwMjYyFQIAEhgWM0VCMEMyRUU3MzQ4Q0VCNjFGQUIzRgA=', 'timestamp': '1705643757', 'text': {'body': 'hello'}, 'type': 'text'}]}, 'field': 'messages'}]}]}
INFO: 2a03:2880:20ff:b::face:b00c:0 - "POST / HTTP/1.1" 200 OK
我已经仔细检查了 WhatsApp API 端点、令牌和请求的结构,但我仍然无法发送消息。我怀疑我的 send_whatsapp_message 函数可能有问题。
有人可以查看代码并提供有关可能导致问题的原因的见解吗?此外,如果有更好的方法来处理在 FastAPI 中发送 WhatsApp 消息,我愿意接受建议。
您的代码看起来总体没问题,问题可能与您如何构建 WhatsApp API 的有效负载有关。让我们回顾一下并进行一些调整:
检查有效的 WhatsApp API 端点: 确保
WHATSAPP_API_ENDPOINT
正确且与用于发送消息的 WhatsApp Business API 端点匹配。
更新
send_whatsapp_message
功能:
在您的 send_whatsapp_message
函数中,您似乎正在使用 phone
作为收件人电话号码的键。但是,根据 WhatsApp Business API 文档,它应该是 recipient_type
和 recipient_id
。
这是
send_whatsapp_message
函数的更新版本:
def send_whatsapp_message(recipient_id, message_body):
headers = {
'Authorization': f'Bearer {WHATSAPP_API_TOKEN}',
'Content-Type': 'application/json'
}
data = {
'recipient_type': 'individual',
'recipient_id': recipient_id,
'message': {
'content': {
'text': message_body
}
}
}
try:
response = requests.post(WHATSAPP_API_ENDPOINT, headers=headers, json=data)
response.raise_for_status() # Raises HTTPError for bad responses
print("WhatsApp API response:", response.text) # Add this line for debugging
return response.json() # If you want to return the API response data
except requests.exceptions.HTTPError as errh:
print("HTTP Error:", errh)
raise HTTPException(status_code=response.status_code, detail=f"HTTP Error: {errh}")
except requests.exceptions.RequestException as err:
print("Request Error:", err)
raise HTTPException(status_code=response.status_code, detail=f"Request Error: {err}")
此修改使有效负载结构与 WhatsApp Business API 要求保持一致。
验证 WhatsApp API 令牌和端点: 仔细检查您的 WhatsApp API 令牌 (
WHATSAPP_API_TOKEN
) 和端点 (WHATSAPP_API_ENDPOINT
) 是否正确。
检查 WhatsApp API 响应: 打印 WhatsApp API 的响应文本,以更深入地了解任何错误消息或问题:
print("WhatsApp API response:", response.text)
通过这些调整,您的
send_whatsapp_message
功能应该能够更好地符合 WhatsApp Business API 要求。进行这些更改后,观察打印的响应是否有任何错误消息并相应地调整代码。