| Current Path : /home/users/unlimited/www/whatsapp-crm/app/Services/ |
| Current File : /home/users/unlimited/www/whatsapp-crm/app/Services/WhatsappService.php |
<?php
namespace App\Services;
use App\Events\NewChatEvent;
use App\Helpers\WebhookHelper;
use App\Models\Campaign;
use App\Models\Chat;
use App\Models\ChatLog;
use App\Models\ChatMedia;
use App\Models\Contact;
use App\Models\Organization;
use App\Models\Setting;
use App\Models\Template;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Session;
class WhatsappService
{
private $accessToken;
private $apiVersion;
private $appId;
private $phoneNumberId;
private $organizationId;
private $wabaId;
public function __construct($accessToken, $apiVersion, $appId, $phoneNumberId, $wabaId, $organizationId)
{
$this->accessToken = $accessToken;
$this->apiVersion = $apiVersion;
$this->appId = $appId;
$this->phoneNumberId = $phoneNumberId;
$this->wabaId = $wabaId;
$this->organizationId = $organizationId;
Config::set('broadcasting.connections.pusher', [
'driver' => 'pusher',
'key' => Setting::where('key', 'pusher_app_key')->first()->value,
'secret' => Setting::where('key', 'pusher_app_secret')->first()->value,
'app_id' => Setting::where('key', 'pusher_app_id')->first()->value,
'options' => [
'cluster' => Setting::where('key', 'pusher_app_cluster')->first()->value,
],
]);
}
/**
* This function sends a text message via a POST request to the specified phone number using Facebook's messaging API.
*
* @param string $phoneNumber The phone number of the recipient.
* @param string $messageContent The content of the message to be sent.
* @return mixed Returns the response from the HTTP request.
*/
public function sendMessage($contactUuId, $messageContent, $type="text", $buttons = [], $header = [], $footer = null, $buttonLabel = null)
{
$contact = Contact::where('uuid', $contactUuId)->first();
$url = "https://graph.facebook.com/{$this->apiVersion}/{$this->phoneNumberId}/messages";
$headers = $this->setHeaders();
$requestData['messaging_product'] = 'whatsapp';
$requestData['recipient_type'] = 'individual';
$requestData['to'] = $contact->phone;
if($type == "text"){
$requestData['type'] = 'text';
$requestData['text']['preview_url'] = true; //If you have added url either http or https a preview will be displayed
$requestData['text']['body'] = clean($messageContent);
} else if($type == "interactive buttons" || $type == "interactive call to action url" || $type == "interactive list"){
$requestData['type'] = 'interactive';
if($type == "interactive buttons"){
$requestData['interactive']['type'] = 'button';
} else if($type == "interactive call to action url"){
$requestData['interactive']['type'] = 'cta_url';
} else if($type == "interactive list"){
$requestData['interactive']['type'] = 'list';
}
if($type == "interactive buttons"){
foreach($buttons as $button){
$requestData['interactive']['action']['buttons'][] = [
'type' => 'reply',
'reply' => [
'id' => $button['id'],
'title' => $button['title'],
],
];
}
} else if($type == "interactive call to action url"){
$requestData['interactive']['action']['name'] = "cta_url";
$requestData['interactive']['action']['parameters'] = $buttons;
} else if($type == "interactive list"){
$requestData['interactive']['action']['sections'] = $buttons;
$requestData['interactive']['action']['button'] = $buttonLabel;
}
if (!empty($header)) {
$requestData['interactive']['header'] = $header;
}
$requestData['interactive']['body']['text'] = clean($messageContent);
if ($footer != null) {
$requestData['interactive']['footer'] = [
'text' => clean($footer),
];
}
}
$responseObject = $this->sendHttpRequest('POST', $url, $requestData, $headers);
if($responseObject->success === true){
$response['text']['body'] = clean($messageContent);
$response['type'] = 'text';
$chat = Chat::create([
'organization_id' => $contact->organization_id,
'wam_id' => $responseObject->data->messages[0]->id,
'contact_id' => $contact->id,
'type' => 'outbound',
'metadata' => json_encode($response),
'status' => 'delivered',
]);
$chat = Chat::with('contact','media')->where('id', $chat->id)->first();
$responseObject->data->chat = $chat;
$chatlogId = ChatLog::insertGetId([
'contact_id' => $contact->id,
'entity_type' => 'chat',
'entity_id' => $chat->id,
'created_at' => now()
]);
$chatLogArray = ChatLog::where('id', $chatlogId)->where('deleted_at', null)->first();
$chatArray = array([
'type' => 'chat',
'value' => $chatLogArray->relatedEntities
]);
event(new NewChatEvent($chatArray, $contact->organization_id));
}
// Trigger webhook
WebhookHelper::triggerWebhookEvent('message.sent', [
'data' => $responseObject,
], $contact->organization_id);
return $responseObject;
}
/**
* This function sends a text message via a POST request to the specified phone number using Facebook's messaging API.
*
* @param string $phoneNumber The phone number of the recipient.
* @param string $messageContent The content of the message to be sent.
* @return mixed Returns the response from the HTTP request.
*/
public function sendTemplateMessage($contactUuId, $templateContent, $campaignId = NULL, $mediaId = NULL)
{
$contact = Contact::where('uuid', $contactUuId)->first();
$url = "https://graph.facebook.com/{$this->apiVersion}/{$this->phoneNumberId}/messages";
$headers = $this->setHeaders();
$requestData['messaging_product'] = 'whatsapp';
$requestData['recipient_type'] = 'individual';
$requestData['to'] = $contact->phone;
$requestData['type'] = 'template';
$requestData['template'] = $templateContent;
$responseObject = $this->sendHttpRequest('POST', $url, $requestData, $headers);
if($responseObject->success === true){
if($campaignId != NULL){
$campaign = Campaign::where('id', $campaignId)->first();
$templateMetadata = json_decode($campaign->metadata);
}
$chat = Chat::create([
'organization_id' => $contact->organization_id,
'wam_id' => $responseObject->data->messages[0]->id,
'contact_id' => $contact->id,
'type' => 'outbound',
'metadata' => $campaignId != NULL ? $this->buildCampaignTemplateChatMessage($templateMetadata, $contactUuId) : $this->buildTemplateChatMessage($templateContent, $contact),
'media_id' => $campaignId != NULL ? $this->getMediaIdFromCampaign($campaignId) : $mediaId,
'status' => $responseObject->data->messages[0]->message_status,
'created_at' => now()
]);
$responseObject->data->chat = $chat;
$chatlogId = ChatLog::insertGetId([
'contact_id' => $contact->id,
'entity_type' => 'chat',
'entity_id' => $chat->id,
'created_at' => now()
]);
$chatLogArray = ChatLog::where('id', $chatlogId)->where('deleted_at', null)->first();
$chatArray = array([
'type' => 'chat',
'value' => $chatLogArray->relatedEntities
]);
event(new NewChatEvent($chatArray, $contact->organization_id));
}
// Trigger webhook
WebhookHelper::triggerWebhookEvent('message.sent', [
'data' => $responseObject,
], $contact->organization_id);
return $responseObject;
}
private function getMediaIdFromCampaign($campaignId){
$campaign = Campaign::where('id', $campaignId)->first();
$templateMetadata = json_decode($campaign->metadata);
$mediaId = null;
if(isset($templateMetadata->media)){
$mediaId = $templateMetadata->media;
}
return $mediaId;
}
private function buildCampaignTemplateChatMessage($templateMetadata, $contactUuId){
$contact = Contact::where('uuid', $contactUuId)->first();
$array = [];
if($templateMetadata->header->format == 'IMAGE' || $templateMetadata->header->format == 'VIDEO' || $templateMetadata->header->format == 'DOCUMENT' || $templateMetadata->header->format == 'LOCATION'){
$array['type'] = strtolower($templateMetadata->header->format);
} else {
$array['type'] = 'text';
}
//BODY
if(isset($templateMetadata->body->text)){
$bodyText = $templateMetadata->body->text;
if (isset($templateMetadata->body->parameters) && !empty($templateMetadata->body->parameters)) {
$bodyParameters = $templateMetadata->body->parameters;
if($bodyParameters && count($bodyParameters) > 1){
foreach($bodyParameters as $index => $parameter){
$placeholder = '{{' . ($index + 1) . '}}';
$value = $parameter->selection === 'static' ? $parameter->value : $this->getParameters($contact, $parameter->value);
$bodyText = str_replace($placeholder, $value, $bodyText);
}
}
}
if($array['type'] == 'text'){
$array[$array['type']]['body'] = $bodyText;
} else {
$array[$array['type']]['caption'] = $bodyText;
}
}
//FOOTER
if(isset($templateMetadata->footer->text)){
$array[$array['type']]['footer'] = $templateMetadata->footer->text;
}
//BUTTONS
if(isset($templateMetadata->buttons)){
foreach($templateMetadata->buttons as $key => $button){
$array['buttons'][$key]['type'] = $button->type;
$array['buttons'][$key]['text'] = $button->text;
$array['buttons'][$key]['value'] = $button->value;
if(isset($button->parameters)){
$array['buttons'][$key]['parameters'] = $button->parameters;
}
}
}
//dd(json_encode($array));
return json_encode($array);
}
private function buildTemplateChatMessage($templateContent, $contact){
//Get the template
$template = Template::where('organization_id', $contact->organization_id)
->where('name', $templateContent['name'])
->where('language', $templateContent['language']['code'])
->first();
$template = json_decode($template->metadata);
$templateMetadatas = $template->components;
$array = [];
$array['type'] = 'text';
foreach($templateMetadatas as $templateMetadata){
if($templateMetadata->type == 'HEADER'){
if($templateMetadata->format == 'IMAGE' || $templateMetadata->format == 'VIDEO' || $templateMetadata->format == 'DOCUMENT' || $templateMetadata->format == 'LOCATION'){
$array['type'] = strtolower($templateMetadata->format);
}
}
//BODY
if($templateMetadata->type == 'BODY'){
if(isset($templateMetadata->text)){
$bodyText = $templateMetadata->text;
if (isset($templateMetadata->parameters) && !empty($templateMetadata->parameters)) {
$bodyParameters = $templateMetadata->parameters;
if($bodyParameters && count($bodyParameters) > 1){
foreach($bodyParameters as $index => $parameter){
$placeholder = '{{' . ($index + 1) . '}}';
$value = $parameter->selection === 'static' ? $parameter->value : $this->getParameters($contact, $parameter->value);
$bodyText = str_replace($placeholder, $value, $bodyText);
}
}
}
if($array['type'] == 'text'){
$array[$array['type']]['body'] = $bodyText;
} else {
$array[$array['type']]['caption'] = $bodyText;
}
}
}
//FOOTER
if($templateMetadata->type == 'FOOTER'){
$array[$array['type']]['footer'] = $templateMetadata->text;
}
//BUTTONS
if($templateMetadata->type == 'BUTTONS'){
foreach($templateMetadata->buttons as $key => $button){
$array['buttons'][$key]['type'] = $button->type;
$array['buttons'][$key]['text'] = $button->text;
$array['buttons'][$key]['value'] = $button->text;
if(isset($button->parameters)){
$array['buttons'][$key]['parameters'] = $button->parameters;
}
}
}
}
//dd(json_encode($array));
return json_encode($array);
}
private function getParameters($contact, $parameter){
if($parameter === 'first name'){
return $contact->first_name;
} else if($parameter === 'last name'){
return $contact->last_name;
} else if($parameter === 'name'){
return $contact->first_name . ' ' . $contact->last_name;
} else if($parameter === 'email'){
return $contact->email;
} else if($parameter === 'phone'){
return $contact->phone;
}
}
/**
* This function sends media content via a POST request and uploads the media to Facebook's resumable API.
* Note that media types can only be audio, document, image, sticker, or video.
*
* @param string $phoneNumber The phone number of the recipient.
* @param string $mediaType The type of media being uploaded. Valid options are audio, document, image, sticker, or video.
* @param string $mediaFile The file to be uploaded as media.
* @return mixed Returns the response from the HTTP request.
*/
/*public function sendMedia($contactUuid, $mediaType, $mediaFile)
{
$contact = Contact::where('uuid', $contactUuId)->first();
$mediaFilePath = Storage::path("media/{$mediaFileName}");
$fileUploadResponse = $this->initiateResumableUploadSession($mediaFilePath);
if(!$fileUploadResponse->success){
return $fileUploadResponse;
}
$url = "https://graph.facebook.com/{$this->apiVersion}/{$this->phoneNumberId}/messages";
$headers = $this->setHeaders();
$requestData['messaging_product'] = 'whatsapp';
$requestData['recipient_type'] = 'individual';
$requestData['to'] = $contact->phone;
$requestData['type'] = $mediaType;
$requestData[$mediaType]['id'] = $fileUploadResponse->data->h;
$responseObject = $this->sendHttpRequest('POST', $url, $requestData, $headers);
dd($responseObject);
}*/
/**
* This function sends a stored image as a media file via a POST request to the specified phone number using Facebook's messaging API.
*
* @param string $contactUuId The UUID of the contact to whom the image will be sent.
* @param string $imageUrl The URL of the stored image.
* @return mixed Returns the response from the HTTP request.
*/
public function sendMedia($contactUuId, $mediaType, $mediaFileName, $mediaFilePath, $mediaUrl, $location, $caption = NULL)
{
$contact = Contact::where('uuid', $contactUuId)->first();
$url = "https://graph.facebook.com/{$this->apiVersion}/{$this->phoneNumberId}/messages";
$headers = $this->setHeaders();
$requestData['messaging_product'] = 'whatsapp';
$requestData['recipient_type'] = 'individual';
$requestData['to'] = $contact->phone;
$requestData['type'] = $mediaType;
$requestData[$mediaType]['link'] = $mediaUrl;
if($caption != NULL){
$requestData[$mediaType]['caption'] = $caption;
}
$responseObject = $this->sendHttpRequest('POST', $url, $requestData, $headers);
//Log::info(json_encode($responseObject));
if($responseObject->success === true){
//Log::info($mediaUrl);
$wamId = $responseObject->data->messages[0]->id;
$contentType = $this->getContentTypeFromUrl($mediaUrl);
$mediaData = $this->formatMediaResponse($wamId, $mediaUrl, $mediaType, $contentType);
$mediaSize = $this->getMediaSizeInBytesFromUrl($mediaUrl);
$chat = Chat::create([
'organization_id' => $contact->organization_id,
'wam_id' => $wamId,
'contact_id' => $contact->id,
'type' => 'outbound',
'metadata' => json_encode($mediaData),
'status' => 'sent'
]);
$chatlogId = ChatLog::insertGetId([
'contact_id' => $contact->id,
'entity_type' => 'chat',
'entity_id' => $chat->id,
'created_at' => now()
]);
$media = ChatMedia::create([
'name' => $mediaFileName,
'path' => $mediaUrl,
'location' => $location,
'type' => $contentType,
'size' => $mediaSize,
]);
Chat::where('id', $chat->id)->update([
'media_id' => $media->id
]);
$chat = Chat::with('contact','media')->where('id', $chat->id)->first();
$responseObject->data->chat = $chat;
$chatLogArray = ChatLog::where('id', $chatlogId)->where('deleted_at', null)->first();
$chatArray = array([
'type' => 'chat',
'value' => $chatLogArray->relatedEntities
]);
event(new NewChatEvent($chatArray, $contact->organization_id));
}
// Trigger webhook
WebhookHelper::triggerWebhookEvent('message.sent', [
'data' => $responseObject,
], $contact->organization_id);
return $responseObject;
}
function getContentTypeFromUrl($url) {
try {
// Make a HEAD request to fetch headers only
$response = Http::head($url);
// Check if the Content-Type header is present
if ($response->hasHeader('Content-Type')) {
return $response->header('Content-Type');
}
return null;
} catch (\Exception $e) {
// Log the error for debugging
Log::error('Error fetching headers: ' . $e->getMessage());
return null;
}
}
function formatMediaResponse($wamId, $mediaUrl, $mediaType, $contentType){
return [
"id" => $wamId,
"type" => $mediaType,
$mediaType => [
"mime_type" => $contentType,
]
];
}
function getMediaSizeInBytesFromUrl($url) {
$imageContent = file_get_contents($url);
if ($imageContent !== false) {
return strlen($imageContent);
}
return null;
}
/**
* This function allows you to react to a specific message with an emoji via a POST request to Facebook's messaging API.
*
* @param string $phoneNumber The phone number of the recipient.
* @param string $wamId The ID of the message you want to react to.
* @param string $emoji The emoji you want to use as a reaction.
* @return mixed Returns the response from the HTTP request.
*/
public function reactToMessage($phoneNumber, $wamId, $emoji)
{
$url = "https://graph.facebook.com/{$this->apiVersion}/{$this->phoneNumberId}/messages";
$headers = $this->setHeaders();
$requestData['messaging_product'] = 'whatsapp';
$requestData['recipient_type'] = 'individual';
$requestData['to'] = $phoneNumber;
$requestData['type'] = 'reaction';
$requestData['reaction']['message_id'] = $wamId;
$requestData['reaction']['emoji'] = $emoji;
$responseObject = $this->sendHttpRequest('POST', $url, $requestData, $headers);
dd($responseObject);
}
/**
* This function sends a location to a specific phone number via a POST request using Facebook's messaging API.
*
* @param string $phoneNumber The phone number of the recipient.
* @param object $location The location object containing longitude, latitude, name, and address.
* @return mixed Returns the response from the HTTP request.
*/
public function sendLocation($phoneNumber, $location)
{
$url = "https://graph.facebook.com/{$this->apiVersion}/{$this->phoneNumberId}/messages";
$headers = $this->setHeaders();
$requestData['messaging_product'] = 'whatsapp';
$requestData['to'] = $phoneNumber;
$requestData['type'] = 'location';
$requestData['location']['longitude'] = $location->longitude;
$requestData['location']['latitude'] = $location->latitude;
$requestData['location']['name'] = $location->name;
$requestData['location']['address'] = $location->address;
$responseObject = $this->sendHttpRequest('POST', $url, $requestData, $headers);
dd($responseObject);
}
public function createTemplate(Request $request)
{
$url = "https://graph.facebook.com/{$this->apiVersion}/{$this->wabaId}/message_templates";
$requestData = [
"name" => $request->name,
"language" => $request->language,
"category" => $request->category,
];
if($request->header['format'] === 'TEXT'){
if(isset($request->header['text'])){
$headerComponent = [];
$headerComponent['type'] = "HEADER";
$headerComponent['format'] = $request->header['format'];
$headerComponent['text'] = $request->header['text'];
if (!empty($request->header['example'])) {
$headerComponent['example']['header_text'] = $request->header['example'];
}
$requestData['components'][] = $headerComponent;
}
}
if(($request->header['format'] === 'IMAGE' || $request->header['format'] === 'VIDEO' || $request->header['format'] === 'DOCUMENT')){
if(isset($request->header['example'])){
$fileUploadResponse = $this->initiateResumableUploadSession($request->header['example']);
if(!$fileUploadResponse->success){
return $fileUploadResponse;
}
$requestData['components'][] = [
"type" => "HEADER",
"format" => $request->header['format'],
"example" => [
"header_handle" => [
$fileUploadResponse->data->h
]
]
];
}
}
if($request->body['text'] != null){
$bodyComponent = [];
$bodyComponent['type'] = "BODY";
$bodyComponent['text'] = $request->body['text'];
if (!empty($request->body['example'])) {
$bodyComponent['example']['body_text'][] = $request->body['example'];
}
$requestData['components'][] = $bodyComponent;
}
if ($request->has('footer')) {
if($request->footer['text'] != null){
$requestData['components'][] = [
"type" => "FOOTER",
"text" => $request->footer['text']
];
}
}
if ($request->has('buttons')) {
if (!isset($requestData['components'])) {
$requestData['components'] = [];
}
$requestData['components'][] = [
'type' => 'BUTTONS',
'buttons' => []
];
$quickReplyButtons = [];
foreach ($request->buttons as $button) {
if ($button['type'] === 'QUICK_REPLY') {
$quickReplyButtons[] = [
'type' => $button['type'],
'text' => $button['text'],
];
}
}
foreach ($request->buttons as $button) {
if ($button['type'] !== 'QUICK_REPLY') {
if ($button['type'] === 'URL') {
$requestData['components'][count($requestData['components']) - 1]['buttons'][] = [
'type' => $button['type'],
'text' => $button['text'],
'url' => $button['url'],
];
} elseif ($button['type'] === 'PHONE_NUMBER') {
$requestData['components'][count($requestData['components']) - 1]['buttons'][] = [
'type' => $button['type'],
'text' => $button['text'],
'phone_number' => $button['country'].$button['phone_number'],
];
} elseif ($button['type'] === 'COPY_CODE') {
$requestData['components'][count($requestData['components']) - 1]['buttons'][] = [
'type' => $button['type'],
'example' => $button['example'],
];
}
}
}
// Add the quick reply buttons at the start
if (!empty($quickReplyButtons)) {
$requestData['components'][count($requestData['components']) - 1]['buttons'] = array_merge($quickReplyButtons, $requestData['components'][count($requestData['components']) - 1]['buttons']);
}
}
$client = new Client();
$responseObject = new \stdClass();
try {
$response = $client->post($url, [
'headers' => [
'Authorization' => 'Bearer ' . $this->accessToken,
'Content-Type' => 'application/json',
],
'json' => $requestData,
]);
$responseObject->success = true;
$responseObject->data = json_decode($response->getBody()->getContents());
//Save Template To Database
$template = new Template();
$template->organization_id = session()->get('current_organization');
$template->meta_id = $responseObject->data->id;
$template->name = $request->name;
$template->category = $request->category;
$template->language = $request->language;
$template->metadata = json_encode($requestData);
$template->status = $responseObject->data->status;
$template->created_by = auth()->user()->id;
$template->created_at = now();
$template->updated_at = now();
$template->save();
} catch (ConnectException $e) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->message = $e->getMessage();
} catch (GuzzleException $e) {
$response = $e->getResponse();
$responseObject->success = false;
$responseObject->data = json_decode($response->getBody()->getContents());
if (isset($responseObject->data->error->error_user_msg)) {
$responseObject->message = $responseObject->data->error->error_user_msg;
} else {
$responseObject->message = $responseObject->data->error->message;
}
} catch (Exception $e) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->message = $e->getMessage();
}
return $responseObject;
}
function syncTemplates()
{
$url = "https://graph.facebook.com/{$this->apiVersion}/{$this->wabaId}/message_templates";
$client = new Client();
$responseObject = new \stdClass();
try {
do {
$response = $client->request('GET', $url, [
'headers' => [
'Authorization' => "OAuth {$this->accessToken}",
],
]);
$responseObject = json_decode($response->getBody()->getContents());
//dd($responseObject);
foreach($responseObject->data as $templateData){
$template = Template::where('organization_id', session()->get('current_organization'))
->where('meta_id', $templateData->id)->first();
if($template){
$template->metadata = json_encode($templateData);
$template->status = $templateData->status;
$template->updated_at = now();
$template->deleted_at = NULL;
$template->save();
} else {
$template = new Template();
$template->organization_id = session()->get('current_organization');
$template->meta_id = $templateData->id;
$template->name = $templateData->name;
$template->category = $templateData->category;
$template->language = $templateData->language;
$template->metadata = json_encode($templateData);
$template->status = $templateData->status;
$template->created_by = auth()->user()->id;
$template->created_at = now();
$template->updated_at = now();
$template->save();
}
};
if(isset($responseObject->paging) && isset($responseObject->paging->next)) {
$url = $responseObject->paging->next;
} else {
$url = null; // Break the loop if no next page URL is available
}
} while($url);
} catch (ConnectException $e) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->message = $e->getMessage();
} catch (GuzzleException $e) {
$response = $e->getResponse();
$responseObject->success = false;
$responseObject->data = json_decode($response->getBody()->getContents());
if (isset($responseObject->data->error->error_user_msg)) {
$responseObject->message = $responseObject->data->error->error_user_msg;
} else {
$responseObject->message = $responseObject->data->error->message;
}
} catch (Exception $e) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->message = $e->getMessage();
}
return $responseObject;
}
/**
* This function deletes a template by its UUID via a DELETE request to Facebook's messaging API.
*
* @param string $uuid The UUID of the template to be deleted.
* @return mixed Returns the response from the HTTP request.
*/
public function deleteTemplate($uuid)
{
$url = "https://graph.facebook.com/{$this->apiVersion}/{$this->wabaId}/message_templates";
$headers = $this->setHeaders();
$template = Template::where('uuid', $uuid)->first();
$requestData['hsm_id'] = $template->meta_id;
$requestData['name'] = $template->name;
$responseObject = $this->sendHttpRequest('DELETE', $url, $requestData, $headers);
if($responseObject->success){
$template->deleted_at = now();
$template->save();
}
return $responseObject;
}
function getMedia($mediaId)
{
$url = "https://graph.facebook.com/{$this->apiVersion}/{$mediaId}";
$headers = $this->setHeaders();
$responseObject = $this->sendHttpRequest('GET', $url, NULL, $headers);
return $responseObject;
}
function checkHealth()
{
$url = "https://graph.facebook.com/{$this->apiVersion}/{$this->wabaId}?fields=health_status";
$headers = $this->setHeaders();
$responseObject = $this->sendHttpRequest('GET', $url, NULL, $headers);
return $responseObject;
}
function subscribeToWaba()
{
$responseObject = new \stdClass();
try {
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $this->accessToken
])->post("https://graph.facebook.com/{$this->apiVersion}/{$this->wabaId}/subscribed_apps")->throw()->json();
$responseObject->success = true;
$responseObject->data = new \stdClass();
$responseObject->data = (object) $response;
} catch (\Exception $e) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->message = $e->getMessage();
}
return $responseObject;
}
function getWabaSubscriptions()
{
$url = "https://graph.facebook.com/{$this->apiVersion}/{$this->wabaId}/subscribed_apps";
$headers = $this->setHeaders();
$responseObject = $this->sendHttpRequest('GET', $url, NULL, $headers);
return $responseObject;
}
function overrideCallbackUrl($callbackUrl, $verifyToken)
{
$responseObject = new \stdClass();
try {
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $this->accessToken
])->post("https://graph.facebook.com/{$this->apiVersion}/{$this->wabaId}/subscribed_apps", [
'override_callback_uri' => $callbackUrl,
'verify_token' => $verifyToken
])->throw()->json();
$responseObject->success = true;
$responseObject->data = new \stdClass();
$responseObject->data = (object) $response;
} catch (\Exception $e) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->message = $e->getMessage();
}
return $responseObject;
}
function unSubscribeToWaba()
{
$url = "https://graph.facebook.com/{$this->apiVersion}/{$this->wabaId}/subscribed_apps";
$headers = $this->setHeaders();
$responseObject = $this->sendHttpRequest('DELETE', $url, NULL, $headers);
return $responseObject;
}
public function getBusinessProfile(){
$responseObject = new \stdClass();
try {
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $this->accessToken
])->get("https://graph.facebook.com/{$this->apiVersion}/{$this->phoneNumberId}/whatsapp_business_profile", [
'fields' => 'about,address,description,email,profile_picture_url,websites,vertical',
])->throw()->json();
if (isset($response['data']['error'])) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->code = $response['data']['error']['code'];
$responseObject->data->error->message = $response['data']['error']['message'];
} else {
$responseObject->success = true;
$responseObject->data = new \stdClass();
$responseObject->data = (object) $response['data'][0];
}
} catch (\Exception $e) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->message = $e->getMessage();
}
return $responseObject;
}
public function updateBusinessProfile(Request $request){
$url = "https://graph.facebook.com/{$this->apiVersion}/{$this->phoneNumberId}/whatsapp_business_profile";
$headers = $this->setHeaders();
$requestData['messaging_product'] = 'whatsapp';
$requestData['about'] = $request->about;
$requestData['address'] = $request->address;
$requestData['description'] = $request->description;
$requestData['vertical'] = $request->industry;
$requestData['email'] = $request->email;
//$requestData['profile_picture_handle'] = $request->profile_picture_handle;
$responseObject = $this->sendHttpRequest('POST', $url, $requestData, $headers);
if($responseObject->success === true){
$organizationConfig = Organization::where('id', $this->organizationId)->first();
$metadataArray = $organizationConfig->metadata ? json_decode($organizationConfig->metadata, true) : [];
$metadataArray['whatsapp']['business_profile']['about'] = $request->about;
$metadataArray['whatsapp']['business_profile']['address'] = $request->address;
$metadataArray['whatsapp']['business_profile']['description'] = $request->description;
$metadataArray['whatsapp']['business_profile']['industry'] = $request->industry;
$metadataArray['whatsapp']['business_profile']['email'] = $request->email;
//$metadataArray['whatsapp']['business_profile']['profile_picture_handle'] = $request->profile_picture_handle;
$updatedMetadataJson = json_encode($metadataArray);
$organizationConfig->metadata = $updatedMetadataJson;
$organizationConfig->save();
}
return $responseObject;
}
public function deRegisterPhone(){
$url = "https://graph.facebook.com/{$this->apiVersion}/{$this->phoneNumberId}/deregister";
$headers = $this->setHeaders();
$responseObject = $this->sendHttpRequest('POST', $url, NULL, $headers);
if($responseObject->success === true){
dd($responseObject);
}
dd($responseObject);
return $responseObject;
}
public function getPhoneNumberId(){
$responseObject = new \stdClass();
try {
$fields = 'display_phone_number,certificate,name_status,new_certificate,new_name_status,verified_name,quality_rating,messaging_limit_tier';
$response = Http::get("https://graph.facebook.com/{$this->apiVersion}/{$this->wabaId}/phone_numbers", [
'fields' => $fields,
'access_token' => $this->accessToken,
])->throw()->json();
if (isset($response['data']['error'])) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->code = $response['data']['error']['code'];
$responseObject->data->error->message = $response['data']['error']['message'];
} else {
$responseObject->success = true;
$responseObject->data = new \stdClass();
$responseObject->data = (object) $response['data'][0];
}
} catch (\Exception $e) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->message = $e->getMessage();
}
return $responseObject;
}
public function getPhoneNumberStatus(){
$responseObject = new \stdClass();
try {
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $this->accessToken
])->get("https://graph.facebook.com/{$this->apiVersion}/{$this->phoneNumberId}", [
'fields' => 'status, code_verification_status , quality_score, health_status',
])->throw()->json();
if (isset($response['data']['error'])) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->code = $response['data']['error']['code'];
$responseObject->data->error->message = $response['data']['error']['message'];
} else {
$responseObject->success = true;
$responseObject->data = new \stdClass();
$responseObject->data = (object) $response;
}
} catch (\Exception $e) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->message = $e->getMessage();
}
return $responseObject;
}
public function getAccountReviewStatus(){
$responseObject = new \stdClass();
try {
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $this->accessToken
])->get("https://graph.facebook.com/{$this->apiVersion}/{$this->wabaId}", [
'fields' => 'account_review_status',
])->throw()->json();
if (isset($response['data']['error'])) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->code = $response['data']['error']['code'];
$responseObject->data->error->message = $response['data']['error']['message'];
} else {
$responseObject->success = true;
$responseObject->data = new \stdClass();
$responseObject->data = (object) $response;
}
} catch (\Exception $e) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->message = $e->getMessage();
}
return $responseObject;
}
function viewMedia($mediaId)
{
$response = $this->getMedia($mediaId);
if(!$response->success){
return $response;
}
$url = $response->data->url;
$headers = $this->setHeaders();
$responseObject = $this->sendHttpRequest('GET', $url, NULL, $headers);
dd($responseObject);
return $responseObject;
}
function initiateResumableUploadSession($file)
{
$sessionResponse = $this->createResumableUploadSession($file);
if(!$sessionResponse->success){
return $sessionResponse;
}
$uploadSessionId = $sessionResponse->data->id;
$fileName = $file->getPathname();
$url = "https://graph.facebook.com/{$this->apiVersion}/{$uploadSessionId}";
$client = new Client();
$responseObject = new \stdClass();
try {
$response = $client->request('POST', $url, [
'headers' => [
'Authorization' => "OAuth {$this->accessToken}",
'file_offset' => 0,
],
'body' => fopen($fileName, 'r'),
'timeout' => 2,
]);
$responseObject->success = true;
$responseObject->data = json_decode($response->getBody()->getContents());
} catch (ConnectException $e) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->message = $e->getMessage();
} catch (GuzzleException $e) {
$response = $e->getResponse();
$responseObject->success = false;
$responseObject->data = json_decode($response->getBody()->getContents());
if (isset($responseObject->data->error->error_user_msg)) {
$responseObject->message = $responseObject->data->error->error_user_msg;
} else {
$responseObject->message = $responseObject->data->error->message;
}
} catch (Exception $e) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->message = $e->getMessage();
}
return $responseObject;
}
function createResumableUploadSession($file)
{
$fileLength = $file->getSize();
$fileType = $file->getMimeType();
$url = "https://graph.facebook.com/{$this->apiVersion}/{$this->appId}/uploads";
$client = new Client();
$responseObject = new \stdClass();
try {
$response = $client->request('POST', $url, [
'form_params' => [
'file_length' => $fileLength,
'file_type' => $fileType,
'access_token' => $this->accessToken,
]
]);
$status = $response->getStatusCode();
$responseObject->success = true;
$responseObject->data = json_decode($response->getBody()->getContents());
} catch (ConnectException $e) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->message = $e->getMessage();
} catch (GuzzleException $e) {
$response = $e->getResponse();
$responseObject->success = false;
$responseObject->data = json_decode($response->getBody()->getContents());
if (isset($responseObject->data->error->error_user_msg)) {
$responseObject->message = $responseObject->data->error->error_user_msg;
} else {
$responseObject->message = $responseObject->data->error->message;
}
} catch (Exception $e) {
$response = $e->getResponse();
$responseObject->success = false;
$responseObject->data = json_decode($response->getBody()->getContents());
}
return $responseObject;
}
//Set the headers for request
public function setHeaders()
{
return [
'Authorization' => 'Bearer ' . $this->accessToken,
'Content-Type' => 'application/json',
];
}
// Private method to send an HTTP request
private function sendHttpRequest($method, $url, $data = [], $headers = [])
{
$client = new Client();
$responseObject = new \stdClass();
try {
$requestOptions = [
'headers' => $headers,
];
if (isset($data) && $method === 'POST' || $method === 'PUT' || $method === 'DELETE') {
$requestOptions['json'] = $data;
}
$response = $client->request($method, $url, $requestOptions);
$responseObject->success = true;
$responseObject->data = json_decode($response->getBody()->getContents());
} catch (ConnectException $e) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->message = $e->getMessage();
} catch (GuzzleException $e) {
$response = $e->getResponse();
$responseObject->success = false;
$responseObject->data = json_decode($response->getBody()->getContents());
if (isset($responseObject->data->error->error_user_msg)) {
$responseObject->message = $responseObject->data->error->error_user_msg;
} else {
$responseObject->message = $responseObject->data->error->message;
}
} catch (Exception $e) {
$responseObject->success = false;
$responseObject->data = new \stdClass();
$responseObject->data->error = new \stdClass();
$responseObject->data->error->message = $e->getMessage();
}
return $responseObject;
}
}