Telegram Inspection Bot — Operations Guide

Issue: #595 n8n workflow ID: fJRm8PGfdVC0sFIJ n8n name: Telegram Inspection Bot (#595) Status: Inactive (pending credential setup — see Pre-Activation Checklist below)


Architecture

Mechanics and managers use the existing Ecotrans Service Bot Telegram bot to report vehicle technical inspections. They send text notes, voice recordings, photos, and videos during a session. When the session ends with /end, the workflow automatically creates a p24_l_cars_service_requests entry with typ_zgloszenia = 'przeglad_techniczny'.

Mechanic (Telegram)
      │
      ▼
et-serwis-production bot  ←──── VLAJVmuXXDAXG2GL credential
      │
      ▼
n8n: Telegram Inspection Bot (#595)
      │
      ├── text        → Supabase telegram_inspection_messages
      ├── voice       → Wasabi p24-infra/telegram-inspections/{session}/
      │                 → Groq Whisper large-v3 STT → Supabase
      ├── photo       → Wasabi → Supabase
      └── video       → Wasabi → Groq Whisper STT → Supabase
      │
      └── /end ──────► p24_l_cars_service_requests (typ_zgloszenia=przeglad_techniczny)

STT provider: Groq Whisper large-v3 (free tier: 7 200 min/month; baseline usage ~300 min/month) Fallback STT: Not implemented in this version; if Groq fails, the voice/video is still stored on Wasabi (the STT field is left NULL).


Bot Commands

CommandDescription
/startBegin a new inspection session. Bot prompts for vehicle registration plate.
/endClose the active session. Creates a service request in the system.

Any other text/media while a confirmed session is active is treated as inspection content.


Message Flow

/start flow

  1. User sends /start
  2. Bot checks if there is already an active session for that chat ID
    • If yes: informs user and exits (use /end first)
    • If no: asks for the vehicle registration number
  3. User sends a registration number (e.g. WU12345)
  4. Bot looks up public.p24_l_cars WHERE plates_normalized = UPPER(input)
    • If not found: informs user and asks again
    • If found: shows vehicle details (brand, model, year, VIN) and asks for confirmation
  5. User replies tak or nie
    • nie: bot asks for the plate again (session deleted, flow restarts)
    • tak: session is confirmed, bot acknowledges and enters collection mode

Collection mode (session active, vehicle confirmed)

Message typeWhat happens
TextSaved to telegram_inspection_messages (type=text)
VoiceDownloaded from Telegram → uploaded to Wasabi → Groq STT → saved with transcript
PhotoDownloaded → uploaded to Wasabi → saved with Wasabi URL
VideoDownloaded → uploaded to Wasabi → Groq STT from video file → saved with transcript

/end flow

  1. All messages for the session are aggregated into a summary
  2. A new row is inserted into p24_l_cars_service_requests:
    • typ_zgloszenia = 'przeglad_techniczny'
    • status = 'Nowe'
    • zgloszono_przez = 'telegram-bot'
    • description = aggregated text + transcript notes
    • comment = session metadata (session ID, message count)
  3. Session status is set to closed with closed_at = now()
  4. Bot confirms to user

Supabase Tables

public.telegram_inspection_sessions

ColumnTypeNotes
idUUIDPK
telegram_chat_idBIGINTTelegram chat ID
telegram_user_idBIGINTTelegram user ID
telegram_usernameTEXTOptional username
vehicle_idUUIDFK → p24_l_cars.id
plates_normalizedTEXTUppercase plate
vehicle_confirmedBOOLEANTrue after user confirms
statusTEXTactive or closed
started_atTIMESTAMPTZSession start
closed_atTIMESTAMPTZSet on /end
created_atTIMESTAMPTZRow creation

RLS: enabled, backend-only (no public policies — service_role access only).

public.telegram_inspection_messages

ColumnTypeNotes
idUUIDPK
session_idUUIDFK → telegram_inspection_sessions
telegram_message_idBIGINTTelegram message ID
message_typeTEXTtext, voice, photo, video
text_contentTEXTFor text messages
stt_textTEXTTranscript for voice/video
wasabi_urlTEXTFull HTTPS URL to file on Wasabi
wasabi_keyTEXTWasabi object key (without bucket)
file_size_bytesBIGINTOriginal file size
file_mime_typeTEXTMIME type
created_atTIMESTAMPTZRow creation

RLS: enabled, backend-only.


Wasabi Storage Layout

Bucket: p24-infra Region: eu-central-2 Endpoint: https://s3.eu-central-2.wasabisys.com

p24-infra/
  telegram-inspections/
    {session_id}/
      voice_{message_id}.ogg
      photo_{message_id}.jpg
      video_{message_id}.mp4

Files are stored permanently (no TTL). The telegram_inspection_messages.wasabi_url column holds the full public HTTPS URL.


STT: Groq Whisper large-v3

  • API: https://api.groq.com/openai/v1/audio/transcriptions
  • Model: whisper-large-v3
  • Language: pl (Polish, hardcoded)
  • Format: json response
  • Limits: 7 200 free minutes/month; baseline ~300 min/month (headroom: 6 900 min)
  • Get API key: https://console.groq.com → API Keys → Create key

If Groq returns an error, the voice/video message is still stored on Wasabi with stt_text = NULL. The session can still be closed with /end.


n8n Credential Requirements

The workflow fJRm8PGfdVC0sFIJ references two placeholder credential IDs that must be replaced before activation:

1. Groq API Key (HUMAN ACTION REQUIRED)

  1. Go to https://console.groq.com → API Keys → Create new key
  2. In n8n: Settings → Credentials → New → HTTP Bearer Auth
    • Name: Groq API - Whisper
    • Token: <your Groq API key>
  3. In the workflow, update the Groq STT - Voice and Groq STT - Video nodes:
    • Replace GROQ_CREDENTIAL_ID_PLACEHOLDER with the real credential ID
  4. The credential ID from n8n.bms-4.infra.zintegrowana.online needs to go into the n8n UI

2. Wasabi S3 Credential (HUMAN ACTION REQUIRED)

  1. In n8n: Settings → Credentials → New → AWS
    • Name: Wasabi S3 - p24-infra
    • Access Key ID: value of P24_INFRA_WASABI_ACCESS_KEY (from .env.local)
    • Secret Access Key: value of P24_INFRA_WASABI_SECRET_KEY (from .env.local)
    • Region: eu-central-2
    • Custom Endpoint: https://s3.eu-central-2.wasabisys.com
  2. In the workflow, update the Upload Voice/Photo/Video to Wasabi nodes:
    • Replace WASABI_CREDENTIAL_ID_PLACEHOLDER with the real credential ID

3. Telegram getFile nodes (HUMAN ACTION REQUIRED)

The Get Voice/Photo/Video File Path nodes call api.telegram.org using {{ $credentials.token }}. This requires the Telegram bot token to be accessible. Update those three HTTP Request nodes to use the actual bot token from the et-serwis-production Telegram credential, or switch to a Code node that reads the credential.

Simpler approach: Update the URL to hard-code the bot token (retrieve from n8n credential viewer).


Pre-Activation Checklist

  • Create Groq credential in n8n and update GROQ_CREDENTIAL_ID_PLACEHOLDER in both STT nodes
  • Create Wasabi AWS credential in n8n and update WASABI_CREDENTIAL_ID_PLACEHOLDER in all three upload nodes
  • Fix Get Voice/Photo/Video File Path nodes to inject bot token correctly
  • Test with /start → valid plate → tak confirmation
  • Test with voice note (verify STT text is in Polish)
  • Test with /end (verify service request created in p24_l_cars_service_requests)
  • Activate workflow in n8n UI

How to Test

  1. Open Telegram and start a chat with the Ecotrans Service Bot
  2. Send /start
  3. Enter a plate that exists in p24_l_cars (e.g. query: SELECT plates_normalized FROM public.p24_l_cars LIMIT 5)
  4. Confirm with tak
  5. Send a text message, then a voice note
  6. Send /end
  7. Verify in Supabase:
    SELECT * FROM public.telegram_inspection_sessions ORDER BY created_at DESC LIMIT 1;
    SELECT * FROM public.telegram_inspection_messages WHERE session_id = '<id>' ORDER BY created_at;
    SELECT * FROM public.p24_l_cars_service_requests WHERE typ_zgloszenia = 'przeglad_techniczny' ORDER BY created_at DESC LIMIT 1;

Troubleshooting

SymptomLikely causeFix
Bot doesn’t respondWorkflow not activeActivate in n8n UI
”Nie znaleziono pojazdu”Plate not in p24_l_carsVerify plates_normalized format (uppercase, no spaces)
Voice saved but no STTGroq API key missing/invalidCheck Groq STT - Voice node credential
Wasabi upload failsWasabi credential missingCheck Upload Voice to Wasabi node credential
Session not foundDB RLSWorkflow uses supabaseApi with service_role — ensure credential has correct key
/end creates no service requestvehicle_confirmed = falseUser must confirm with ‘tak’ before sending media

EU AI Act Classification

Registered in dev_r_ai_systems:

  • project_id: p24-infra
  • service_name: telegram-inspection-bot
  • system_name: voice-to-text-inspection
  • eu_ai_act_risk: minimal
  • decision_type: informational
  • has_human_oversight: true

Classification justification: Transcription-only, no automated decisions, no Annex III high-risk triggers (no worker evaluation, scoring, or employment decisions).


  • n8n-workflows/telegram-inspection-bot_is595.json — workflow JSON (importable)
  • supabase/migrations/20260616_telegram_inspection_bot.sql — DB migration (already applied)
  • docs/eu-ai-act-compliance.md — EU AI Act compliance overview