Help: Telegram + Supabase + AI Agent fallback workflow

Hello,

I’m working on a Telegram bot project using n8n + Supabase.

Goal:

  1. Receive a message from Telegram (Telegram Trigger).
  2. Search in the bot_responses table in Supabase.
  3. If there is a matching row → reply directly with the stored answer.
  4. If no match is found → forward the message to an AI Agent (OpenRouter / LLM) and send that reply.

Problem:

  • The HTTP Request node successfully returns data from Supabase.
  • However, when I send a message that does not exist in the database, the If/Code Node does not recognize the empty result.
  • As a result, the bot either responds incorrectly or always assumes there is an answer, even if the array is empty.

What I need:

  • Help configuring the condition (If or Code Node) so that:
    • If Supabase returns an array with data → reply with the DB answer.
    • If Supabase returns an empty array → route to the AI Agent.

Environment:

  • n8n self-hosted (on a VPS).
  • Supabase Postgres (tables: bot_responses, products).
  • Telegram Bot connected to the workflow.

:backhand_index_pointing_right: I’d appreciate any help with the correct query/condition or a working workflow JSON example that implements this fallback logic.

Thanks!
— Fahad

@fahad1 welcome to the community friend

Your query is a classic “empty array detection” problem. It’s a common issue when working with database responses. Do you know exactly how to set up the condition properly.

Hey @fahad1,

You’re on the right track :+1: Supabase always returns an array, even when it’s empty : so checking for null or undefined won’t work. The trick is to check the length of the array.

A couple of easy ways to handle this in n8n:

:small_blue_diamond: Option 1 : If Node
In the If node, set the condition like this:

{{ $json["data"].length }}

  • “Greater than” → 0 → means you found a row, use the DB answer.

  • “Equal to” → 0 → means no match, route to your AI Agent.

:small_blue_diamond: Option 2 : Code Node
If you want more control, drop in a Code node after Supabase:

const results = $json.data || [];

if (results.length > 0) {
  // Found a DB match → keep the answer
  return [{ json: { answer: results[0].answer } }];
} else {
  // Nothing found → flag it for AI
  return [{ json: { fallback: true } }];
}

Then you can add an If node that checks for fallback === true and branch to your AI Agent.

That way, the workflow cleanly splits between “DB answer” and “AI answer.”

Thanks again for the suggestions :folded_hands:

I’ve tried all the approaches mentioned (If node with $json.length, checking $json.data.length, and also using a Code node to detect results.length > 0).

The behavior is still the same:

  • When the message matches a row in Supabase → it replies correctly from the DB.
  • When the message does not match any row → instead of going to the AI Agent, the workflow still routes through the Supabase branch (empty array case).

So the “empty array detection” logic is not working for me. I always end up stuck in the DB branch, even though the HTTP Request clearly returns an empty array ([]).

It feels like I’m missing the exact n8n condition setup to properly branch on “array empty vs array with rows”.

Do you maybe have a working If node expression or an example workflow JSON that implements this fallback logic? That would help a lot

1 Like

Hey @fahad1, welcome back :waving_hand:

You’re right, the key is to check the length of the array inside the If node. Here’s the exact expression that works:

{{ $json["data"] && $json["data"].length > 0 }}

Set the If node like this:

  • Condition type: Expression

  • Value 1:

{{ $json["data"] && $json["data"].length > 0 }}

  • Operator: Equal

  • Value 2: true

That way:

  • If Supabase returns rows → goes “true” branch (DB answer).

  • If Supabase returns [] → goes “false” branch (AI Agent).

:white_check_mark: Mini workflow example:

Import this, replace Supabase + Telegram settings, and it will branch correctly.

If this helps, please mark it as Solution so others can find it :folded_hands:

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.