AutomationFlowsSlack & Telegram › Bot / Job Queue Worker (telegram + Max)

Bot / Job Queue Worker (telegram + Max)

Bot / Job Queue Worker (Telegram + MAX). Uses postgres, telegram. Scheduled trigger; 15 nodes.

Cron / scheduled trigger★★★★☆ complexity15 nodesPostgresTelegram
Slack & Telegram Trigger: Cron / scheduled Nodes: 15 Complexity: ★★★★☆ Added:

This workflow follows the Postgres → Telegram recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "Bot / Job Queue Worker (Telegram + MAX)",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "seconds",
              "secondsInterval": 30
            }
          ]
        }
      },
      "name": "Cron every 30s",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT * FROM public.claim_jobs('n8n-worker', 10, NULL, 120);"
      },
      "name": "PG claim_jobs()",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.4,
      "position": [
        460,
        300
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "name": "Has jobs?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        680,
        300
      ]
    },
    {
      "parameters": {
        "batchSize": 1,
        "options": {}
      },
      "name": "SplitInBatches",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        900,
        300
      ]
    },
    {
      "parameters": {
        "dataMode": "jsonOutput",
        "values": {
          "string": [
            {
              "name": "worker_id",
              "value": "'n8n-worker'"
            },
            {
              "name": "job_id",
              "value": "={{ $json.id }}"
            },
            {
              "name": "job_type",
              "value": "={{ $json.job_type }}"
            },
            {
              "name": "payload",
              "value": "={{ JSON.stringify($json.payload) }}"
            },
            {
              "name": "queue_name",
              "value": "={{ $json.queue_name }}"
            },
            {
              "name": "phone",
              "value": "={{ $json.payload.phone }}"
            },
            {
              "name": "work_type",
              "value": "={{ $json.payload.work_type }}"
            },
            {
              "name": "city",
              "value": "={{ $json.payload.city }}"
            },
            {
              "name": "name",
              "value": "={{ $json.payload.name }}"
            },
            {
              "name": "lead_id",
              "value": "={{ $json.payload.lead_id }}"
            },
            {
              "name": "step",
              "value": "={{ $json.payload.step }}"
            },
            {
              "name": "channel",
              "value": "={{ $json.payload.channel || 'telegram' }}"
            },
            {
              "name": "text",
              "value": "={{ $json.payload.text }}"
            },
            {
              "name": "user_id",
              "value": "={{ $json.payload.user_id }}"
            }
          ]
        }
      },
      "name": "Set job vars",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3,
      "position": [
        1120,
        300
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "string": [
                  {
                    "value1": "={{ $json.job_type }}",
                    "operation": "contains",
                    "value2": "lead_intent"
                  }
                ]
              }
            },
            {
              "conditions": {
                "string": [
                  {
                    "value1": "={{ $json.job_type }}",
                    "operation": "contains",
                    "value2": "lead_created"
                  }
                ]
              }
            },
            {
              "conditions": {
                "string": [
                  {
                    "value1": "={{ $json.job_type }}",
                    "operation": "contains",
                    "value2": "incoming_message"
                  }
                ]
              }
            },
            {
              "conditions": {
                "string": [
                  {
                    "value1": "={{ $json.job_type }}",
                    "operation": "contains",
                    "value2": "material_order"
                  }
                ]
              }
            }
          ]
        }
      },
      "name": "Switch job type",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3,
      "position": [
        1340,
        300
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "INSERT INTO public.bot_leads (contact_id, service_kind, status, city, source, raw_payload)\nSELECT bc.id, 'lawn_mowing', 'new', '={{ ($json.city || 'omsk').toString().replace(/'/g, \"''\") }}', '={{ ($json.queue_name || '').toString().replace(/'/g, \"''\") }}', '{{ JSON.stringify($json.payload) }}'::jsonb\n  FROM public.bot_contacts bc\n  JOIN public.bot_contact_identities bci ON bci.contact_id = bc.id\n WHERE bci.channel = '={{ ($json.channel || '').toString().replace(/'/g, \"''\") }}' AND bci.external_id = '={{ ($json.user_id || '').toString().replace(/'/g, \"''\") }}'\n LIMIT 1;"
      },
      "name": "PG insert bot_leads",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.4,
      "position": [
        1560,
        180
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "={{$env.TELEGRAM_OWNER_CHAT_ID}}",
        "text": "\ud83d\udd14 \u041d\u043e\u0432\u044b\u0439 \u043b\u0438\u0434!\n\ud83d\udcde {{$json.phone}}\n\ud83c\udfd7 {{$json.work_type}}\n\ud83d\udccd {{$json.city}}\n\ud83d\udc64 {{$json.name || '\u2014'}}",
        "additionalFields": {
          "parse_mode": "HTML"
        }
      },
      "name": "TG notify admin (lead)",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.1,
      "position": [
        1780,
        180
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT bl.*, bc.phone, bc.full_name, bci.external_id as messenger_id, bci.channel\n  FROM public.bot_leads bl\n  JOIN public.bot_contacts bc ON bc.id = bl.contact_id\n  LEFT JOIN public.bot_contact_identities bci ON bci.contact_id = bc.id AND bci.is_blocked = false\n WHERE bl.id = '={{ ($json.lead_id || '').toString().replace(/'/g, \"''\") }}'\n LIMIT 1;"
      },
      "name": "PG fetch lead",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.4,
      "position": [
        1560,
        360
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "msg",
              "value": "\u2705 \u0417\u0430\u043a\u0430\u0437 \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d!\n\ud83c\udfd7 {{$json.service_kind || $json.work_type}}\n\ud83d\udccd {{$json.city}}\n\n\u0421 \u0432\u0430\u043c\u0438 \u0441\u0432\u044f\u0436\u0435\u0442\u0441\u044f \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0434\u043b\u044f \u0443\u0442\u043e\u0447\u043d\u0435\u043d\u0438\u044f \u0434\u0435\u0442\u0430\u043b\u0435\u0439."
            }
          ]
        }
      },
      "name": "Set confirm msg",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3,
      "position": [
        1780,
        360
      ]
    },
    {
      "parameters": {
        "chatId": "={{$env.TELEGRAM_OWNER_CHAT_ID}}",
        "text": "\ud83c\udfaf \u0421\u043e\u0437\u0434\u0430\u043d \u0437\u0430\u043a\u0430\u0437!\n\ud83d\udcde {{$json.phone}}\n\ud83c\udfd7 {{$json.service_kind || $json.work_type}}\n\ud83d\udccd {{$json.city}}\n\ud83c\udd94 {{$json.id}}",
        "additionalFields": {
          "parse_mode": "HTML"
        }
      },
      "name": "TG notify admin (order)",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.1,
      "position": [
        2000,
        360
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "INSERT INTO public.bot_messages (contact_id, lead_id, channel, direction, kind, text, metadata, external_id)\nSELECT bc.id, '={{ ($json.lead_id || '').toString().replace(/'/g, \"''\") }}'::uuid, '={{ ($json.channel || '').toString().replace(/'/g, \"''\") }}', 'inbound', 'text', '={{ ($json.text || '').toString().replace(/'/g, \"''\") }}', '{}'::jsonb, '={{ ($json.user_id || '').toString().replace(/'/g, \"''\") }}'\n  FROM public.bot_contacts bc\n  JOIN public.bot_contact_identities bci ON bci.contact_id = bc.id\n WHERE bci.channel = '={{ ($json.channel || '').toString().replace(/'/g, \"''\") }}' AND bci.external_id = '={{ ($json.user_id || '').toString().replace(/'/g, \"''\") }}'\n LIMIT 1\n ON CONFLICT (channel, direction, external_id) WHERE external_id IS NOT NULL DO NOTHING;"
      },
      "name": "PG archive msg",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.4,
      "position": [
        1560,
        540
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "INSERT INTO public.material_requests (phone, material_kind, grade, quantity, city, address, source, raw_payload)\nVALUES ('={{ ($json.phone || '').toString().replace(/'/g, \"''\") }}', '={{ ($json.payload?.material_kind || 'sand').toString().replace(/'/g, \"''\") }}', '={{ ($json.payload?.grade || '').toString().replace(/'/g, \"''\") }}', '={{ ($json.payload?.quantity || 1).toString().replace(/'/g, \"''\") }}', '={{ ($json.city || 'omsk').toString().replace(/'/g, \"''\") }}', '={{ ($json.payload?.address || '').toString().replace(/'/g, \"''\") }}', 'bot', '{{ JSON.stringify($json.payload) }}'::jsonb);"
      },
      "name": "PG material req",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.4,
      "position": [
        1560,
        720
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "={{$env.TELEGRAM_OWNER_CHAT_ID}}",
        "text": "\ud83e\uddf1 \u0417\u0430\u043a\u0430\u0437 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432!\n\ud83d\udcde {{$json.phone}}\n\ud83c\udfd7 {{$json.payload.material_kind || '\u2014'}}\n\ud83d\udce6 {{$json.payload.quantity || 1}} {{$json.payload.grade || ''}}\n\ud83d\udccd {{$json.city}}",
        "additionalFields": {
          "parse_mode": "HTML"
        }
      },
      "name": "TG notify admin (materials)",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.1,
      "position": [
        1780,
        720
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "UPDATE public.job_queue SET status = 'completed', completed_at = now(), updated_at = now() WHERE id = '={{ ($json.job_id || '').toString().replace(/'/g, \"''\") }}'::uuid;"
      },
      "name": "PG complete job",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.4,
      "position": [
        2000,
        720
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Cron every 30s": {
      "main": [
        [
          {
            "node": "PG claim_jobs()",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PG claim_jobs()": {
      "main": [
        [
          {
            "node": "Has jobs?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has jobs?": {
      "main": [
        [
          {
            "node": "SplitInBatches",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "SplitInBatches": {
      "main": [
        [
          {
            "node": "Set job vars",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set job vars": {
      "main": [
        [
          {
            "node": "Switch job type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch job type": {
      "main": [
        [
          {
            "node": "PG insert bot_leads",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "PG fetch lead",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "PG archive msg",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "PG material req",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PG insert bot_leads": {
      "main": [
        [
          {
            "node": "TG notify admin (lead)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "TG notify admin (lead)": {
      "main": [
        [
          {
            "node": "PG complete job",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PG fetch lead": {
      "main": [
        [
          {
            "node": "Set confirm msg",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set confirm msg": {
      "main": [
        [
          {
            "node": "TG notify admin (order)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "TG notify admin (order)": {
      "main": [
        [
          {
            "node": "PG complete job",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PG archive msg": {
      "main": [
        [
          {
            "node": "PG complete job",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PG material req": {
      "main": [
        [
          {
            "node": "TG notify admin (materials)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "TG notify admin (materials)": {
      "main": [
        [
          {
            "node": "PG complete job",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "active": false,
  "tags": [
    "bot",
    "telegram",
    "max",
    "job-queue"
  ]
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Bot / Job Queue Worker (Telegram + MAX). Uses postgres, telegram. Scheduled trigger; 15 nodes.

Source: https://github.com/alexdmitrievi/Podryad_PRO/blob/main/n8n/workflows/01-job-queue-worker.json — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

TelegramQuery. Uses httpRequest, dataTable, postgres, telegram. Scheduled trigger; 26 nodes.

HTTP Request, Data Table, Postgres +1
Slack & Telegram

Any external system triggers a reminder via webhook with a tenant token — the workflow validates the token, fetches the tenant's channel config and message template from PostgreSQL, renders the messag

Postgres, Telegram, Form Trigger +1
Slack & Telegram

Bot / CRM Nurture Worker (welcome → followup chain). Uses postgres, telegram. Scheduled trigger; 12 nodes.

Postgres, Telegram
Slack & Telegram

Premium / Referral notifications & loyalty hints. Uses postgres, telegram, httpRequest. Scheduled trigger; 11 nodes.

Postgres, Telegram, HTTP Request
Slack & Telegram

Premium / Referral notifications & loyalty hints. Uses postgres, telegram, httpRequest. Scheduled trigger; 11 nodes.

Postgres, Telegram, HTTP Request