Business Digital

Intégrations webhooks et bots Mattermost : tutoriel pratique 2026

11 min de lecture

📍 Article principal de la série : Mattermost 2026 : guide pratique.

Mattermost devient puissant quand connecté à votre stack : Forgejo notifie les PR, Grafana alerte les SLO breaches, Uptime Kuma signale les downtimes, Wave Webhook confirme les paiements. Ce tutoriel détaille les configurations testées en production.

Prérequis

  • Mattermost en production avec compte admin.
  • Niveau attendu : intermédiaire.
  • Temps estimé : 1-2 heures pour 5 intégrations.

Webhook entrant : pattern général

Étape 1 — Créer webhook dans Mattermost

Profile picture → Integrations → Incoming Webhooks → Add. Saisir :

  • Title : nom service (Forgejo, Grafana…).
  • Channel : où poster.
  • Lock to channel : ON pour sécurité.

Mattermost génère URL type https://chat.../hooks/abc123xyz. Copier.

Étape 2 — Tester

curl -X POST -H "Content-Type: application/json" \
  -d '{"text":"Hello from cURL!"}' \
  https://chat.../hooks/abc123xyz

Message apparaît dans channel Mattermost.

Intégration Forgejo

Settings repo Forgejo → Webhooks → Add webhook → Mattermost. Configuration :

  • Target URL : webhook Mattermost copié.
  • Channel : nom channel.
  • Username : forgejo-bot.
  • Events : Push, Pull Request, Issues, Releases.

À chaque PR créée/mergée, message dans #dev avec lien.

Intégration Grafana Alerts

Grafana → Alerting → Contact points → New → type Webhook. URL : webhook Mattermost. Format JSON Mattermost-compatible :

{
  "text": "🚨 **{{ .CommonLabels.alertname }}** {{ .Status }}\n{{ .CommonAnnotations.summary }}",
  "channel": "alerts"
}

Toute alert Grafana (SLO breach, latence p99 > 500ms) post dans #alerts.

Intégration Uptime Kuma

Settings monitor → Notifications → Add → Mattermost. URL webhook + channel. Pour chaque DOWN ou UP, message immédiat.

{
  "text": "🔴 **{{monitorJSON.name}}** is DOWN\nReason: {{ msg }}"
}

Intégration Wave Mobile Money

Wave Business webhook → URL endpoint custom (votre VPS). Endpoint validate signature puis post Mattermost :

// app/api/wave-webhook/route.ts (Next.js)
import { verify } from 'crypto';

export async function POST(req: Request) {
  const body = await req.text();
  const sig = req.headers.get('Wave-Signature');
  if (!verify(body, sig, process.env.WAVE_SECRET)) {
    return new Response('Invalid', { status: 401 });
  }
  const data = JSON.parse(body);
  if (data.type === 'checkout.session.completed') {
    await fetch(process.env.MATTERMOST_WEBHOOK!, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        text: `💰 Paiement Wave reçu : ${data.amount} XOF de ${data.customer_phone}`,
        channel: 'sales'
      })
    });
  }
  return new Response('OK');
}

Slash commands custom

Profile → Integrations → Slash Commands → Add. Exemple /standup qui demande à chacun ses 3 lignes :

  • Command : standup.
  • Method : POST.
  • Request URL : https://api.votre-entreprise.com/standup.
  • Response Type : in-channel ou ephemeral.
// API endpoint /standup
export async function POST(req: Request) {
  const formData = await req.formData();
  const username = formData.get('user_name');
  return Response.json({
    response_type: 'in_channel',
    text: `📝 Standup de ${username}: ...`,
    attachments: [{
      actions: [{
        name: 'Hier', integration: { url: '...' }
      }]
    }]
  });
}

Bots custom (Plugins)

Pour bots avancés, plugin Mattermost en Go ou JavaScript. System Console → Plugins → Upload. Plugin lit/écrit messages, réagit à mentions, exécute commandes.

Exemples plugins officiels : Welcome Bot (onboarding new users), Standup, Polls, Webhooks (proxy).

Erreurs fréquentes

