I'm currently using a basic AI agent chat integrated into my WordPress site. Both my WordPress installation and my callin.io instance are hosted on Hostinger, but on separate servers. My callin.io instance is self-hosted using Docker Compose on a VPS with Nginx. This is my first experience with callin.io, JSON, or managing a VPS, so I'm definitely a beginner.
```nginx
server {
listen 80;
listen [::]:80;
servername n8n.xtreamsolution.net;
return 301 https://$host$request uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name n8n.xtreamsolution.net;
ssl_certificate /etc/letsencrypt/live/n8n.xtreamsolution.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/n8n.xtreamsolution.net/privkey.pem;
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_cache_bypass $http_upgrade;
chunked_transfer_encoding off;
}
location /webhook {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://xtreamsolution.net';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type';
add_header 'Access-Control-Max-Age' 86400;
return 204;
}
# Removing the duplicate header here, letting the if block handle it
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
```
I'm encountering an issue where my webhook endpoint successfully receives a request and returns a 200 OK
status, but the response body is empty. This causes my frontend to display:
“Empty response from server.”
Workflow Setup:
- I'm utilizing a Chat Trigger node that forwards user input to an AI Agent node.
- The AI Agent is configured with a System Message to enforce JSON output (e.g.,
{ "response": "Hello" }
). - A Respond to Webhook node is placed at the conclusion of the workflow.
- Respond to Webhook → Respond With: JSON
- Response Body:
json
{{ { "output": $json.response || "No AI response" } }}
What I Have Tried:
-
Confirmed that the webhook URL is being invoked correctly via the browser console:
bash
POST https://n8n.xtreamsolution.net/webhook/f406671e-c954-4691-b39a-66c90aa2f103/chat
Status: 200 OK
-
Experimented with a Function node returning static JSON:
javascript
return [{ json: { response: "Test response from n8n" } }];
Even with this, my frontend still logsBot: Empty response from server.
. - Reviewed CORS settings;
Access-Control-Allow-Origin
is correctly set to my domain (https://xtreamsolution.net
). - Verified that the AI Agent node is producing output, but the final Respond to Webhook node consistently returns empty.
- Attempted to bypass the Output Parser and directly feed JSON to the Respond to Webhook node, but the issue persists.
Additional Notes:
-
Frontend fetch request details:
javascript
const response = await fetch('https://n8n.xtreamsolution.net/webhook/f406671e-c954-4691-b39a-66c90aa2f103/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message })
});
const data = await response.json();
console.log(data);
-
The console output shows:
sql
Bot: Empty response from server.
my version Version 1.102.3
Hello! Welcome to the community.
Try this JSON for your Respond to Webhook node:
{"output": {{ $json.output.toJsonString() || "No AI response" }} }