# AI WhatsApp Application
To get started with this tutorial, you need to have completed the Flask Web Development Tutorial, have a Flask application running on a https (secure domain). You will not be able to complete this section if you do not have the above. This Tutorial was created with the YouTube Video for Creating a WhatsApp ChatGPT Application with Flask (opens new window)
It is highly recommended that you watch the video as you go through the written Tutorial
# Get Meta Developer Account
Head over to Facebook Developer (opens new window) to access your Meta Developer account, if you do not already have one, create a new developer account.
# Create Meta Application
You will need a Business Profile to do this, create one and continue.
Try sending a WhatsApp Message to the user using the template provided on Meta Developer Platform, you will need to enter and approve all the test accounts that will be used. After development, you can enter a permanent WhatsApp number and you will receive a permanent token and will not need to approve all the test users.
# Test Webhook
We need to build a Webhook that will receive the messages from Meta.
The function below called: def whatsAppWebhook() is what you need to test the webhook: Select two random strings: (1) The Flask Route and (2) The Verify Token. You will need to provide both of these to Meta. More details are available in the youTube Video.
from flask import Flask, request
import json
import requests
from concurrent.futures import ThreadPoolExecutor
executor = ThreadPoolExecutor(2)
WHATSAPP_URL = 'https://graph.facebook.com/v17.0/number-id/messages'
WHATSAPP_TOKEN = 'Bearer Access-Token-From_Meta-Development-Portal'
def sendWhastAppMessage(phoneNumber, message):
headers = {"Authorization": WHATSAPP_TOKEN}
payload = { "messaging_product": "whatsapp",
"recipient_type": "individual",
"to": phoneNumber,
"type": "text",
"text": {"body": message}
}
requests.post(WHATSAPP_URL, headers=headers, json=payload)
return True
def handleWhatsAppMessage(fromId, text):
##Long function goes here
pass
@app.route('/a-random-string', methods=['GET', 'POST'])
def whatsAppWebhook():
if request.method == 'GET':
VERIFY_TOKEN = 'another-random-string'
mode = request.args.get('hub.mode')
token = request.args.get('hub.verify_token')
challenge = request.args.get('hub.challenge')
if mode == 'subscribe' and token == VERIFY_TOKEN:
return challenge, 200
else:
return 'error', 403
if request.method == 'POST':
data = request.json
if 'object' in data and 'entry' in data:
if data['object'] == 'whatsapp_business_account':
for entry in data['entry']:
fromId = entry['changes'][0]['value']['messages'][0]['from']
msgType = entry['changes'][0]['value']['messages'][0]['type']
text = entry['changes'][0]['value']['messages'][0]['text']['body']
sendWhastAppMessage(fromId, f"We have received: {text}")
#executor.submit(handleWhatsAppMessage, fromId, text)
return 'success', 200
Based on the code above - our webhook URL will be:
https://maximus-the-great.com/a-random-string
This 'a-random-string' is the @app.route for the Flask application, you can use any route that makes sense to you, but a random string that you change regularly is a good option.
# Connect OpenAI API
Add the following code to Make an OpenAI API request
import openai
openai.api_key = 'enter-openai-api-key'
def makeOpenAIFunctionCall(text):
system_instruction = "You are a helpful Chatbot based on WhatsApp. Include relevant emojis in your response."
messages = [{"role": "system", "content": system_instruction}]
question = {}
question['role'] = 'user'
question['content'] = text
messages.append(question)
try:
response = openai.ChatCompletion.create(model='gpt-3.5-turbo-0613',messages=messages)
return response['choices'][0]['message']['content']
except:
return ''
Bring it all together by defining the function that talks to the Webhook as seen below
The function should look like:
```python
def handleWhatsAppMessage(fromId, text):
answer = makeOpenAIFunctionCall(text)
sendWhastAppMessage(fromId, answer)
Remember to add this line inside the Webhook POST Call:
......
executor.submit(handleWhatsAppMessage, fromId, text)
......
# Final Code
The final code for the application should look like this
from flask import Flask, request
import requests
import json
import openai
openai.api_key = 'openai-api-key'
from concurrent.futures import ThreadPoolExecutor
executor = ThreadPoolExecutor(2)
app = Flask(__name__)
WHATSAPP_URL = 'https://graph.facebook.com/v17.0/phone-number-id/messages'
WHATSAPP_TOKEN = 'Bearer whatsapp-access-token-from-meta'
@app.route("/")
def hello():
return "<h1 style='color:blue'>Hello There! We are Live</h1>"
def sendWhastAppMessage(phoneNumber, message):
headers = {"Authorization": WHATSAPP_TOKEN}
payload = { "messaging_product": "whatsapp",
"recipient_type": "individual",
"to": phoneNumber,
"type": "text",
"text": {"body": message}
}
requests.post(WHATSAPP_URL, headers=headers, json=payload)
return True
def makeOpenAIFunctionCall(text):
system_instruction = "You are a helpful Chatbot based on WhatsApp. Include relevant emojis>
messages = [{"role": "system", "content": system_instruction}]
question = {}
question['role'] = 'user'
question['content'] = text
messages.append(question)
try:
response = openai.ChatCompletion.create(model='gpt-3.5-turbo-0613',messages=messages)
return response['choices'][0]['message']['content']
except:
return ''
def handleWhatsAppMessage(fromId, text):
answer = makeOpenAIFunctionCall(text)
sendWhastAppMessage(fromId, answer)
@app.route('/a-random-string', methods=['GET', 'POST'])
def whatsAppWebhook():
if request.method == 'GET':
VERIFY_TOKEN = 'another-random-string'
mode = request.args.get('hub.mode')
token = request.args.get('hub.verify_token')
challenge = request.args.get('hub.challenge')
if mode == 'subscribe' and token == VERIFY_TOKEN:
return challenge, 200
else:
return 'error', 403
if request.method == 'POST':
data = request.json
if 'object' in data and 'entry' in data:
if data['object'] == 'whatsapp_business_account':
for entry in data['entry']:
fromId = entry['changes'][0]['value']['messages'][0]['from']
msgType = entry['changes'][0]['value']['messages'][0]['type']
text = entry['changes'][0]['value']['messages'][0]['text']['body']
#sendWhastAppMessage(fromId, f"We have received: {text}")
executor.submit(handleWhatsAppMessage, fromId, text)
return 'success', 200
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5555)
Happy Coding 🤖