Erreur Cause Solution
Webhook 404 URL mal copiée Vérifier hooks/… format
Message en clair sans markdown Format JSON sans "text" Toujours wrapper dans {"text":"..."}
Channel inexistant Lock to channel ON empêche override Désactiver lock ou cibler bon channel
Webhook sortant ne déclenche pas Trigger word manquant Définir trigger word dans config
Bot ne lit pas messages Permissions plugin insuffisantes System Console permissions
Rate limit Mattermost > 30 req/sec Batch via queue

Spécificités Afrique de l’Ouest francophone

Trois précisions. Webhooks Mobile Money : Wave, Orange Money, Mixx by Yas (ex-Free Money) offrent webhooks signés. Toujours vérifier signature avant poster Mattermost (sinon spam possible). Notifications client : channel #client-X dédié pour mises à jour automatisées (build deploy, monitoring). Bot Astreinte : bot mention @on-call route vers la personne d’astreinte selon planning Postgres.

Tutoriels frères

FAQ

Webhooks IPv6 ? Oui, Mattermost répond IPv4 et IPv6.

Limites webhooks ? 30 req/sec par webhook. Throttle si plus.

Bots multi-channel ? Oui, un bot peut poster dans plusieurs channels.

Bots écrire en DM ? Oui, via API si bot a permission.

Plugins Slack compatibles ? Non. Mais équivalents existants.

Lectures complémentaires

Étape 1 — Activer les intégrations dans la console System Console

Avant tout webhook, Mattermost désactive par défaut les intégrations entrantes pour limiter la surface d’attaque. Connectez-vous en compte System Admin et ouvrez System Console → Integrations → Integration Management. Cette étape conditionne l’ensemble du tutoriel : sans elle, aucune commande ni aucun bot ne fonctionne.

Enable Incoming Webhooks: true
Enable Outgoing Webhooks: true
Enable Custom Slash Commands: true
Enable Bot Account Creation: true
Enable User Access Tokens: true

Cliquez Save. La preuve que ça tourne : un membre standard voit désormais l’option Integrations dans le menu de son équipe et la création d’un webhook entrant est possible sans intervention admin.

Étape 2 — Créer un webhook entrant pour les alertes Grafana

Le cas d’usage le plus courant : pousser des alertes monitoring dans un canal #ops. Dans Main Menu → Integrations → Incoming Webhooks → Add Incoming Webhook, ciblez le canal ops-dakar. Mattermost retourne une URL secrète à conserver dans Vaultwarden ou dans la variable d’environnement Grafana.

POST https://mm.itskillscenter.io/hooks/abcd1234efgh5678
Content-Type: application/json

{
  "text": ":fire: **High CPU** sur srv-prod-1",
  "channel": "ops-dakar",
  "username": "grafana",
  "icon_url": "https://grafana.com/static/img/menu/grafana2.svg"
}

Testez avec curl. La preuve que ça tourne : un message au visuel Grafana apparaît instantanément dans #ops-dakar avec l’icône configurée et un horodatage UTC converti en heure locale Dakar.

Étape 3 — Construire un webhook sortant qui réagit à un mot-clé

Un webhook sortant transforme Mattermost en déclencheur HTTP. Exemple : taper !deploy staging dans #releases déclenche un POST vers votre serveur n8n qui lance la pipeline. Dans Outgoing Webhooks → Add :

Title: Trigger n8n deploy
Content Type: application/json
Channel: releases
Trigger Words: !deploy
Callback URLs: https://n8n.itskillscenter.io/webhook/mm-deploy

Côté n8n, créez un workflow avec un nœud Webhook qui parse le payload Mattermost (champs token, text, user_name). Vérifiez le token pour rejeter les appels usurpés. Validation pratique : !deploy staging dans #releases déclenche le workflow n8n et un message de confirmation s’affiche dans le canal sous 3 secondes.

Étape 4 — Créer une commande slash personnalisée

Une slash command est plus discrète qu’un webhook sortant : elle ne pollue pas le canal avec le déclencheur. Dans Slash Commands → Add, créez /jira qui interroge votre instance Jira Cloud et renvoie le statut d’un ticket.

