-
Notifications
You must be signed in to change notification settings - Fork 571
/
Copy pathwhatsapp_utils.py
107 lines (82 loc) · 3.37 KB
/
whatsapp_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import logging
from flask import current_app, jsonify
import json
import requests
# from app.services.openai_service import generate_response
import re
def log_http_response(response):
logging.info(f"Status: {response.status_code}")
logging.info(f"Content-type: {response.headers.get('content-type')}")
logging.info(f"Body: {response.text}")
def get_text_message_input(recipient, text):
return json.dumps(
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": recipient,
"type": "text",
"text": {"preview_url": False, "body": text},
}
)
def generate_response(response):
# Return text in uppercase
return response.upper()
def send_message(data):
headers = {
"Content-type": "application/json",
"Authorization": f"Bearer {current_app.config['ACCESS_TOKEN']}",
}
url = f"https://graph.facebook.com/{current_app.config['VERSION']}/{current_app.config['PHONE_NUMBER_ID']}/messages"
try:
response = requests.post(
url, data=data, headers=headers, timeout=10
) # 10 seconds timeout as an example
response.raise_for_status() # Raises an HTTPError if the HTTP request returned an unsuccessful status code
except requests.Timeout:
logging.error("Timeout occurred while sending message")
return jsonify({"status": "error", "message": "Request timed out"}), 408
except (
requests.RequestException
) as e: # This will catch any general request exception
logging.error(f"Request failed due to: {e}")
return jsonify({"status": "error", "message": "Failed to send message"}), 500
else:
# Process the response as normal
log_http_response(response)
return response
def process_text_for_whatsapp(text):
# Remove brackets
pattern = r"\【.*?\】"
# Substitute the pattern with an empty string
text = re.sub(pattern, "", text).strip()
# Pattern to find double asterisks including the word(s) in between
pattern = r"\*\*(.*?)\*\*"
# Replacement pattern with single asterisks
replacement = r"*\1*"
# Substitute occurrences of the pattern with the replacement
whatsapp_style_text = re.sub(pattern, replacement, text)
return whatsapp_style_text
def process_whatsapp_message(body):
wa_id = body["entry"][0]["changes"][0]["value"]["contacts"][0]["wa_id"]
name = body["entry"][0]["changes"][0]["value"]["contacts"][0]["profile"]["name"]
message = body["entry"][0]["changes"][0]["value"]["messages"][0]
message_body = message["text"]["body"]
# TODO: implement custom function here
response = generate_response(message_body)
# OpenAI Integration
# response = generate_response(message_body, wa_id, name)
# response = process_text_for_whatsapp(response)
data = get_text_message_input(current_app.config["RECIPIENT_WAID"], response)
send_message(data)
def is_valid_whatsapp_message(body):
"""
Check if the incoming webhook event has a valid WhatsApp message structure.
"""
return (
body.get("object")
and body.get("entry")
and body["entry"][0].get("changes")
and body["entry"][0]["changes"][0].get("value")
and body["entry"][0]["changes"][0]["value"].get("messages")
and body["entry"][0]["changes"][0]["value"]["messages"][0]
)