← Blog

Manual

Correu i WhatsApp

setembre 11, 2026

L’app de gestió ja pot enviar i rebre correu i enviar i rebre WhatsApp. Tot es configura i es consulta des de dues pantalles noves dins de /compta/, i els avisos automàtics (confirmacions, recordatoris, tiquets) surten sols quan es creen cites, vendes o fitxes de client.

Què hem muntat

Tres serveis en segon pla i un connector dins de WordPress:

Peça Què fa On escolta
Mailpit Servidor de correu local: rep tot el correu, el desa i en mostra la safata 127.0.0.1:1025 (SMTP) i 127.0.0.1:8025 (safata i API)
Pont de WhatsApp Es vincula a WhatsApp Web amb un codi QR i envia/rep missatges 127.0.0.1:3001
Tasques de WordPress Importa el correu i envia els recordatoris cada minut
Plugin compt-comunicacions Connecta tot això amb l’app: ajustos, bústia, plantilles i automatitzacions

Per què no hi ha Postfix

En aquest entorn no hi ha root: sudo està bloquejat pel flag no new privileges, així que no s’hi poden instal·lar paquets de sistema com Postfix o Dovecot. La solució és fer servir serveis que corren en espai d’usuari, gestionats amb systemd d’usuari (amb Linger=yes, o sigui que sobreviuen al tancament de sessió i als reinicis).

Mailpit és un binari únic que fa d’MTA de proves: accepta el correu pel port 1025 i el desa en una base de dades SQLite, amb safata web i API HTTP incloses.

El servidor de correu local

Servei Unitat systemd Comanda
Mailpit mailpit.service systemctl --user restart mailpit
Pont de WhatsApp whatsapp-bridge.service systemctl --user restart whatsapp-bridge
Tasques de WordPress compt-comms-cron.timer systemctl --user list-timers

La safata de Mailpit es pot obrir directament a http://127.0.0.1:8025. Els registres són a /var/www/html/comms/logs/.

# Estat dels tres serveis
systemctl --user status mailpit whatsapp-bridge compt-comms-cron.timer

# Registres
tail -f /var/www/html/comms/logs/mailpit.log
tail -f /var/www/html/comms/logs/whatsapp.log
tail -f /var/www/html/comms/logs/wp-cron.log

Enviar correu: local o SMTP extern

El connector intercepta phpmailer_init i decideix per on surt el correu segons el mode triat a la pantalla de configuració:

  • Servidor local — tot el correu va a Mailpit (127.0.0.1:1025). És el mode per defecte i serveix per desenvolupar i provar sense enviar res de veritat.
  • SMTP extern — s’envia pel proveïdor que triïs (Gmail amb contrasenya d’aplicació, Brevo, Mailgun…): host, port, xifrat (STARTTLS o SSL), usuari i contrasenya.

També es filtren wp_mail_from i wp_mail_from_name, i es força Reply-To. Detall important après d’una prova: PHPMailer rebutja adreces sense domini amb punt, així que un remitent no-reply@nitidastudio.synology.me falla; per defecte s’usa un domini vàlid i, si el configurat no ho és, es cau a no-reply@<domini>.

Com que tot passa per wp_mail(), els correus de WooCommerce també surten per aquí.

Rebre correu

Mailpit envia un webhook a WordPress cada cop que arriba un correu nou:

GET/POST https://nitidastudio.synology.me/?compt_comms_mailpit=<testimoni>

El plugin valida el testimoni, demana el missatge sencer a l’API de Mailpit i el desa a la taula wp_comms_missatges. Com a xarxa de seguretat, el cron també fa un sondeig cada minut, de manera que cap correu no es perd si el webhook falla. Si el remitent coincideix amb l’email (o el telèfon) d’un client, el missatge s’enllaça sol a la seva fitxa; si no, es pot vincular a mà des de la bústia.

El pont de WhatsApp

És un petit servei en Node que fa servir la llibreria Baileys (WhatsApp Web). No cal compte de negoci ni API oficial: es vincula el mòbil escanejant un codi QR.

# Vincular (una sola vegada)
Obre /compta/comunicacions/ i escaneja el QR amb:
WhatsApp → Dispositius vinculats → Vincular un dispositiu

# Canviar de mòbil
/var/www/html/comms/reset-whatsapp.sh

El pont exposa una API senzilla, sempre a localhost i protegida amb un testimoni compartit (X-Compt-Token):

Endpoint Què fa
GET /health Estat: connectat, número vinculat, si hi ha QR
GET /qr.png Imatge del codi QR (la que es veu a la pantalla de configuració)
POST /send Enviar un text a un número
POST /send-media Enviar imatge, vídeo, àudio o document
POST /logout Desvincular el dispositiu