Command Trigger Word: jira
Request URL: https://jira-bridge.itskillscenter.io/mm-slash
Request Method: POST
Response Username: jira-bot
Autocomplete: true
Autocomplete Hint: [TICKET-ID]
Autocomplete Description: Affiche le statut d'un ticket Jira

Testez avec /jira ITSC-42. Votre bridge doit répondre en moins de 3 secondes (timeout Mattermost) avec un payload JSON. Indicateur que tout est en place : la fiche du ticket s’affiche en mode ephemeral (visible uniquement pour vous) avec titre, statut et assignee.

Étape 5 — Provisionner un compte bot avec un token long-lived

Pour un bot persistant qui écoute les events WebSocket (réponse à mention, sondage, modération), un User Access Token sur compte bot est plus propre qu’un User Access Token sur un compte humain. Dans Integrations → Bot Accounts → Add :

Username: assistant-itsc
Display Name: Assistant ITSkillsCenter
Description: Bot interne automatisations
Role: Member (ou System Admin si modération globale)

Mattermost génère un token mmsa-xxxxxxxxxxxx à conserver hors du dépôt Git. Ajoutez-le dans le canal cible via Channel Settings → Manage Members → Add Members. Le test concluant : un appel GET /api/v4/users/me avec le header Authorization: Bearer mmsa-... retourne le profil du bot.

Étape 6 — Écrire un bot Node.js qui répond aux mentions

Le SDK officiel @mattermost/client couvre REST et WebSocket. Voici un bot minimal qui répond Bonjour Dakar ! dès qu’on le mentionne. Cible Node 22 LTS, pas Node 20 (EOL avril 2026).

// bot.mjs
import { Client4, WebSocketClient } from '@mattermost/client';
const c = new Client4();
c.setUrl('https://mm.itskillscenter.io');
c.setToken(process.env.MM_TOKEN);
const me = await c.getMe();
const ws = new WebSocketClient();
ws.initialize('wss://mm.itskillscenter.io/api/v4/websocket', process.env.MM_TOKEN);
ws.addMessageListener(async (e) => {
  if (e.event !== 'posted') return;
  const post = JSON.parse(e.data.post);
  if (post.user_id === me.id) return;
  if (post.message.includes('@assistant-itsc')) {
    await c.createPost({ channel_id: post.channel_id, message: 'Bonjour Dakar !' });
  }
});

Lancez avec MM_TOKEN=mmsa-... node bot.mjs sous PM2 ou systemd. Le test concluant : taper @assistant-itsc bonjour dans n’importe quel canal où le bot est membre déclenche la réponse en moins de 500 ms.

Étape 7 — Sécuriser les webhooks avec un secret partagé et IP allowlist

Une URL de webhook entrante non protégée est un risque de spam et d’usurpation. Mattermost n’expose pas nativement de signature HMAC sur les webhooks entrants, mais vous pouvez placer un proxy Caddy ou Traefik en frontal qui valide un header X-Webhook-Secret avant de relayer.

# Caddyfile
mm-hooks.itskillscenter.io {
  @authorized header X-Webhook-Secret "super-secret-2026"
  reverse_proxy @authorized localhost:8065
  respond 401
}

Côté webhooks sortants, vérifiez systématiquement le champ token (généré par Mattermost à la création) côté serveur. Vous saurez que tout fonctionne quand : un test avec un mauvais secret retourne 401 et n’apparaît pas dans Mattermost ; un test avec le bon secret arrive normalement.

Étape 8 — Logger et superviser les intégrations en production

Sans observabilité, un bot qui crash silencieusement laisse l’équipe sans réponse pendant des heures. Utilisez Loki ou Grafana Cloud (free tier 50 Go logs/mois) pour centraliser les logs du bot et des bridges. Ajoutez un healthcheck qui poste ping dans #monitoring toutes les 5 minutes.

# bot.mjs - keepalive
setInterval(async () => {
  try {
    await c.createPost({ channel_id: MONITORING_CHANNEL_ID, message: 'ping ' + new Date().toISOString() });
  } catch (e) { console.error('keepalive failed', e); process.exit(1); }
}, 5 * 60 * 1000);

