Numéros de téléphone ivoiriens : formats, préfixes et validation pour développeurs
Un numéro mal formaté est le premier motif d'échec d'un envoi. Voici les formats à accepter, comment les normaliser et reconnaître l'opérateur.
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.
SMSGOLD_API_KEY (fichier .env chargé avec node --env-file=.env depuis Node.js 20, ou dotenv).// 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.
// 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.
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é.
sender_name non approuvé pour votre compte.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.
Un numéro mal formaté est le premier motif d'échec d'un envoi. Voici les formats à accepter, comment les normaliser et reconnaître l'opérateur.
Du premier SMS envoyé avec cURL à une classe réutilisable et un service Laravel, avec une gestion propre des erreurs.
Un SMS en quelques lignes avec requests, puis une fonction propre, réutilisable dans Django, FastAPI ou vos scripts.
Créez votre compte gratuitement, importez vos contacts et préparez vos messages. Vous activez l'envoi quand vous êtes prêt.