OpenAI has not too long ago launched a spread of exceptional enhancements which have left customers amazed. Amongst these additions, the OpenAI operate calling characteristic has emerged as essentially the most outstanding addition. With this highly effective performance, builders achieve the power to pick out and invoke for resolving particular issues. A key side of OpenAI’s operate calling characteristic is its seamless integration with exterior APIs, enabling builders to generate responses by leveraging exterior providers.
In our earlier blogs, we explored “How To Use OpenAI Operate Calling To Create an Appointment Reserving Chatbot”. By this exploration, we created a chatbot that integrates with the Google Calendar API. This integration empowers the chatbot to effectively deal with appointment bookings and harness the complete performance of the Google calendar.
On this weblog, we are going to discover find out how to create an appointment-booking chatbot, which integrates with the GoHighLevel platform for appointment administration. GoHighLevel is a buyer relationship administration (CRM) platform that provides numerous options for companies to handle their buyer interactions, advertising campaigns, gross sales processes, and extra. One of many options supplied by GoHighLevel is the calendar performance. The GoHighLevel calendar permits customers to schedule and handle appointments and delete appointments.
Let’s begin with the weblog the place we are going to discover find out how to create an appointment reserving chatbot that seamlessly integrates with the GoHighLevel (GHL) platform.
Step 1:
We’ll begin by organising the GoHighLevel platform. We have to first go to the https://app.gohighlevel.com/ web site after which declare our free 14-day trial. It’s essential give your Firm Title, Title, E-mail ID, Cellphone quantity, and bank card particulars to join the primary time.
Upon getting created an account, you will note under like dashboard:
Step 2:
We have to use GoHighLevel API, to handle appointment creation, updation, and deletion. With the intention to use the API, we want an API key.
There are 2 kinds of API keys accessible:
- Company API Key – which is used to handle the agency-level objects like sub-accounts, and customers.
- Location API Key – which is used to handle all of the objects that are a part of sub-accounts (contacts, appointments, alternatives, and many others.)
To handle appointments we want a Location API key. To generate a Location API key it is advisable to first add a location by making a sub-account.
To create a sub-account it is advisable to first click on the “Sub-Accounts” from the left panel after which hit “Create Sub-Account” as proven under:
Step 3:
It’s going to open a display screen like under, the place it is advisable to choose “Clean Snapshot” beneath the title “Common Account”.
Then, it’ll open a display screen with a map like under. It’s essential choose your location after which proceed together with your chosen location by clicking the arrow.
After this, it’ll open a tab with the title “Add account”. It’s essential add your particulars after which hit the “save” button. It’s going to create a sub-account with the given location.
Step 4:
Subsequent, It’s essential swap to the not too long ago created sub-account by clicking on “Click on right here to modify” from the left panel as proven within the under picture:
It’s going to open up a variety field that has all sub-accounts listed. You possibly can select one from the record, and the system will swap to that account. after which you may see a display screen like under:
Step 5:
After making a sub-account, you may retrieve the Location API key, which shall be used for appointment administration. To acquire the Location API key, first go to the “Settings” possibility situated within the left panel after which choose “Enterprise Profile” from the accessible choices. A display screen will seem the place it is advisable to scroll down a bit, and you can see your Location API key as proven within the under picture:
Step 6:
Transferring ahead, we have to add workers to our workforce. So as to add an worker, it is advisable to comply with the under steps:
- First, it is advisable to go to the setting after which choose the “My Workers” possibility from all accessible choices.
- On the display screen that seems, find and click on on the “Add worker” button.
- Present the required private particulars, together with First Title, Final Title, E-mail, Password, and Cellphone Quantity.
- Subsequent, set the “Consumer Roles” to “Consumer” for the worker.
- Lastly, click on on the “Save” button to save lots of the worker’s data.
Step 7:
Now, let’s proceed with creating a bunch that may assist in workforce administration. To create the group, it is advisable to comply with under steps:
- Begin by deciding on the “Calendars” possibility from the left panel.
- On the precise aspect of the display screen, find and click on on the “Create Group” button.
- It’s going to open up a kind for group creation. Within the kind, you will have to supply the next particulars: Group Title, Group Description, and Calendar URL.
- Upon getting crammed within the crucial data, submit the shape.
Within the Calendar URL, you may merely present any string like “demo-calendar”.
Step 8:
Let’s now transfer ahead and create a calendar that may facilitate appointment administration capabilities. To create the calendar, comply with the under steps:
- From the identical display screen, choose the “Create Calendar” possibility.
- This motion will open up an inventory of choices. From the record, select “Easy Calendar”.
- A kind will seem, through which it is advisable to fill in all the required particulars.
- Upon getting crammed within the crucial particulars, click on on the “Full” button.
For this demo, we’ve got saved the “Appointment Slot Setting” as under:
Step 9:
Upon getting created a calendar, the subsequent step is to maneuver it to the beforehand created group. To perform this, comply with the steps under:
- Choose the “Calendars” possibility from the settings.
- On the display screen, find the calendar that was created earlier.
- Click on on the three dots image located on the precise aspect of the calendar.
- This motion will open up a variety field, as depicted under.
- From the choice field, select the choice “Transfer to Group”.
- A pop-up field will seem, permitting you to pick out the specified group for the calendar and hit the “Choose” button.
Step 10:
Now we have accomplished the essential setup of “GoHighLevel.” Now, we’re totally ready to make the most of the GoHighLevel API for appointment creation, updating, and deletion. To make use of the GoHighLevel API, we want three kinds of IDs: Group ID, Calendar ID and Consumer ID. We’ll receive these IDs within the following steps.
To acquire the Group ID, it is advisable to comply with the under steps:
- Choose the “Calendars” possibility from the settings.
- On the display screen, You can find a tab for “Teams” through which you’ll find the group that was created earlier.
- Click on on the three dots image located on the precise aspect of the group data.
- This motion will open up a variety field, as depicted under.
- Click on on the “Copy Embed Code” from the choice field.
Your copied embed code will appear like under:
<iframe src=”https://api.leadconnectorhq.com/widget/group/NZc2nxIeE6a2liSwqmNX” fashion=”width: 100%;border:none;overflow: hidden;” scrolling=”no” id=”<your_group_id>_1688194531391″></iframe><br><script src=”https://hyperlink.msgsndr.com/js/form_embed.js” sort=”textual content/javascript”></script>
From the URL above, you may find the ID area. The string earlier than the “_” image represents your Group ID.
Step 11:
Transferring ahead on this step, we are going to receive our Calendar ID.
To acquire the Calendar ID, it is advisable to comply with the under steps:
- Choose the “Calendars” possibility from the settings.
- On the display screen, You can find a tab for “Calendars” through which you’ll find the calendar that was created earlier.
- Click on on the three dots image located on the precise aspect of the calendar data.
- This motion will open up a variety field, as depicted under.
- Click on on the “Copy Embed Code” from the choice field.
Your copied embed code will appear like under as earlier:
<iframe src=”https://api.leadconnectorhq.com/widget/reserving/kK8LwFPuNByksXB3h18s” fashion=”width: 100%;border:none;overflow: hidden;” scrolling=”no” id=”<your_calendar_id>_1688196021697″></iframe><br><script src=”https://hyperlink.msgsndr.com/js/form_embed.js” sort=”textual content/javascript”></script>
Step 12:
On this step, let’s proceed to acquire the Consumer ID.
To acquire the Consumer ID, it is advisable to comply with the under steps:
After completion of those steps, we’ve got all 3 IDs, now we are going to transfer ahead to secret an appointment reserving chatbot utilizing python.
Step 13:
Now, it’s time to start out with the event of the Python script for an appointment reserving chatbot. To perform this, we are going to leverage OpenAI’s operate calling characteristic, which integrates with the GHL Calendar for environment friendly appointment administration.
First, we are going to import the required libraries:
import requests
import json
from datetime import date, datetime, timedelta
import time
import pytz
Step 14:
Subsequent, we are going to outline a utility operate that may name ChatGPT and generate responses. So as to add this performance to our script, embrace the next traces of code:
GPT_MODEL = "gpt-3.5-turbo-0613"
openai_api_key = "<your_openai_key>"
def chat_completion_request(messages, capabilities=None, function_call=None, mannequin=GPT_MODEL):
headers = {
"Content material-Kind": "software/json",
"Authorization": "Bearer " + openai_api_key,
}
json_data = {"mannequin": mannequin, "messages": messages}
if capabilities shouldn't be None:
json_data.replace({"capabilities": capabilities})
if function_call shouldn't be None:
json_data.replace({"function_call": function_call})
strive:
response = requests.submit(
"https://api.openai.com/v1/chat/completions",
headers=headers,
json=json_data,
)
return response
besides Exception as e:
print("Unable to generate ChatCompletion response")
print(f"Exception: {e}")
return e
Step 15:
Transferring ahead, on this step, we are going to outline a operate that calls the GHL appointment reserving endpoint. Nevertheless, earlier than that, we have to create one other operate that converts the date and time supplied by the person into the ISO 8601 date format. The ISO 8601 format is an internationally acknowledged customary for representing dates and occasions.
We are able to outline each capabilities as follows:
limit1 = datetime.strptime("10:00:00", "%H:%M:%S").time()
limit2 = datetime.strptime("17:00:00", "%H:%M:%S").time()
limit3 = datetime.strptime("12:00:00", "%H:%M:%S").time()
headers = {
'Authorization': 'Bearer <Your_Location_API_key>'
}
def convert_to_iso8601(datetime_string, target_timezone):
datetime_format = "%Y-%m-%d %H:%M:%S"
dt = datetime.strptime(datetime_string, datetime_format)
source_timezone = pytz.timezone('Asia/Kolkata')
dt = source_timezone.localize(dt)
target_timezone = pytz.timezone(target_timezone)
dt = dt.astimezone(target_timezone)
iso8601_datetime = dt.strftime("%Y-%m-%dTpercentH:%M:%Spercentz")
iso8601_datetime = iso8601_datetime[:-2] + ":" + iso8601_datetime[-2:]
return iso8601_datetime
def appointment_booking(arguments):
strive:
provided_date = datetime.strptime(json.masses(arguments)['date'], "%Y-%m-%d")
provided_time = datetime.strptime(json.masses(arguments)['time'].change("PM","").change("AM","").strip(), "%H:%M:%S").time()
strive:
email_address = json.masses(arguments)['email_address']
besides:
return "Please present e-mail ID for identification."
strive:
phone_number = json.masses(arguments)['phone_number']
besides:
return "Please present a cellphone quantity for identification."
if provided_date and provided_time and email_address and phone_number:
start_date_time = str(provided_date.date()) + " " + str(provided_time)
iso8601_datetime = convert_to_iso8601(start_date_time, 'Asia/Kolkata')
if day_list[provided_date.weekday()] == "Saturday":
if provided_time >= limit1 and provided_time <= limit3:
url = "https://relaxation.gohighlevel.com/v1/appointments/"
payload = {
"calendarId": "kK8LwFPuNByksXB3h18s",
"selectedTimezone": "Asia/Calcutta",
"selectedSlot": iso8601_datetime,
"e-mail": email_address,
"cellphone": phone_number
}
response = requests.request("POST", url, headers=headers, information=payload)
response = json.masses(response.textual content)
strive:
if response['id']:
return "Appointment booked efficiently."
besides:
return response['selectedSlot']['message']
else:
return "Please attempt to guide an appointment into working hours, which is 10 AM to 2 PM at saturday."
else:
if provided_time >= limit1 and provided_time <= limit2:
url = "https://relaxation.gohighlevel.com/v1/appointments/"
payload = {
"calendarId": "kK8LwFPuNByksXB3h18s",
"selectedTimezone": "Asia/Calcutta",
"selectedSlot": iso8601_datetime,
"e-mail": email_address,
"cellphone": phone_number
}
response = requests.request("POST", url, headers=headers, information=payload)
response = json.masses(response.textual content)
strive:
if response['id']:
return "Appointment booked efficiently."
besides:
return response['selectedSlot']['message']
else:
return "Please attempt to guide an appointment into working hours, which is 10 AM to 7 PM."
else:
return "Please present all the required data: Appointment date, time, e-mail ID, Cellphone quantity."
besides:
return "We face an error whereas processing your request. Please strive once more."
Step 16:
Now, let’s outline a operate that may replace appointments utilizing the GHL endpoint. To replace an appointment, we have to discover the corresponding ‘ID’ of the appointment. Subsequently, we are going to first describe a operate that fetches the ‘ID’ primarily based on the parameters supplied by the person. This operate will then return the ‘ID’ to the replace operate.
We are able to outline each capabilities as follows:
def get_all_booked_appointment(arguments):
strive:
provided_date = datetime.strptime(json.masses(arguments)['date'], "%Y-%m-%d")
ending_date_time = datetime.strptime(json.masses(arguments)['date'], "%Y-%m-%d") + timedelta(days=1)
strive:
email_address = json.masses(arguments)['email_address']
besides:
return "Please present e-mail ID for identification."
if provided_date and email_address:
starting_timestamp = time.mktime(provided_date.timetuple()) * 1000
ending_timestamp = time.mktime(ending_date_time.timetuple()) * 1000
url = f"https://relaxation.gohighlevel.com/v1/appointments/?startDate={starting_timestamp}&endDate={ending_timestamp}&userId=oJbRc7r2HBYunuvJ3XC7&calendarId=kK8LwFPuNByksXB3h18s&teamId=ONZc2nxIeE6a2liSwqmNX&includeAll=true"
payload={}
response = requests.request("GET", url, headers=headers, information=payload)
response = json.masses(response.textual content)
occasions = []
for ingredient in response['appointments']:
if ingredient['contact']['email'] == email_address:
occasions.append(ingredient)
if len(occasions) == 1:
id = occasions[0]['id']
return id
elif len(occasions) > 1:
print("You might have a number of appointments with the identical e-mail handle:")
depend = 1
for ele in occasions:
print(str(depend)+"]")
print(ele['address'])
print(ele['startTime'])
print(ele['endTime'])
print(ele['contact']['email'])
print()
depend = depend + 1
event_number = int(enter("Please enter which appointment:"))
if event_number >= 1 and event_number <= len(occasions):
id = occasions[event_number - 1]['id']
return id
else:
return "Please choose legitimate occasion quantity"
else:
return "No registered occasion discovered with this e-mail ID."
else:
return "Please present all the required data: Appointment date and e-mail ID."
besides:
return "We face an error whereas processing your request. Please strive once more."
def appointment_updation(arguments):
strive:
provided_date = datetime.strptime(json.masses(arguments)['to_date'], "%Y-%m-%d")
provided_time = datetime.strptime(json.masses(arguments)['time'].change("PM","").change("AM","").strip(), "%H:%M:%S").time()
if provided_date and provided_time and json.masses(arguments)['date'] and json.masses(arguments)['email_address']:
start_date_time = str(provided_date.date()) + " " + str(provided_time)
iso8601_datetime = convert_to_iso8601(start_date_time, 'Asia/Kolkata')
if day_list[provided_date.date().weekday()] == "Saturday":
if provided_time >= limit1 and provided_time <= limit3:
id = get_all_booked_appointment(arguments)
if id == "Please choose legitimate occasion quantity" or id == "No registered occasion discovered with this e-mail ID." or id == "We face an error whereas processing your request. Please strive once more.":
return id
else:
url = f"https://relaxation.gohighlevel.com/v1/appointments/{id}"
payload = {
"selectedTimezone": "Asia/Calcutta",
"selectedSlot": iso8601_datetime
}
response = requests.request("PUT", url, headers=headers, information=payload)
response = json.masses(response.textual content)
strive:
if response['id']:
return "Appointment up to date efficiently."
besides:
return response['selectedSlot']['message']
else:
return "Please attempt to guide an appointment into working hours, which is 10 AM to 2 PM at saturday."
else:
if provided_time >= limit1 and provided_time <= limit2:
id = get_all_booked_appointment(arguments)
if id == "Please choose legitimate occasion quantity" or id == "No registered occasion discovered with this e-mail ID." or id == "We face an error whereas processing your request. Please strive once more.":
return id
else:
url = f"https://relaxation.gohighlevel.com/v1/appointments/{id}"
payload = {
"selectedTimezone": "Asia/Calcutta",
"selectedSlot": iso8601_datetime
}
response = requests.request("PUT", url, headers=headers, information=payload)
response = json.masses(response.textual content)
strive:
if response['id']:
return "Appointment up to date efficiently."
besides:
return response['selectedSlot']['message']
else:
return "Please attempt to guide an appointment into working hours, which is 10 AM to 7 PM."
else:
return "Please present all the required data: Present appointment date, New appointment date, time and e-mail ID."
besides:
return "We face an error whereas processing your request. Please strive once more."
Step 17:
Subsequent, we are going to outline a operate for deleting appointments. This operate will first name the ‘get_all_booked_appointments’ operate that we created earlier to fetch the corresponding ID of the appointment. The fetched ID will then be handed to the deletion endpoint of the GHL.
It’s essential add the under traces of code to outline the deletion operate:
def appointment_deletion(arguments):
strive:
id = get_all_booked_appointment(arguments)
if id == "Please choose legitimate occasion quantity" or id == "No registered occasion discovered with this e-mail ID." or id == "We face an error whereas processing your request. Please strive once more.":
return id
else:
url = f"https://relaxation.gohighlevel.com/v1/appointments/{id}"
payload={}
response = requests.request("DELETE", url, headers=headers, information=payload)
if response.textual content == "OK":
return "Appointment deleted efficiently."
besides:
return "We face an error whereas processing your request. Please strive once more."
Step 18:
Now, we have to outline the operate specs for appointment creation, updation, and deletion. These operate specs shall be handed to ChatGPT, enabling it to find out which operate to invoke primarily based on the person’s argument.
capabilities = [
{
"name": "appointment_booking",
"description": "When user want to book appointment, then this function should be called.",
"parameters": {
"type": "object",
"properties": {
"date": {
"type": "string",
"format": "date",
"example":"2023-07-23",
"description": "Date, when the user wants to book an appointment. The date must be in the format of YYYY-MM-DD.",
},
"time": {
"type": "string",
"example": "20:12:45",
"description": "time, on which user wants to book an appointment on a specified date. Time must be in %H:%M:%S format.",
},
"email_address": {
"type": "string",
"description": "email_address of the user gives for identification.",
},
"phone_number":{
"type" : "string",
"description": "Phone number given by user for identification."
}
},
"required": ["date","time","email_address","phone_number"],
},
},
{
"identify": "appointment_updation",
"description": "When person wish to reschedule appointment, then this operate ought to be referred to as.",
"parameters": {
"sort": "object",
"properties": {
"to_date": {
"sort": "string",
"format": "date",
"instance":"2023-07-23",
"description": "It's the date on which the person desires to reschedule the appointment. The date should be within the format of YYYY-MM-DD.",
},
"date": {
"sort": "string",
"format": "date",
"instance":"2023-07-23",
"description": "It's the date from which the person desires to reschedule his/her appointment. The date should be within the format of YYYY-MM-DD.",
},
"time": {
"sort": "string",
"instance":"4:00:00",
"description": "It's the time on which the person desires to reschedule an appointment. Time should be in %H:%M:%S format.",
},
"email_address": {
"sort": "string",
"description": "email_address of the person offers for identification.",
}
},
"required": ["date","to_date","time","email_address"],
},
},
{
"identify": "appointment_deletion",
"description": "When person wish to delete appointment, then this operate ought to be referred to as.",
"parameters": {
"sort": "object",
"properties": {
"date": {
"sort": "string",
"format": "date",
"instance":"2023-07-23",
"description": "Date, on which person has an appointment and desires to delete it. The date should be within the format of YYYY-MM-DD.",
},
"email_address": {
"sort": "string",
"description": "email_address of the person offers for identification.",
}
},
"required": ["date","email_address"],
},
}]
Step 19:
Now, we’re prepared to check the appointment reserving chatbot. You simply want so as to add the next traces of code to run the chatbot.
day_list = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
messages = [{"role": "system", "content": f"""You are an expert in booking appointments, who can fulfill appointment scheduling, rescheduling, and deletion very efficiently. You need to remember the below guidelines while processing user requests.
Guidelines:
- You will ask for the appointment date and time, phone number, and email address, when the user wants to book an appointment.
- When the user wants to reschedule an appointment, then you will ask for the current appointment date, new date and time for the appointment, and email address. If the user didn't remember the current appointment details then inform the user that rescheduling will not be possible without these details.
- You will ask email address every time, as it is a must for user identification.
- Don't make assumptions about what values to plug into functions, if the user does not provide any of the required parameters then you must need to ask for clarification.
- If a user request is ambiguous, you also need to ask for clarification.
- If a user didn't specify "ante meridiem (AM)" or "post meridiem (PM)" while providing the time, then you must have to ask for clarification. If the user didn't provide day, month, and year while giving the time then you must have to ask for clarification.
You must need to satisfy the above guidelines while processing the request. You need to remember that today's date is {date.today()}."""}]
user_input = enter("Please enter your query right here: (if you wish to exit then write 'exit' or 'bye'.) ")
whereas user_input.strip().decrease() != "exit" and user_input.strip().decrease() != "bye":
messages.append({"function": "person", "content material": user_input})
# calling chat_completion_request to name ChatGPT completion endpoint
chat_response = chat_completion_request(
messages, capabilities=capabilities
)
# fetch response of ChatGPT and name the operate
assistant_message = chat_response.json()["choices"][0]["message"]
if assistant_message['content']:
print("Response is: ", assistant_message['content'])
messages.append({"function": "assistant", "content material": assistant_message['content']})
else:
fn_name = assistant_message["function_call"]["name"]
arguments = assistant_message["function_call"]["arguments"]
operate = locals()[fn_name]
outcome = operate(arguments)
print("Response is: ", outcome)
user_input = enter("Please enter your query right here: ")
Testing
Appointment Reserving
You possibly can see the booked appointments by clicking on the “Calendars” possibility, beneath the primary menu as proven under:
Appointment Updation:
Appointment Deletion:
On this weblog, we explored the method of making an appointment reserving chatbot utilizing OpenAI’s operate calling characteristic. We realized find out how to combine the GoHighLevel calendar API, permitting our chatbot to seamlessly work together with the calendar system. This integration allows customers to guide appointments effortlessly by conversing with the chatbot.