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.
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.