Aller au contenu

Envoyer un SMS avec Node.js et une API REST (fetch, Express, TypeScript)

Envoyer un SMS depuis Node.js avec l'API SMS Gold : fetch natif, module réutilisable en TypeScript, route Express et gestion des erreurs.

Depuis Node.js 18, fetch est disponible nativement : envoyer un SMS ne demande aucune bibliothèque supplémentaire. Voici comment appeler l'API SMS Gold depuis un script, un module TypeScript ou une application Express.

Prérequis

  • Un compte SMS Gold activé, avec des crédits et un nom d'expéditeur approuvé.
  • Une clé API, définie dans une variable d'environnement SMSGOLD_API_KEY (fichier .env chargé avec node --env-file=.env depuis Node.js 20, ou dotenv).
  • Node.js 18 ou plus.

1. Le premier SMS

// send.mjs
const res = await fetch("https://smsgold.tornixtech.com/api/v2/sms/send", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SMSGOLD_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    to: "+2250700000000",
    message: "Votre commande n°1042 est prête.",
    sender_name: "MABOUTIQUE",
  }),
});

console.log(res.status, await res.json());

Exécutez-le avec node --env-file=.env send.mjs.

2. Un module TypeScript réutilisable

// smsgold.ts
const API_URL = "https://smsgold.tornixtech.com/api/v2/sms/send";

export interface SendResult {
  success: boolean;
  message_id: string | null;
  status: "sent" | "failed";
  credits_remaining: number;
  error: string | null;
}

export class SmsError extends Error {
  constructor(public status: number, message: string) {
    super(`${status} : ${message}`);
  }
}

/** 07 00 00 00 00 -> +2250700000000 */
export function normalizeCI(phone: string): string {
  const digits = phone.replace(/\D/g, "");
  return digits.startsWith("225") ? `+${digits}` : `+225${digits}`;
}

export async function sendSms(to: string, message: string, sender = "MABOUTIQUE"): Promise<SendResult> {
  let res: Response;
  try {
    res = await fetch(API_URL, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.SMSGOLD_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ to: normalizeCI(to), message, sender_name: sender }),
      signal: AbortSignal.timeout(30_000),
    });
  } catch (err) {
    throw new SmsError(0, `connexion impossible : ${(err as Error).message}`);
  }

  const data = await res.json().catch(() => ({}));
  if (!res.ok || !data.success) {
    throw new SmsError(res.status, data.error ?? "erreur inconnue");
  }
  return data as SendResult;
}

AbortSignal.timeout() interrompt la requête si elle dépasse 30 secondes, pour ne jamais bloquer votre application.

3. Une route Express

import express from "express";
import { sendSms, SmsError } from "./smsgold.js";

const app = express();
app.use(express.json());

app.post("/orders/:id/ready", async (req, res) => {
  try {
    const result = await sendSms(req.body.phone, `Votre commande n°${req.params.id} est prête.`);
    res.json({ ok: true, messageId: result.message_id });
  } catch (err) {
    const status = err instanceof SmsError ? err.status : 500;
    res.status(status === 402 ? 402 : 502).json({ ok: false, error: (err as Error).message });
  }
});

app.listen(3000);

En production, préférez une file de tâches (BullMQ, par exemple) pour envoyer les SMS en arrière-plan et absorber les pics d'activité.

4. Codes d'erreur à connaître

  • 401 : clé API absente, invalide ou révoquée.
  • 402 : crédits insuffisants, aucun débit effectué.
  • 403 : compte désactivé ou aucun nom d'expéditeur approuvé.
  • 422 : champ manquant ou sender_name non approuvé pour votre compte.
  • 502 : l'opérateur n'a pas confirmé l'envoi ; vérifiez votre solde avant de relancer.

5. Sécurité

  • N'appelez jamais l'API depuis le navigateur ou une application mobile : votre clé serait exposée. Passez toujours par votre serveur.
  • Limitez le nombre de SMS qu'un même utilisateur peut déclencher (par exemple pour les codes de vérification), afin d'éviter les abus.
  • Utilisez des clés distinctes par environnement et révoquez immédiatement une clé compromise.

Pour aller plus loin

Les mêmes exemples existent en PHP et en Python. La documentation de l'API détaille tous les champs, réponses et règles de remboursement.

Tous les articles

Prêt à envoyer vos premiers SMS professionnels ?

Créez votre compte gratuitement, importez vos contacts et préparez vos messages. Vous activez l'envoi quand vous êtes prêt.