PM2 ou systemd redémarre alors le bot et l’absence de ping sur 10 minutes déclenche une alerte Uptime Kuma. Le test concluant : un kill manuel du bot provoque une alerte dans #ops sous 11 minutes maximum, suivie d’une reprise automatique. Vous disposez maintenant d’une stack d’intégrations Mattermost robuste : webhooks chiffrés, slash commands, bot WebSocket, supervision et reprise automatique, prête pour une équipe distribuée Dakar-Abidjan.

Étape 9 — Brancher un bridge Matterbridge avec WhatsApp Business

Beaucoup d’équipes ouest-africaines pilotent leur support client depuis WhatsApp Business via l’API Cloud Meta (Graph API v25.0). Plutôt que de faire alterner les opérateurs entre deux apps, faites circuler les messages WhatsApp dans un canal Mattermost dédié #support-wa via Matterbridge. Les agents répondent depuis Mattermost, le bridge reformate le message au bon format pour Meta.

# matterbridge.toml extrait
[mattermost.itsc]
Server = "mm.itskillscenter.io"
Token = "mmsa-bridge-token"
PrefixMessagesWithNick = true

[whatsapp.support]
Number = "+221770000000"
ApiToken = "EAAG...whatsapp-cloud-token"

[[gateway]]
name = "support"
enable = true
[[gateway.inout]]
account = "mattermost.itsc"
channel = "support-wa"
[[gateway.inout]]
account = "whatsapp.support"
channel = "main"

Lancez matterbridge -conf matterbridge.toml dans un conteneur Docker. Validation pratique : un message WhatsApp envoyé au numéro Business apparaît dans #support-wa préfixé par le numéro de l’expéditeur, et la réponse d’un agent est livrée sur WhatsApp en moins de 2 secondes. Attention aux quotas Meta : la fenêtre conversationnelle gratuite est de 24h après le premier message client.

Étape 10 — Mesurer l’usage et facturer en interne

Une fois 5 ou 6 intégrations en production, comptez les messages, slash commands et appels webhook par équipe pour facturer en interne ou justifier le coût d’infrastructure auprès de la direction. Mattermost expose tout cela dans la table Posts et l’endpoint /api/v4/integrations/usage. Construisez un dashboard Grafana avec datasource PostgreSQL pointant sur la base Mattermost en lecture seule.

-- Top 10 webhooks entrants par volume mensuel
SELECT username, COUNT(*) AS msgs
FROM Posts
WHERE Type='' AND CreateAt > (extract(epoch from now() - interval '30 days') * 1000)::bigint
  AND Props ? 'from_webhook'
GROUP BY username
ORDER BY msgs DESC
LIMIT 10;

Comment vérifier le bon fonctionnement : un panneau Grafana publié dans #ops liste les top webhooks et bots par usage, mis à jour toutes les 5 minutes. Vous disposez maintenant d’une plateforme d’intégrations Mattermost mature : WhatsApp bridgé pour le support, métriques d’usage exposées et budget infrastructure justifiable poste par poste.

Étape 11 — Versionner et redéployer toutes les intégrations en un clic

Au-delà de 5 intégrations actives, recréer manuellement webhooks et bots après une réinstallation prend des heures. La parade : exporter les définitions en JSON via mmctl integrations export et les commit dans un dépôt Gitea privé. Au prochain déploiement, un script Ansible rejoue toutes les définitions sur le nouveau Mattermost.

mmctl auth login https://mm.itskillscenter.io --name prod --access-token $MM_TOKEN
mmctl webhook list-incoming --json > integrations/incoming.json
mmctl webhook list-outgoing --json > integrations/outgoing.json
mmctl bot list --json > integrations/bots.json
git add integrations/ && git commit -m 'snapshot intégrations 2026-05-05'

Le bon résultat se reconnaît à : un test de restauration sur un Mattermost vierge à partir du dépôt Git reconstruit en moins de 15 minutes l’ensemble des webhooks, slash commands, bots et bridges WhatsApp. Vous avez désormais une plateforme d’intégrations Mattermost industrialisée, observée et reproductible — base solide pour scaler de 10 à 100 utilisateurs sans refaire la configuration.

Partager