Support ticket for every negative review with n8n

An n8n workflow that reads the event log every 5 minutes and opens a ticket for every review or private feedback of 2 stars or fewer.

API documentationNo-code recipes · Tickets with n8n

What you get

Every 5 minutes, n8n reads the account's new events from where it stopped, keeps the reviews and private feedback of 2 stars or fewer, and opens a ticket in your support tool, with the rating, the text and the author. Your team handles unhappy customers like any other customer request.

The workflow polls the event log (GET /v1/events) instead of receiving webhooks: it needs no public address, also works with an n8n installed behind a firewall, and has no signature to verify since it calls the API itself. There is no Ma Belle Note node in n8n: the workflow uses the generic Schedule Trigger, Code and HTTP Request nodes. The labels quoted are those of n8n's English interface.

What you need

  • n8n, on n8n Cloud or self-hosted.
  • An API key with the events:read scope, created with the Custom template.
  • The n8n node of your support tool (n8n offers some for Zendesk, Freshdesk and Jira, among others), or an email node.

1. Store the key in n8n

Create a credential of type Header Auth:

  • Name: Authorization.
  • Value: Bearer followed by your key, for instance Bearer mbn_live_....

The key thus stays encrypted in n8n's credentials, not in plain text in the workflow.

2. Trigger the workflow every 5 minutes

Add a Schedule Trigger node, with a 5-minute interval.

3. Resume where the workflow stopped

Add a Code node, in JavaScript, named Read position:

const state = $getWorkflowStaticData("global");
state.startedAt ??= new Date().toISOString();
const query = new URLSearchParams({ types: "review.created,feedback.created", limit: "100" });
if (state.after) query.set("after", state.after);
return [{ json: { url: `https://api.mabellenote.com/v1/events?${query}` } }];

The workflow's static data keeps, from one run to the next, the after read position and the date the workflow was activated.

4. Read the event log

Add an HTTP Request node:

  • Method: GET.
  • URL: the expression {{ $json.url }}.
  • Authentication: Generic Credential Type, then Header Auth, with the credential of step 1.

The response is a page of at most 100 events, oldest first, with the next position in nextCursor.

5. Move the position forward and keep the useful events

Add a second Code node, named Negative events:

const state = $getWorkflowStaticData("global");
const page = $input.first().json;
state.after = page.nextCursor;
return page.data
  .filter((event) => event.createdAt >= state.startedAt)
  .filter((event) => event.data.object.rating <= 2)
  .map((event) => ({ json: event }));

It stores the new position, drops the events older than the workflow's activation and keeps only reviews and feedback of 1 or 2 stars. A review deleted in the meantime, delivered without a rating, is dropped too.

6. Open the ticket

Add the node of your support tool, for instance Create ticket for Zendesk or Freshdesk, and compose the ticket with n8n expressions:

Ticket itemExpression
SubjectReview {{ $json.data.object.rating }}/5 by {{ $json.data.object.author.name }}
Description{{ $json.data.object.comment }}
External reference{{ $json.id }}, the event identifier

The event type, review.created or feedback.created, is in {{ $json.type }} and the related location in {{ $json.establishmentId }}.

7. Activate the workflow

Activate (publish) the workflow. The read position is only stored during runs started by the Schedule Trigger: test runs started by hand begin from the start and do not change it.

When first activated, the workflow catches up on the 30 days of events kept by the log, in pages of 100, without opening a ticket for what came before its activation: depending on your volume, a few runs are enough.

Good to know

  • Resuming after an error: if a node fails, for instance because the support tool does not answer, the run fails and the position does not move. The same page is read again on the next run: use the event identifier as the ticket's external reference so as not to create two.
  • Delay: an event is published a few seconds after the fact it describes, then read on the next run, so at most 5 minutes later.
  • Rate: 288 calls a day, very far from the limit of 120 calls per minute.
  • Personal data: a private feedback contains the contact details the customer left (author.name, author.email). Only send to the support tool what your team needs.
  • Webhooks: for an instant reaction, an n8n Webhook node can receive the deliveries instead of polling, provided it is reachable over HTTPS and verifies the signature on the raw body, as described in the webhooks guide.

Updated on October 25, 2026