# 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)

Watch the video (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 🤖