I asked GPT-4 to build a Shopify app. In an hour. And it did.

Ralf Elfving
7 min readMar 19, 2023

--

“You’re a helpful Shopify app developer assistant, helping to code Shopify apps.”

That’s what I told GPT-4 before I copy/pasted an entire Shopify app tutorial from Gadget.dev into the prompt, and appended my question:

“What other kind of Shopify app tutorials do you think you could build with Gadget using the example tutorial above? Give five reasonable Shopify app projects you think we could complete together in less than an hour.”

About an hour later, I had a complete Shopify app that updated a newly created customer segmentation metafield based on custom spending tiers whenever customers places an order. Pretty neat, considering I spent 25 minutes of said hour debugging code.

If you for whatever reason want to watch a novice JS developer build a Shopify app with GPT-4, here’s the video of my experience (don’t worry, I fast-forward over sections with no action).

If you just want to build the app, follow the high level steps below.

Building the Shopify app

I want to spend most of my time building more stuff with GPT-4, not writing this. So to save me some time, and give you the best possible explanation of how to build this app — follow this 10-minute tutorial of how to build a Shopify app with Gadget.dev. It will all be worth it, because we’ll just bolt the rest on to it. Oh, make sure to follow the Shopify Partner version of the tutorial!

Ok, you’re done? Let’s take what you already have and extend it with what GPT-4 and I built.

  • Go to your Gadget app. On the Shopify Connection’s page in Gadget, select the edit icon in “SHOPIFY API SETTINGS”.
  • Select read/write access for the Shopify Customer models, and click “confirm” at the bottom.
  • Go to the Shopify partners dashboard, open your app’s page, select the “App setup” option in the left-hand nav, and scroll down to the “Protected customer data access”. Click “Request access”
  • Click all checkboxes in there. Yes. All of them. If you intent to install this app on a real store, read this message from Shopify first. It’s important.
  • Go back to the “Overview” page for the app in the Partner Dashboard, and re-install your Shopify app on the store just as you did when you installed it the first time.
  • Grant the new permissions in the OAuth flow. Your have successfully updated your Shopify app to access customer data. YAY!
  • In Gadget, go to your connection and sync data to download the customer records (oh.. if you don’t already have any customers, create one in Shopify by going to the customer section, and click “Add customer”)

Adding the secret sauce

Ok. Take a breather. Next we’re adding the ingredients that differentiates this app from your product tagger app. There’s three components

  1. A custom customerSegment model (like the allowedTag model)
  2. A customer_segment metafield to store the data (I really regret not camel casing it)
  3. A JS code file that contain all the logic

The customerSegment model

I’m going to save myself some typing here, and let GPT-4 explain what you’re supposed to do.

Here are the steps to create the `customerSegment` custom model with the necessary fields:

1. Create the CustomerSegment model:
— In your Gadget app, click on the “Add a Model” button.
— Name the model “CustomerSegment” and set the API identifier to “customerSegment”.
— Click on “Create Model” to create the model.

2. Add fields to the CustomerSegment model:
— Click on the “Add a Field” button to create a new field for the model.

a. Add the “segmentName” field:
— Field name: “segmentName”
— API identifier: “segmentName”
— Field type: “String”
— Check the “Required” box to make this field mandatory.

b. Add the “threshold” field:
— Field name: “threshold”
— API identifier: “threshold”
— Field type: “Float” (note: Gadget calls this “number”)
— Check the “Required” box to make this field mandatory.

c. Add the “segmentValue” field:
— Field name: “segmentValue”
— API identifier: “segmentValue”
— Field type: “String”
— Check the “Required” box to make this field mandatory.

With the model and fields created, you can add records to the CustomerSegment model using Gadget’s API Playground or Data UI. Make sure to populate the records with appropriate segment names and threshold values based on your segmentation criteria.

Click on the “create” action for the new model, and then click “Create action”. This will open the API playground with a default create mutation. All you have to do is to add the values for each record you want to create into the variable input field at the bottom left.

Here’s something to get you started, you can change the values (not the fields!) to what makes sense to you.

{
"customerSegment": {"segmentname": "Up to 50", "segmentvalue": "Low spender", "threshold": 50}
}

