Skip to content

Instantly share code, notes, and snippets.

@md-riaz
Created May 19, 2024 04:24
Show Gist options
  • Save md-riaz/fc0143c68eb3f25e7256042d0e169ad7 to your computer and use it in GitHub Desktop.
Save md-riaz/fc0143c68eb3f25e7256042d0e169ad7 to your computer and use it in GitHub Desktop.
<?php
class WhatsappClass
{
private $phoneNumberId;
private $accessToken;
private $url;
/**
* @param string $phoneNumberId
* @param string $accessToken
* @param string $version
* @throws Exception
*/
public function __construct(string $phoneNumberId, string $accessToken, string $version = "v19.0")
{
if (empty($phoneNumberId) || empty($accessToken)) {
throw new Exception('phone_number_id and access_token are required');
}
$this->phoneNumberId = $phoneNumberId;
$this->accessToken = $accessToken;
$this->url = "https://graph.facebook.com/{$version}/{$this->phoneNumberId}/messages";
}
/**
* @param string $url
* @param array $data
* @return mixed
* @throws Exception
*/
private function sendRequest(string $url, array $data)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $this->accessToken,
'Accept: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode >= 400) {
throw new Exception("HTTP Error: $httpCode - Response: $response");
}
if (curl_errno($ch)) {
throw new Exception('Curl error: ' . curl_error($ch));
}
curl_close($ch);
return json_decode($response, true);
}
/**
* @param string $message
* @param string $recipientId
* @param string $recipientType
* @param bool $previewUrl
* @return mixed
* @throws Exception
*/
public function sendMessage(
string $message,
string $recipientId,
string $recipientType = "individual",
bool $previewUrl = true
) {
$data = [
"messaging_product" => "whatsapp",
"recipient_type" => $recipientType,
"to" => $recipientId,
"type" => "text",
"text" => ["preview_url" => $previewUrl, "body" => $message],
];
return $this->sendRequest($this->url, $data);
}
/**
* @param string $template
* @param string $recipientId
* @param string $lang
* @param array $parameters
* @return mixed
* @throws Exception
*/
public function sendTemplate(string $template, string $recipientId, string $lang = "en_US", array $parameters = [])
{
$templateData = ["name" => $template, "language" => ["code" => $lang]];
if (!empty($parameters)) {
$templateData["components"] = [["type" => "body", "parameters" => $this->buildParameters($parameters)]];
}
$data = [
"messaging_product" => "whatsapp",
"to" => $recipientId,
"type" => "template",
"template" => $templateData,
];
return $this->sendRequest($this->url, $data);
}
/**
* @param string $lat
* @param string $long
* @param string $name
* @param string $address
* @param string $recipientId
* @return mixed
* @throws Exception
*/
public function sendLocation(string $lat, string $long, string $name, string $address, string $recipientId)
{
$data = [
"messaging_product" => "whatsapp",
"to" => $recipientId,
"type" => "location",
"location" => [
"latitude" => $lat,
"longitude" => $long,
"name" => $name,
"address" => $address,
],
];
return $this->sendRequest($this->url, $data);
}
/**
* @param string $image
* @param string $recipientId
* @param string $recipientType
* @param string|null $caption
* @param bool $link
* @return mixed
* @throws Exception
*/
public function sendImage($image, $recipientId, string $recipientType = "individual", $caption = null, $link = true)
{
$imageData = $link ? ["link" => $image, "caption" => $caption] : ["id" => $image, "caption" => $caption];
$data = [
"messaging_product" => "whatsapp",
"recipient_type" => $recipientType,
"to" => $recipientId,
"type" => "image",
"image" => $imageData,
];
return $this->sendRequest($this->url, $data);
}
/**
* @param string $audio
* @param string $recipientId
* @param bool $link
* @return mixed
* @throws Exception
*/
public function sendAudio($audio, $recipientId, $link = true)
{
$audioData = $link ? ["link" => $audio] : ["id" => $audio];
$data = [
"messaging_product" => "whatsapp",
"to" => $recipientId,
"type" => "audio",
"audio" => $audioData,
];
return $this->sendRequest($this->url, $data);
}
/**
* @param string $video
* @param string $recipientId
* @param string|null $caption
* @param bool $link
* @return mixed
* @throws Exception
*/
public function sendVideo($video, $recipientId, $caption = null, $link = true)
{
$videoData = $link ? ["link" => $video, "caption" => $caption] : ["id" => $video, "caption" => $caption];
$data = [
'messaging_product' => 'whatsapp',
'to' => $recipientId,
'type' => 'video',
'video' => $videoData,
];
return $this->sendRequest($this->url, $data);
}
/**
* @param string $document
* @param string $recipientId
* @param string|null $caption
* @param bool $link
* @return mixed
* @throws Exception
*/
public function sendDocument($document, $recipientId, $caption = null, $link = true)
{
$documentData = $link ? ["link" => $document, "caption" => $caption] : ["id" => $document, "caption" => $caption];
$data = [
"messaging_product" => "whatsapp",
"to" => $recipientId,
"type" => "document",
"document" => $documentData,
];
return $this->sendRequest($this->url, $data);
}
/**
* @param array $button
* @return array
*/
public function createButton(array $button)
{
return [
"type" => "list",
"header" => ["type" => "text", "text" => $button["header"]],
"body" => ["text" => $button["body"]],
"footer" => ["text" => $button["footer"]],
"action" => $button["action"],
];
}
/**
* @param array $button
* @param string $recipientId
* @return mixed
* @throws Exception
*/
public function sendButton(array $button, string $recipientId)
{
$data = [
"messaging_product" => "whatsapp",
"to" => $recipientId,
"type" => "interactive",
"interactive" => $this->createButton($button),
];
return $this->sendRequest($this->url, $data);
}
/**
* @param array $data
* @return mixed
*/
public function preprocess(array $data)
{
return $data["entry"][0]["changes"][0]["value"];
}
/**
* @param array $data
* @return mixed|null
*/
public function getMobile(array $data)
{
$data = $this->preprocess($data);
return $data["contacts"][0]["wa_id"] ?? null;
}
/**
* @param array $data
* @return mixed|null
*/
public function getName(array $data)
{
$contact = $this->preprocess($data);
return $contact["contacts"][0]["profile"]["name"] ?? null;
}
/**
* @param array $data
* @return mixed|null
*/
public function getMessage(array $data)
{
$data = $this->preprocess($data);
return $data["messages"][0]["text"]["body"] ?? null;
}
/**
* @param array $data
* @return mixed|null
*/
public function getMessageId(array $data)
{
$data = $this->preprocess($data);
return $data["messages"][0]["id"] ?? null;
}
/**
* @param array $data
* @return mixed|null
*/
public function getMessageTimestamp(array $data)
{
$data = $this->preprocess($data);
return $data["messages"][0]["timestamp"] ?? null;
}
/**
* @param array $data
* @return mixed|null
*/
public function getInteractiveResponse(array $data)
{
$data = $this->preprocess($data);
return $data["messages"][0]["interactive"]["list_reply"] ?? null;
}
/**
* @param array $data
* @return mixed|null
*/
public function getMessageType(array $data)
{
$data = $this->preprocess($data);
return $data["messages"][0]["type"] ?? null;
}
/**
* @param array $data
* @return mixed|null
*/
public function getDelivery(array $data)
{
$data = $this->preprocess($data);
return $data["statuses"][0]["status"] ?? null;
}
/**
* @param array $data
* @return string
*/
public function changedField(array $data)
{
return $data["entry"][0]["changes"][0]["field"];
}
/**
* Build Parameters for Template Message
*
* @param array $params
* @return array
*/
public function buildParameters(array $params)
{
$parameters = [];
foreach ($params as $param) {
if (isset($param['type'])) {
$parameters[] = $param;
} else {
$parameters[] = [
'type' => 'text',
'text' => $param,
];
}
}
return $parameters;
}
}
/**
* Download media from WhatsApp
* @param string $mediaId
* @return string
* @throws Exception
*/
private function downloadMedia(string $mediaId)
{
$mediaUrl = "https://graph.facebook.com/v19.0/{$mediaId}";
$ch = curl_init($mediaUrl);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $this->accessToken,
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode >= 400) {
throw new Exception("HTTP Error: $httpCode - Response: $response");
}
if (curl_errno($ch)) {
throw new Exception('Curl error: ' . curl_error($ch));
}
curl_close($ch);
$responseArray = json_decode($response, true);
return $responseArray['url'] ?? '';
}
/**
* Save media content to database
* @param string $url
* @return string Path to the saved file
* @throws Exception
*/
private function saveMediaToDatabase(string $url)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$mediaContent = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode >= 400) {
throw new Exception("HTTP Error: $httpCode - Response: $mediaContent");
}
if (curl_errno($ch)) {
throw new Exception('Curl error: ' . curl_error($ch));
}
curl_close($ch);
// Save media to database or filesystem
// Assuming we save it to the filesystem for this example
$filePath = 'path/to/save/' . basename($url);
file_put_contents($filePath, $mediaContent);
return $filePath;
}
/**
* Handle incoming messages and extract media
* @param array $data
* @throws Exception
*/
public function handleIncomingMessage(array $data)
{
$messageData = $this->preprocess($data);
foreach ($messageData["messages"] as $message) {
if (isset($message["image"])) {
$mediaUrl = $this->downloadMedia($message["image"]["id"]);
$savedPath = $this->saveMediaToDatabase($mediaUrl);
// Save the file path to your database here
} elseif (isset($message["document"])) {
$mediaUrl = $this->downloadMedia($message["document"]["id"]);
$savedPath = $this->saveMediaToDatabase($mediaUrl);
// Save the file path to your database here
}
// Handle other media types similarly
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment