Skip to content

Instantly share code, notes, and snippets.

@verygoodplugins
Last active July 29, 2024 04:37
Show Gist options
  • Save verygoodplugins/532520c15c8ef139105cc283178ec9f5 to your computer and use it in GitHub Desktop.
Save verygoodplugins/532520c15c8ef139105cc283178ec9f5 to your computer and use it in GitHub Desktop.
Python script for querying the WooCommerce REST API using ChatGPT
import openai
import requests
import re
import json
openai.api_key = "X"
# Define WooCommerce credentials.
site_url = "https://yoursite.com/"
woocommerce_key = "Y"
woocommerce_secret = "Z"
def generate_text(messages, model, max_tokens=150, temperature=0.7):
response = openai.ChatCompletion.create(
model=model,
messages=messages,
max_tokens=max_tokens,
n=1,
temperature=temperature,
top_p=1
)
return response.choices[0].message['content'].strip()
# We want a smaller response object so we don't run out of tokens
def clean_response( response ):
keys_to_keep = ["name", "permalink", "featured", "description", "short_description", "sku", "price", "regular_price", "sale_price", "on_sale", "purchasable", "weight", "dimensions", "average_rating", "rating_count", "categories", "tags", "attributes", "variations" ]
for item in response:
keys_to_delete = []
for key, value in item.items():
if key not in keys_to_keep or not value:
keys_to_delete.append(key)
for key in keys_to_delete:
del item[key]
return response
def main():
print("I'm the WooCommerce assistant! One moment please while I get ready...")
## Get the attributes
r = requests.get(site_url + "/wp-json/wc/v3/products/attributes", auth=(woocommerce_key, woocommerce_secret))
if r.status_code != 200:
print("Error: Failed to validate credentials")
return
# Attributes retrieved successfully, let's iterate through them and extract the slug and name properties
attributes = r.json()
attribute_list = []
for attribute in attributes:
attribute_dict = {}
attribute_dict["name"] = attribute["name"]
attribute_dict["slug"] = attribute["slug"]
attribute_dict["terms"] = []
r = requests.get(site_url + "/wp-json/wc/v3/products/attributes/" + str( attribute["id"] ) + "/terms/", auth=(woocommerce_key, woocommerce_secret))
terms = r.json()
for term in terms:
term_dict = {}
term_dict["name"] = term["name"]
term_dict["id"] = term["id"]
attribute_dict["terms"].append(term_dict)
attribute_list.append(attribute_dict)
# Now we have a list of dictionaries, each containing the name and id of an attribute.
print( " == Retrieved attributes: == " )
print(attribute_list)
# Next get the categories
r = requests.get(site_url + "/wp-json/wc/v3/products/categories", auth=(woocommerce_key, woocommerce_secret))
# Categories retrieved successfully, let's iterate through them and extract the id and name properties
categories = r.json()
category_list = []
for category in categories:
category_dict = {}
category_dict["name"] = category["name"]
category_dict["id"] = category["id"]
category_list.append(category_dict)
print( " == Retrieved categories: == " )
print(category_list)
# Next get the tags
r = requests.get(site_url + "/wp-json/wc/v3/products/tags", auth=(woocommerce_key, woocommerce_secret))
tags = r.json()
tag_list = []
for tag in tags:
tag_dict = {}
tag_dict["name"] = tag["name"]
tag_dict["id"] = tag["id"]
tag_list.append(tag_dict)
print( " == Retrieved tags: == " )
print(tag_list)
print( "\n\nOk! I'm ready! What can I help you with today?" )
messages = [
{
'role' : 'system',
'content': f"""You are an friendly AI sales assistant connected to a WooCommerce store. It is your job to help answer customer questions.
The customer is about to tell you what they are looking for. If the reply does not sound like it's related to shopping,
you should say "I'm sorry, I'm only trained to help customers locate products in this store. What can I help you find today?".
Once the customer indicates the product they are looking for, you should create a REST API query for WooCommerce.
These are the rules for the query:
1. Only use the minimum number of parameters required to locate the product. Do not make up URL parameters.
2. When searching, the category should take priority over the attribute.
3. Do not use the same parameter twice in the same request URI (for example, &attribute_term=158&attribute_term=138 is incorrect)
4. Do not search by `attribute` or `category` unless it specifically relates to the customer's request.
5. The `attribute` parameter only uses a slug. If the slug is not known, do not use the parameter.
6. The `category` and `attribute_term` parameters should only use IDs. If the ID is not known, do not use the parameter.
When replying with the query URL, always use the format 'GET:{{query}}'.
If the customer asks for a discount, you can give them the code "10PERCENT".
When talking to the customer, never make up a product name or a URL. Only use the information you have been given.
To help you better understand the store, here are some important details:
Store URL: {site_url}
Categories: {json.dumps( category_list )}
Tags: {json.dumps( tag_list )}
Attributes: {json.dumps( attribute_list )}
Customer's input:"""
}
]
while True:
user_input = input("\nYou: ")
if user_input.lower() == "exit":
print("Assistant: Goodbye!")
break
messages.append({'role': 'user', 'content': user_input})
response_text = generate_text(messages, "gpt-3.5-turbo")
messages.append({'role': 'assistant', 'content': response_text})
if "GET:" in response_text:
url_pattern = r"(?P<url>https?://[^\s]+)"
url_match = re.search(url_pattern, response_text)
url = url_match.group("url")
print( " === REST REQUEST TO:", url )
r = requests.get( url, auth=(woocommerce_key, woocommerce_secret) )
result = clean_response( r.json() )
if not result:
# No results. Try and search all products.
url = site_url + "wp-json/wc/v3/products/?per_page=5";
print( " === No results. Trying again with REST REQUEST TO:", url )
r = requests.get( url, auth=(woocommerce_key, woocommerce_secret) )
result = clean_response( r.json() )
messages.append(
{
'role' : 'system',
'content': f"""You have performed a search but unfortunately no matching results have been returned. You should apologize to the customer, and
ask them if they are interested in any of the other products included in the results below. Behave like a friendly sales assistant.
If the customer is interested in any of the products, you should reply with the URL to the product page.
Results: {json.dumps( result )}"""
}
)
else:
messages.append(
{
'role' : 'system',
'content': f"""You have performed a search over the API and the following results have been returned. Describe the results to the customer in a conversation and
friendly tone, like a sales assistant would.
You may also ask the customer if they would like to purchase the product. If they say yes, you should reply with the URL to the product page.
If the customer requests information about additional products, make another request over the API. Do not make up information about products or links.
Results: {json.dumps( result )}"""
}
)
response_text = generate_text(messages, "gpt-3.5-turbo")
messages.append({'role': 'assistant', 'content': response_text})
print("\nAssistant:", response_text)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment