# How to Build an **ai upsell during customer support** System

> Source: <https://dev.to/samchenreviews/how-to-build-an-ai-upsell-during-customer-support-system-2lcc>
> Published: 2026-08-29 16:35:46+00:00

You can turn every live chat or ticket into a revenue opportunity by wiring a generative-AI model into your support platform, letting it suggest the next best product in real time. The result is a fully automated "AI upsell during customer support" flow that surfaces a personalized offer, sends the customer a checkout link, and logs the conversion back into your CRM - all without the agent having to type a single line.

Below is a step-by-step, production-ready guide that uses **Intercom** or **Zendesk** for the support channel, **OpenAI** for the language model, **n8n** as the glue, and **Shopify** (or any Shopify-compatible store) as the fulfillment engine. If you already have a CRM (HubSpot, Salesforce, etc.) you'll see where to plug it in.

| Tool | Plan / Price | Role |
|---|---|---|
| Intercom (or Zendesk) | Intercom "Essential" - check the provider's current pricing; Zendesk "Support Team" - check the provider's current pricing | Customer-support front-end (chat & ticketing) |
| OpenAI API | Pay-as-you-go; first $18 free credit for new accounts - see the OpenAI pricing page | Generates the upsell suggestion |
| n8n (self-hosted Docker) |
Free (Community Edition) - run `docker run -p 5678:5678 n8nio/n8n`
|
Orchestrates webhook → LLM → Shopify |
| Shopify (Basic) | $39/mo (store + API access) - see Shopify pricing page | Holds product catalog and creates checkout links |
| CRM (HubSpot, Salesforce, etc.) | Free tier available; paid tiers for advanced automation - check the provider's current pricing | Records the upsell event and enriches the contact record |
| HTTPS endpoint (e.g., ngrok) | Free tier for dev; paid for production - check ngrok pricing | Exposes n8n webhook to Intercom/Zendesk |

**Estimated build time:** 6-8 hours for a developer familiar with REST APIs and basic workflow tooling.

Both Intercom and Zendesk can push a payload whenever a conversation is updated.

**Intercom**: In the Intercom UI go to **Settings → App → Webhooks** and create a new webhook. Set the **Event** to `conversation.user.replied`

and point it at `https://your-n8n-host.com/webhook/ai-upsell`

. Leave the default "Send full payload".

**Zendesk**: Navigate to **Admin → Extensions → Target URLs** → **Add target**. Choose *HTTP Target*, give it a name like `AI Upsell`

, paste the same n8n URL, and select *POST JSON*. Then create a **Trigger** under **Admin → Business Rules → Triggers**: when *Ticket is Updated* AND *Assignee is not empty*, fire the target.

"A webhook that fires on every reply guarantees you never miss an upsell opportunity."

Make sure the endpoint is reachable from the internet. For local testing you can spin up `ngrok http 5678`

and copy the generated https URL into the webhook config.

```
docker run -d \
 --name n8n \
 -p 5678:5678 \
 -e N8N_BASIC_AUTH_ACTIVE=true \
 -e N8N_BASIC_AUTH_USER=admin \
 -e N8N_BASIC_AUTH_PASSWORD=changeme123 \
 n8nio/n8n
```

`changeme123`

with a strong password.`https://your-host:5678`

in a browser, log in, and you're ready to build the workflow.**Webhook node** - set *HTTP Method* to `POST`

, *Path* to `/webhook/ai-upsell`

. This is the entry point that receives the conversation payload.

**Set node (Extract relevant data)** - map the incoming JSON to a clean object:

`customerId`

→ `{{ $json["user"]["id"] }}`

(Intercom) or `{{ $json["ticket"]["requester_id"] }}`

(Zendesk)`latestMessage`

→ `{{ $json["conversation"]["conversation_message"]["body"] }}`

(Intercom) or `{{ $json["ticket"]["description"] }}`

(Zendesk)`email`

→ `{{ $json["user"]["email"] }}`

or `{{ $json["ticket"]["requester"]["email"] }}`

**HTTP Request node (OpenAI Completion)** - configure as follows:

```
{
 "url": "https://api.openai.com/v1/chat/completions",
 "method": "POST",
 "headers": {
 "Content-Type": "application/json",
 "Authorization": "Bearer {{ $env.OPENAI_API_KEY }}"
 },
 "body": {
 "model": "gpt-4o-mini",
 "messages": [
 {
 "role": "system",
 "content": "You are a sales assistant for an e-commerce store. Suggest one relevant product upgrade based on the customer's last message. Keep the tone friendly and concise (max 50 words). Return only JSON: {\"product_id\":\"...\",\"reason\":\"...\"}."
 },
 {
 "role": "user",
 "content": "{{ $json[\"latestMessage\"] }}"
 }
 ],
 "temperature": 0.3,
 "max_tokens": 150
 }
}
```

`product_id`

and a brief `reason`

.

```
items[0].json = JSON.parse($json["choices"][0]["message"]["content"]);
return items;
```

`item.json.product_id`

and `item.json.reason`

.

```
{
 "url": "https://{{ $env.SHOPIFY_STORE }}/api/2023-10/checkouts.json",
 "method": "POST",
 "authentication": "basicAuth",
 "user": "{{ $env.SHOPIFY_API_KEY }}",
 "password": "{{ $env.SHOPIFY_PASSWORD }}",
 "body": {
 "checkout": {
 "line_items": [
 {
 "variant_id": "{{ $json[\"product_id\"] }}",
 "quantity": 1
 }
 ],
 "email": "{{ $json[\"email\"] }}"
 }
 }
}
```

`checkout_url`

that the customer can click to complete the upsell purchase.

```
{{ $json["latestMessage"].toLowerCase().includes("upgrade") || $json["latestMessage"].toLowerCase().includes("extra") }}
```

`https://api.intercom.io/messages`

with the `Authorization: Bearer <INTERCOM_TOKEN>`

header and a body:

```
 {
 "message_type": "inapp",
 "body": "Hey! Based on what you said, I think you'll love our {{ $json[\"reason\"] }}. 👉 {{ $json[\"checkout_url\"] }}",
 "from": { "type": "admin", "id": "<ADMIN_ID>" },
 "to": { "type": "user", "id": "{{ $json[\"customerId\"] }}" }
 }
```

`https://yourdomain.zendesk.com/api/v2/tickets.json`

with a body that adds a public comment containing the upsell line.**CRM Update (optional)** - add a **HTTP Request** node pointing at your CRM's "Create Deal" endpoint. Include `customerId`

, `product_id`

, and a flag `upsell_generated: true`

.

**Save & Activate** - turn the workflow on. Test by sending a fake message through Intercom/Zendesk that contains "I want something bigger". You should see the AI suggest a product, n8n hit Shopify, and the support UI reply with a checkout link.

Create an `.env`

file in the n8n Docker container (or set environment variables in your host) with:

```
OPENAI_API_KEY=sk-...
INTERCOM_TOKEN=...
SHOPIFY_STORE=yourstore.myshopify.com
SHOPIFY_API_KEY=...
SHOPIFY_PASSWORD=...
```

Restart the container so n8n picks up the new vars:

```
docker restart n8n
```

`docker run -e LOGGING_PROVIDER=papertrail ...`

flag.

"The weakest link is always the webhook latency; a 5-second delay can make the suggestion feel out-of-sync."

| Failure point | Symptom | Fix |
|---|---|---|
Webhook auth mismatch |
Intercom/Zendesk reports "401 Unauthorized" | Verify the token values in your `.env` and that the header name matches the platform's docs (`Authorization: Bearer ...` for Intercom, `Authorization: Basic ...` for Zendesk). |
OpenAI rate limits |
HTTP 429 response from `api.openai.com`
|
Upgrade to a higher quota or implement exponential back-off. Cache recent `product_id` suggestions for identical messages to reduce calls. |
Shopify checkout API version deprecation |
404 on `/api/2023-10/checkouts.json`
|
Pin the API version in the URL (`/api/2024-01/...` ) and monitor Shopify's deprecation schedule. |
n8n execution timeout (default 30 s) |
Workflow stops before the checkout link is created | Increase the timeout under Settings → Workflow or split the flow into two webhooks (one for AI, one for Shopify). |
Eligibility filter too strict |
No upsell ever sent even when relevant | Tune the keyword list or switch to a small text-classification model (e.g., OpenAI's `text-classification` endpoint) to detect intent more reliably. |
Cost runaway |
Monthly OpenAI bill spikes | Add a per-day quota node that caps the number of completions (e.g., 500 calls/day). Track usage with n8n's built-in "Workflow Execution" metrics. |

For a deeper technical reference, see [n8n's documentation](https://docs.n8n.io/).

The system prompt tells the model to "pick the most relevant product from our catalog". You can make it smarter by passing a *few-shot* example list of product IDs and descriptions in the prompt, or by enriching the prompt with the customer's purchase history fetched from your CRM before the OpenAI call.

Yes. Replace the Shopify checkout node with the equivalent API call for WooCommerce, BigCommerce, or a custom cart service. The only requirement is that the endpoint returns a URL that you can embed in the support reply.

Treat the conversation as a new event. The webhook fires again, the AI receives the latest message, and the eligibility filter decides whether to propose another upsell. You can also add a flag in the CRM (`last_upsell_timestamp`

) to enforce a minimum gap (e.g., 48 hours) between suggestions.

Shopify's checkout URLs are single-use and tied to the email you pass in the payload, so they can't be hijacked easily. Nevertheless, enable HTTPS everywhere and never expose your API keys in the front-end. All secret handling stays inside n8n.

Not for most small-to-medium stores. The `gpt-4o-mini`

model with a well-crafted system prompt yields accurate suggestions for a catalog of up to a few thousand SKUs. If you have >10 k products, consider adding a lookup step that selects the top-10 candidates by tag before sending the list to the LLM.

Check out the ** AI automations you can sell** page for a catalog of plug-and-play workflows, or grab

By wiring together a support platform, OpenAI, n8n, and Shopify you get a scalable **ai upsell during customer support** engine that works on every ticket, respects the agent's workflow, and captures the extra revenue in your CRM. The pieces are all real-world products with documented APIs, so you can replicate the flow today, iterate on the prompts, and watch your average order value climb. Happy building.
