-
Notifications
You must be signed in to change notification settings - Fork 15
Let customers chat with an analyst over WhatsApp β every message becomes a normal FreeITSM ticket. It sits alongside email as another inbound channel and reuses the whole ticket pipeline: the reading-pane thread, multi-tenancy routing/isolation, origins and the requester record.
Status: Phase 1 β Twilio end-to-end (inbound β ticket, in-window replies, AI summary/suggest), plus a Meta Cloud provider behind the same interface. Templates (for replying outside the 24h window), media download, and the hosted relay are later phases.
A messaging channel is the channel equivalent of an email mailbox β one WhatsApp number wired to a provider. When a customer messages it:
- The provider (Twilio or Meta) pushes the message to this install's webhook:
api/messaging/webhook.php?channel=<id>. - FreeITSM verifies the request, finds an open conversation for that sender (or opens a new ticket), and stores the message.
- The ticket is tagged with the WhatsApp origin and shows in the inbox like any other ticket.
- The analyst replies from an inline composer in the reading pane; the reply goes back out over WhatsApp.
Inbound and outbound messages live in the same emails table as email (with a channel column), so the reading-pane conversation thread just works.
Email works by FreeITSM polling a mailbox. WhatsApp is the opposite: the provider pushes inbound messages to a public HTTPS URL β there is no polling option. So the install must be reachable from the internet on that URL.
-
Hosted / public server: point the provider at
https://yourdomain/api/messaging/webhook.php?channel=<id>. Done. -
Local / behind a firewall (dev or self-host): run a tunnel and use the public URL it gives you:
Then the webhook is e.g.
ngrok http 80https://abc123.ngrok-free.app/freeitsm-app/api/messaging/webhook.php?channel=<id>.
Tip β set the Public base URL once. At the top of Settings β Messaging there's a Public base URL field. Put your public domain there (or your
ngrokaddress while testing) and every channel's webhook URL shown below becomes copy-paste-ready β no hand-editinglocalhost. Leave it blank to fall back to whatever address you're browsing from.
Choose per channel under Tickets β Settings β Messaging:
| Provider | Best for | Notes |
|---|---|---|
| Twilio | Getting started / testing | Has a WhatsApp sandbox β you can send/receive end-to-end with no Meta business verification. Recommended first build. |
| Meta WhatsApp Cloud API | Production, direct | Cheapest long-term (no middleman), but needs Meta business verification before it works. |
Both implement the same MessagingProvider interface (includes/messaging/), so switching is just a channel setting.
- Twilio: Account SID + Auth Token. The channel's WhatsApp number is the "From".
- Meta: Phone number ID + Access token + App secret, plus a Verify token you choose (used for Meta's webhook subscription handshake).
Credentials are encrypted at rest (AES-256-GCM, same as mailbox secrets).
Each channel has an ingress mode:
-
Direct β the provider hits this install's webhook URL directly. Authenticated by the provider's own request signature (Twilio's
X-Twilio-Signature, Meta'sX-Hub-Signature-256). -
Relay β a hosted relay forwards the verbatim request to this install. Authenticated by a shared secret (
X-FreeITSM-Relay-Secret). For self-hosters who can't expose a public endpoint. (The relay component itself is a later phase; the endpoint already accepts relayed requests.)
Channel routing mirrors email routing exactly, but keyed on the sender's phone number (numbers have no domain):
- Single-company install β the Default company.
- Pinned channel (assigned to a company) β that company; sender ignored.
- Shared channel β the exact sender number is mapped to a company β that company; otherwise triage (surfaces under Default until filed).
On a single-company install none of this is visible β it behaves exactly as today.
WhatsApp only allows free-text replies within 24 hours of the customer's last message. Outside that window, providers block free text and require a pre-approved template message.
FreeITSM tracks this per conversation (tickets.last_inbound_at). Inside the window, the composer works normally. Once it closes, the composer is disabled with a notice β template support is a later phase.
From the composer on a WhatsApp ticket:
- Suggest β drafts a concise reply for you to review/edit before sending (nothing is sent automatically).
- Summarise β summarises the conversation and saves it as an internal note on the ticket.
Both reuse the Tickets β Settings β Reply Cleanup AI key/provider, so usage shows on that billing line.
- In Twilio, open the WhatsApp sandbox and note your Account SID, Auth Token, and sandbox number.
- In FreeITSM: Tickets β Settings β Messaging β Add. Provider = Twilio, enter the number + SID + token, save.
- Copy the channel's webhook URL from the list. If testing locally, start
ngrok http 80and swap the host for your ngrok host. - Paste that URL into the Twilio sandbox's "When a message comes in" field.
- Join the sandbox from your phone (send the join code), then message it β a ticket appears in the inbox.
- Open the ticket and reply from the composer; the reply lands on your phone.
-
includes/messaging/βMessagingProvider(interface),TwilioProvider,MetaCloudProvider,messaging.php(factory + helpers),ingest.php(message β ticket). -
api/messaging/βwebhook.php(inbound),send_message.php(analyst reply),ai_summary.php,ai_suggest_reply.php,get_channels.php/save_channel.php/delete_channel.php. - Tables:
messaging_channels,tenant_channel_senders; plusemails.channel/emails.channel_idandtickets.last_inbound_at.
FreeITSM β an open-source IT Service Management platform Β· github.com/edmozley/freeitsm Β· MIT licence
- Installation
- β° Scheduled tasks (cron jobs)
- Architecture
- AI Providers
- Internationalisation (i18n)
- Timezones & Time Handling
- Theming & Dark Mode
- β¨οΈ Command palette (βK)
- π Searching inside tickets
- π Attached documents
- MobileβFriendly
-
Security
- Layer 1 β which modules you can enter
- β³ π§© Module Access Control
- β³ π οΈ Module Access β Developer Guide
- Layer 2 β what you can administer
- β³ π Roles & Permissions
- β³ π οΈ Roles β Developer Guide
- β³ π€ Why capabilities are constants
- Layer 3 β the System module
- β³ π Admin Access Control
- Hardening
- β³ π Security review response 2026-08
- β³ π‘οΈ Security hardening 2026-08
- β³ π οΈ Security hardening 2026-08 β Developer Guide
- β³ π‘οΈ Round three β plain English
- β³ π οΈ Round three β Developer Guide
- Single Sign-On (SSO)
- ποΈ LDAP & Active Directory
- Browser Extension
- API Reference
-
π REST API β how it works
- β³ π« REST API: Tickets
- β³ π» REST API: Assets
- β³ π΄ REST API: Problems
- β³ π REST API: Changes
- β³ π REST API: Knowledge
- β³ β REST API: Tasks
- β³ ποΈ REST API: CMDB
- β³ π REST API: Contracts
- β³ ποΈ REST API: Calendar
- β³ πΏ REST API: Software
- β³ π¦ REST API: Service Status
- β³ βοΈ REST API: Morning Checks
- β³ π REST API: Forms
- β³ βοΈ REST API: Workflow
- β³ πΊοΈ REST API: Network Mapper
- β³ π§ Using the API docs page
- β³ π OpenAPI specification
- β³ β OpenAPI: kept correct
- β³ π οΈ Maintaining the catalogue
- Watchtower
-
Tickets
- β³ Mailbox Authentication
- β³ π€ Email send log
- β³ Basic IMAP mailboxes
- β³ Email rendering & images
- β³ SLA Management
- β³ WhatsApp channel
- β³ π¬ Web chat channel
- β³ π£ Slack channel
- β³ π Linking tickets
- β³ ποΈ Canned responses
- β³ βοΈ Limiting replies to particular senders
- β³ βοΈ Email signatures
- β³ π The public web address
- β³ π Raising a ticket for someone else
- β³ π Merging tickets
- β³ β Splitting tickets
- β³ β Selecting several tickets
- β³ π οΈ Snoozing tickets β Developer Guide
- β³ π₯ Collision detection
- β³ β±οΈ Time tracking
- Problem Management
- Tasks
- Assets
- Knowledge
- Change Management
- Calendar
- Morning Checks
- Reporting
- Software
- Forms
- Contracts
- Service Status
- π Notifications
- π¨ War Room
- Self-Service Portal
- LMS
- Process Mapper
- CMDB
- Network Mapper
- Workflows
- Issue trackers (Jira, Azure DevOps)
- System
-
Overview
- β³ π Progress tracker
- β³ Concepts & vocabulary
- β³ Email routing & mailboxes
- β³ Settings: global vs per-company
- β³ Users & self-service
- β³ Staff cross-company access
- β³ Worked examples
- β³ Pitfalls & gotchas
- β³ Scope: what it's for
- β³ π οΈ Developer Guide (make a module multi-company)
- β³ ποΈ Case study: CMDB (a linked graph)
- β³ π§ͺ Test harness (prove it's isolated)