The segmentname is only used in Gadget, the segmentvalue is what will be added to the metafield in Shopify, and the threshold value is how much a customer needs to spend to get the segment value applied to their customer profile. A customer will keep that segmentvalue in the metafield until they spend enough to hit the next threshold above it. So maybe start with 50, 100, 150 to test things out.

Creating the metafield

Head back into your Shopify store’s admin. Go to settings, select “Custom data”, and select “Customer”. Then click “add definition”.

Name your metafield exactly customer_segment, name the namespace custom, give it an optional description, and select the type “Single line text”. That was easy. Next up is Gadget.

Go to your Shopify Customer model. Add a new field. Name it customer_segment. Click the checkbox next to “Store data from Shopify Metafield” (not sure why this is capitalized, but I digress). Name the namespace field custom, and name the key field customer_segment, and then click “Register namespace”. Give it 5 seconds… or really, until it says it’s done.

Then you’re done. Your Gadget app can now read and write your newly created metafield. Look at you, developing Shopify apps. F**k yeah!

Adding the code file

Last but not least, the code file. A single file of 49 lines of code that handles all of our logic. Well. Everything that Gadget doesn’t already handle behind the scenes.

Go to the Shopify Customer model in Gadget. Click the Create action, then click “Run code file” under “SUCCESS EFFECTS”. Copy/paste the code file below to replace the default code in the newly created code file.

module.exports = async ({ api, record, params, logger, connections }) => {
if (record.id && record.totalSpent && record.changed("totalSpent")) {
// Fetch customer segments from the CustomerSegment model
const customerSegments = await api.customerSegment.findMany();

// Find the highest segment for the customer based on their total spent
const highestSegment = customerSegments
.filter((segment) => Number(record.totalSpent) >= segment.threshold)
.reduce((prev, curr) =>
prev.threshold > curr.threshold ? prev : curr,
{ threshold: 0 }
);

// If there's a matching segment and segmentValue is not null, update the customer's metafield with the segment value
if (highestSegment && highestSegment.segmentValue !== null) {
logger.info(
{ highestSegment },
`applying highest segment to customer ${record.id}`
);


// Write the highest segment value back as a metafield to the customer
const shopify = await connections.shopify.current;
if (shopify) {
await shopify.graphql(
`mutation updateCustomerSegmentMetafield($metafields: [MetafieldsSetInput!]!) {
metafieldsSet(metafields: $metafields) {
metafields {
id
value
}
}
}`,
{
metafields: [
{
key: "customer_segment",
namespace: "custom",
ownerId: `gid://shopify/Customer/${record.id}`,
type: "single_line_text_field",
value: highestSegment.segmentvalue,
},
],
}
);
}
}
}
};

Then go to the Update action, and do the same, but click the little round (x) and replace the file the field points to to use shopifyCustomer/create/onCreate.js. This code will now run whenever a customer gets created, or updated.

A side note. By using record.changed(“totalSpent”) in the first if-statement, we’re avoiding to run this code file if something about the customer has changed, but not the totalSpent field. If that doesn’t change, we don’t need to update the customer segmentation metafield, right? This also ensures we don’t get stuck in an infinite loop of updating the customer object, and reacting to the webhook echo. Nifty.

Enjoy the fruits of your labour

That’s it. The hard work is over. Create an order in Shopify, and make the total value of the customer higher than the lowest threshold value in your custom model.

Before you spend 10 minutes debugging why the code isn’t working, note that placing test orders in checkout does not count towards customer.totalSpent. Instead create draft orders in Shopify admin and mark them as paid, it’ll work.

A few last notes

I hope this is useful to you. I at least enjoyed making the video (not so much typing this up, waiting for GPT to summarize videos I suppose).

You can extend this app’s logic to be a lot more complicated by adding more fields to the custom model, and more code to the code file.

At the end of the day, this experiment was meant to test if GPT-4 could build a Shopify app with a tutorial as input. In an hour. And it could (with some help). Hope you keep pushing its limits!

If you have any questions, please reach out to me on Twitter @ralfelfving. And if you want to learn more about Gadget.dev, just go to… well… www.gadget.dev.

--

--