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
| Command | Description |
|---|---|
/start | Begin a new inspection session. Bot prompts for vehicle registration plate. |
/end | Close 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
- User sends
/start - Bot checks if there is already an active session for that chat ID
- If yes: informs user and exits (use
/endfirst) - If no: asks for the vehicle registration number
- If yes: informs user and exits (use
- User sends a registration number (e.g.
WU12345) - 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
- User replies
takornienie: 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 type | What happens |
|---|---|
| Text | Saved to telegram_inspection_messages (type=text) |
| Voice | Downloaded from Telegram → uploaded to Wasabi → Groq STT → saved with transcript |
| Photo | Downloaded → uploaded to Wasabi → saved with Wasabi URL |
| Video | Downloaded → uploaded to Wasabi → Groq STT from video file → saved with transcript |
/end flow
- All messages for the session are aggregated into a summary
- 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 notescomment= session metadata (session ID, message count)
- Session status is set to
closedwithclosed_at = now() - Bot confirms to user
Supabase Tables
public.telegram_inspection_sessions
| Column | Type | Notes |
|---|---|---|
id | UUID | PK |
telegram_chat_id | BIGINT | Telegram chat ID |
telegram_user_id | BIGINT | Telegram user ID |
telegram_username | TEXT | Optional username |
vehicle_id | UUID | FK → p24_l_cars.id |
plates_normalized | TEXT | Uppercase plate |
vehicle_confirmed | BOOLEAN | True after user confirms |
status | TEXT | active or closed |
started_at | TIMESTAMPTZ | Session start |
closed_at | TIMESTAMPTZ | Set on /end |
created_at | TIMESTAMPTZ | Row creation |
RLS: enabled, backend-only (no public policies — service_role access only).
public.telegram_inspection_messages
| Column | Type | Notes |
|---|---|---|
id | UUID | PK |
session_id | UUID | FK → telegram_inspection_sessions |
telegram_message_id | BIGINT | Telegram message ID |
message_type | TEXT | text, voice, photo, video |
text_content | TEXT | For text messages |
stt_text | TEXT | Transcript for voice/video |
wasabi_url | TEXT | Full HTTPS URL to file on Wasabi |
wasabi_key | TEXT | Wasabi object key (without bucket) |
file_size_bytes | BIGINT | Original file size |
file_mime_type | TEXT | MIME type |
created_at | TIMESTAMPTZ | Row 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:
jsonresponse - 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)
- Go to https://console.groq.com → API Keys → Create new key
- In n8n: Settings → Credentials → New → HTTP Bearer Auth
- Name:
Groq API - Whisper - Token:
<your Groq API key>
- Name:
- In the workflow, update the
Groq STT - VoiceandGroq STT - Videonodes:- Replace
GROQ_CREDENTIAL_ID_PLACEHOLDERwith the real credential ID
- Replace
- The credential ID from
n8n.bms-4.infra.zintegrowana.onlineneeds to go into the n8n UI
2. Wasabi S3 Credential (HUMAN ACTION REQUIRED)
- 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
- Name:
- In the workflow, update the
Upload Voice/Photo/Video to Wasabinodes:- Replace
WASABI_CREDENTIAL_ID_PLACEHOLDERwith the real credential ID
- Replace
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_PLACEHOLDERin both STT nodes - Create Wasabi AWS credential in n8n and update
WASABI_CREDENTIAL_ID_PLACEHOLDERin all three upload nodes - Fix
Get Voice/Photo/Video File Pathnodes to inject bot token correctly - Test with
/start→ valid plate →takconfirmation - 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
- Open Telegram and start a chat with the
Ecotrans Service Bot - Send
/start - Enter a plate that exists in
p24_l_cars(e.g. query:SELECT plates_normalized FROM public.p24_l_cars LIMIT 5) - Confirm with
tak - Send a text message, then a voice note
- Send
/end - 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
| Symptom | Likely cause | Fix |
|---|---|---|
| Bot doesn’t respond | Workflow not active | Activate in n8n UI |
| ”Nie znaleziono pojazdu” | Plate not in p24_l_cars | Verify plates_normalized format (uppercase, no spaces) |
| Voice saved but no STT | Groq API key missing/invalid | Check Groq STT - Voice node credential |
| Wasabi upload fails | Wasabi credential missing | Check Upload Voice to Wasabi node credential |
| Session not found | DB RLS | Workflow uses supabaseApi with service_role — ensure credential has correct key |
| /end creates no service request | vehicle_confirmed = false | User must confirm with ‘tak’ before sending media |
EU AI Act Classification
Registered in dev_r_ai_systems:
project_id:p24-infraservice_name:telegram-inspection-botsystem_name:voice-to-text-inspectioneu_ai_act_risk:minimaldecision_type:informationalhas_human_oversight:true
Classification justification: Transcription-only, no automated decisions, no Annex III high-risk triggers (no worker evaluation, scoring, or employment decisions).
Related Files
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