Quan arriba un missatge, el pont l’envia a /wp-json/compt-comms/v1/whatsapp/inbound; el plugin n’extreu el text (conversa, text estès, subtítols d’imatge o document, botons i llistes), l’enllaça al client pel telèfon i el deixa a la bústia. Els missatges de grup i els estats/reaixos s’ignoren.

Les pantalles noves

Al menú de l’app hi ha un grup nou, Comunicacions, amb dues entrades:

  • /compta/comunicacions/ — estat dels serveis, QR de WhatsApp, configuració de correu i de WhatsApp (pont local, Meta Cloud API o Twilio), automatitzacions i plantilles, amb botons per enviar correus i WhatsApps de prova i per sincronitzar la bústia.
  • /compta/missatges/ — bústia unificada: filtres per canal, sentit i estat, cerca, conversa per fils, resposta directa, vinculació a client i redacció de missatges nous.

Les rutes funcionen com la resta de l’app: s’afegeixen a astrolus_crud_slugs() i una entitat virtual a astrolus_entities(), i el plugin enganxa un filtre a template_include que carrega les seves plantilles. Els avisos de resultat es mostren amb paràmetres ?compt_msg=.

Automatitzacions

El tema ara dispara accions en desar registres (astrolus_entity_saved_<taula>), i el plugin les escolta:

Avis Quan surt Canal per defecte
Benvinguda En crear la fitxa d’un client Correu i WhatsApp
Confirmació de cita En crear una cita Correu i WhatsApp
Recordatori de cita 24 h abans (configurable) Correu i WhatsApp
Tiquet o factura En registrar una venda Correu
Avís a l’equip Cites i vendes noves Correu (als empleats actius)

Cada automatització es pot activar o desactivar i canviar de canal des de la pantalla de configuració. Els textos són plantilles editables amb variables com {client_nom}, {data}, {hora}, {servei}, {import} o {linies}. Els enviaments queden registrats a wp_comms_log per no repetir-se: el recordatori, per exemple, només s’envia un cop per cita.

Com ho hem verificat

  • Correu de prova enviat des de la pantalla → capturat per Mailpit → importat sol a la bústia.
  • Correu entrant des del correu d’una clienta → enllaçat automàticament a la seva fitxa.
  • Cita creada → confirmació a la clienta i avís a l’equip; el recordatori surt dins la finestra de 24 h i no es duplica si es torna a executar.
  • Venda creada → tiquet a la clienta i avís a l’equip.
  • Pont de WhatsApp amb QR vàlid; sense vincular, l’enviament retorna un error controlat i queda registrat.

Seguretat

  • Els tres serveis escolten només a 127.0.0.1: des d’una altra màquina de la xarxa no s’hi arriba.
  • La carpeta de serveis (/var/www/html/comms/) està bloquejada per web amb un .htaccess que retorna 403; a dins hi ha els testimonis i les credencials de WhatsApp.
  • Els endpoints REST exigeixen el testimoni compartit i retornen 401 sense ell.
  • Les pantalles de Comunicacions només són accessibles amb sessió de WordPress iniciada.
  • La carpeta comms/whatsapp/auth/ conté la sessió de WhatsApp: no s’ha de versionar mai.

Què queda pendent

  1. Vincular el WhatsApp: fins que no s’escaneja el QR, els enviaments de WhatsApp queden registrats com a error.
  2. Enviar correu de veritat: cal omplir el mode SMTP extern amb credencials.
  3. Rebre correu d’Internet (per exemple info@elteudomini.cat) requereix un domini amb registres MX i un servidor amb el port 25 obert; aquí no és possible, però en un VPS es podria instal·lar Postfix i Dovecot o contractar un servei de correu.
  4. El pont de WhatsApp fa servir WhatsApp Web, que no és l’API oficial: va molt bé per a un ús normal, però per a volums alts o números dedicats és millor Meta Cloud API o Twilio, totes dues ja suportades a la configuració.
  5. Els fitxers multimèdia entrants de WhatsApp es registren amb les seves dades (tipus i nom), però encara no es descarrega el contingut.

Fitxers clau

/var/www/html/comms/
├── bin/mailpit                 # servidor de correu
├── mailpit-data/               # missatges de Mailpit
├── whatsapp/server.js          # pont de WhatsApp (Node + Baileys)
├── whatsapp/config.json        # port, testimonis i URLs dels webhooks
├── units/                      # unitats systemd
├── logs/                       # registres
└── README.md                   # documentació completa

wp-content/plugins/compt-comunicacions/
├── includes/class-store.php       # taules de missatges, registre i cua
├── includes/class-settings.php    # ajustos i plantilles
├── includes/class-mailer.php      # SMTP i plantilles de correu
├── includes/class-whatsapp.php    # pont local, Meta i Twilio
├── includes/class-inbound.php     # webhooks i importació de correu
├── includes/class-automations.php # avisos automàtics
├── includes/class-ui.php          # rutes, accions i avisos
└── templates/                     # pantalles de configuració i bústia