Init Git Prod Mars 2026

This commit is contained in:
Oleg Barykin committed 2026-03-05 10:25:39 +01:00
commit d81efe93b1
362 files changed
+86627

No files matched your search

+115
View File
@@ -0,0 +1,115 @@
<?php
// /sms/wa_client.php
declare(strict_types=1);
namespace Sms;
final class WaClient
{
private string $phoneId;
private string $token;
private int $timeout;
public function __construct(array $cfg)
{
$this->phoneId = $cfg['phone_number_id'] ?? '';
$this->token = $cfg['access_token'] ?? '';
$this->timeout = (int)($cfg['timeout'] ?? 20);
if ($this->phoneId === '' || $this->token === '') {
throw new \RuntimeException('Config WhatsApp incomplète: phone_number_id / access_token manquants.');
}
}
/** Normalise en format international chiffres-only (WhatsApp: pas de "+") */
public static function normalizePhone(string $raw): string
{
$n = preg_replace('/\D+/', '', $raw ?? '');
// Ex: numéro FR commençant par 0 -> remplace 0 initial par 33
if (preg_match('/^0\d{9}$/', $n)) {
$n = '33' . substr($n, 1);
}
return $n;
}
/**
* Envoi d’un template Utility.
* $templateName: ex. 'notification_rdv'
* $lang: 'ru' (ou celui déclaré/validé chez Meta)
* $to: numéro destinataire (06..., +33..., 336..., etc.)
* $bodyParams: tableau des valeurs pour {{1}}, {{2}}, ...
*/
public function sendTemplate(string $templateName, string $lang, string $to, array $bodyParams, ?array $buttonUrlParams = null): array
{
$toNorm = self::normalizePhone($to);
if ($toNorm === '' || strlen($toNorm) < 8) {
throw new \InvalidArgumentException('Numéro destinataire invalide.');
}
// BODY params
$components = [[
'type' => 'body',
'parameters' => array_map(fn($t) => ['type'=>'text','text'=>(string)$t], $bodyParams)
]];
// BUTTON URL params (facultatif)
// $buttonUrlParams attendu sous la forme: ['0' => ['123']] // index "0" => [ valeurs pour {{1}}, {{2}} si existait ]
if ($buttonUrlParams) {
foreach ($buttonUrlParams as $index => $values) {
$params = array_map(fn($t) => ['type'=>'text','text'=>(string)$t], (array)$values);
$components[] = [
'type' => 'button',
'sub_type' => 'url',
'index' => (string)$index,
'parameters' => $params,
];
}
}
$payload = [
'messaging_product' => 'whatsapp',
'to' => $toNorm,
'type' => 'template',
'template' => [
'name' => $templateName,
'language' => ['code' => $lang],
'components' => $components,
]
];
$json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$ch = curl_init("https://graph.facebook.com/v23.0/{$this->phoneId}/messages");
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => [
"Authorization: Bearer {$this->token}",
"Content-Type: application/json",
"Accept: application/json",
"Expect:",
"Connection: close",
],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
]);
$resp = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$err = curl_error($ch);
curl_close($ch);
$data = json_decode($resp ?? '', true);
return [
'http_code' => $code,
'error' => $err ?: null,
'response' => $data ?? $resp,
'payload' => $payload,
];
}
}