641 lines
15 KiB
PHP
641 lines
15 KiB
PHP
<?php
|
|
|
|
/**
|
|
* KrmPesan PHP SDK.
|
|
*
|
|
* @version 3.5.0
|
|
*
|
|
* @see https://github.com/KrmPesan/SDK-PHP
|
|
*
|
|
* @author KrmPesan <support@krmpesan.com>
|
|
* @copyright 2023 KrmPesan
|
|
*/
|
|
|
|
namespace KrmPesan;
|
|
|
|
use DateTime;
|
|
use DateTimeZone;
|
|
use Exception;
|
|
|
|
/**
|
|
* KrmPesan Client Class For Handle REST API Request.
|
|
*
|
|
* @see https://docs.krmpesan.com/
|
|
*/
|
|
class ClientV3
|
|
{
|
|
/**
|
|
* Default Curl Timeout.
|
|
*
|
|
* @var int
|
|
*
|
|
* @see https://www.php.net/manual/en/function.curl-setopt
|
|
*/
|
|
protected $timeout;
|
|
|
|
/**
|
|
* Default API Url.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $apiUrl = 'https://api.krmpesan.app';
|
|
|
|
/**
|
|
* Default TimeZone For DateTime
|
|
* Example: Asia/Jakarta.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $timezone;
|
|
|
|
/**
|
|
* Store Token to File JSON Format.
|
|
*/
|
|
protected $tokenFile;
|
|
|
|
/**
|
|
* API Token.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $token;
|
|
|
|
/**
|
|
* Refresh Token.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $refreshToken;
|
|
|
|
/**
|
|
* API Token.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $deviceId;
|
|
|
|
/**
|
|
* Token Expired.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $expiredAt;
|
|
|
|
/**
|
|
* Custom Request Header.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $customHeader;
|
|
|
|
/**
|
|
* Construct Function.
|
|
*
|
|
* @param array $data
|
|
*/
|
|
public function __construct(array $data)
|
|
{
|
|
$this->timezone = isset($data['timezone']) ? $data['timezone'] : 'Asia/Jakarta';
|
|
|
|
// Set Token Path
|
|
if (isset($data['tokenFile']) and !empty($data['tokenFile'])) {
|
|
// check path directory is exist
|
|
if (!is_dir($data['tokenFile'])) {
|
|
throw new Exception('Directory not found.');
|
|
}
|
|
|
|
// save path
|
|
$this->tokenFile = $data['tokenFile'] . '/token.json';
|
|
|
|
// load token
|
|
$this->getToken();
|
|
} else {
|
|
// Set Token (optional)
|
|
$this->token = $data['idToken'];
|
|
|
|
// Set DeviceId
|
|
if (!isset($data['deviceId']) or empty($data['deviceId'])) {
|
|
throw new Exception('DeviceId is required.');
|
|
} else {
|
|
$this->deviceId = $data['deviceId'];
|
|
}
|
|
|
|
// Set Refresh Token
|
|
if (!isset($data['refreshToken']) or empty($data['refreshToken'])) {
|
|
throw new Exception('Token is required.');
|
|
} else {
|
|
$this->refreshToken = $data['refreshToken'];
|
|
}
|
|
}
|
|
|
|
// Set Custom Header
|
|
$this->customHeader = $data['headers'] ?? null;
|
|
|
|
// validate token
|
|
$this->validateToken();
|
|
}
|
|
|
|
/**
|
|
* Curl Post or Get Function.
|
|
*
|
|
* @param string $type
|
|
* @param string $url
|
|
* @param array $form
|
|
*/
|
|
private function action($type, $url, $form = null, $file = null)
|
|
{
|
|
// setup url
|
|
$buildUrl = $this->apiUrl . '/' . $url;
|
|
|
|
// set default header
|
|
$headers = [];
|
|
$headers[] = 'Content-Type: application/json';
|
|
$headers[] = 'Authorization: Bearer ' . $this->token;
|
|
|
|
// use custom header if not null
|
|
if ($this->customHeader) {
|
|
$headers = $this->customHeader;
|
|
}
|
|
|
|
// build curl instance
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_URL, $buildUrl);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYSTATUS, false);
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
|
|
if (isset($file)) {
|
|
curl_setopt($ch, CURLOPT_INFILE, fopen($file, 'r'));
|
|
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($file));
|
|
} else {
|
|
$headers[] = 'Content-Type: application/json';
|
|
}
|
|
|
|
if (isset($form)) {
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $form);
|
|
}
|
|
|
|
// check action type
|
|
if ($type == 'POST') {
|
|
curl_setopt($ch, CURLOPT_POST, true);
|
|
} elseif ($type == 'PUT') {
|
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
|
|
} elseif ($type == 'DELETE') {
|
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
|
} else {
|
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
|
|
}
|
|
|
|
// running curl
|
|
$result = curl_exec($ch);
|
|
|
|
// throw error
|
|
if (curl_errno($ch)) {
|
|
throw new Exception(curl_error($ch));
|
|
}
|
|
|
|
// stop connection
|
|
curl_close($ch);
|
|
|
|
// return result request
|
|
return $result;
|
|
}
|
|
|
|
public function request($type, $url, $form = null)
|
|
{
|
|
try {
|
|
$this->validateToken();
|
|
|
|
return $this->action($type, $url, $form);
|
|
} catch (Exception $e) {
|
|
throw new Exception($e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Refresh Token.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function refreshToken()
|
|
{
|
|
$url = 'tokens?refresh_token=' . $this->refreshToken . '&device_key=' . $this->deviceId;
|
|
$response = $this->action('GET', $url);
|
|
$data = json_decode($response, true);
|
|
$this->token = $data['IdToken'];
|
|
|
|
// load token to internal function
|
|
$this->storeToken();
|
|
|
|
return $data;
|
|
}
|
|
|
|
public function getToken()
|
|
{
|
|
if (isset($this->tokenFile) and !empty($this->tokenFile)) {
|
|
$getFile = file_get_contents($this->tokenFile);
|
|
$parseFile = json_decode($getFile, true);
|
|
|
|
$refreshToken = isset($parseFile['refreshToken']) ? $parseFile['refreshToken'] : null;
|
|
$deviceId = isset($parseFile['deviceId']) ? $parseFile['deviceId'] : null;
|
|
$idToken = isset($parseFile['idToken']) ? $parseFile['idToken'] : null;
|
|
$expiredAt = isset($parseFile['expiredAt']) ? $parseFile['expiredAt'] : null;
|
|
|
|
if (!$refreshToken) {
|
|
throw new Exception('refreshToken Not Found at ' . $this->tokenFile);
|
|
}
|
|
|
|
// set refresh token
|
|
$this->refreshToken = $refreshToken;
|
|
|
|
if (!$deviceId) {
|
|
throw new Exception('deviceId Not Found at ' . $this->tokenFile);
|
|
}
|
|
|
|
// set refresh token
|
|
$this->deviceId = $deviceId;
|
|
|
|
if (!$idToken xor !$expiredAt) {
|
|
$this->refreshToken();
|
|
} else {
|
|
$this->token = $idToken;
|
|
$this->expiredAt = $expiredAt;
|
|
}
|
|
}
|
|
|
|
$result = [
|
|
'idToken' => $this->token,
|
|
'refreshToken' => $this->refreshToken,
|
|
'expiredAt' => $this->expiredAt,
|
|
];
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function storeToken()
|
|
{
|
|
if (isset($this->tokenFile) and !empty($this->tokenFile)) {
|
|
try {
|
|
$getFile = file_get_contents($this->tokenFile);
|
|
$parseFile = json_decode($getFile, true);
|
|
|
|
$date = new DateTime('now', new DateTimeZone($this->timezone));
|
|
$date->modify('+1 day');
|
|
$parseFile['idToken'] = $this->token;
|
|
$parseFile['expiredAt'] = $date->format('Y-m-d H:i:s');
|
|
|
|
file_put_contents($this->tokenFile, json_encode($parseFile));
|
|
} catch (Exception $e) {
|
|
throw new Exception('tokenFile Error.!');
|
|
}
|
|
}
|
|
}
|
|
|
|
public function validateToken()
|
|
{
|
|
try {
|
|
$date = new DateTime('now', new DateTimeZone($this->timezone));
|
|
$now = $date->format('Y-m-d H:i:s');
|
|
|
|
if ($now > $this->expiredAt) {
|
|
$this->refreshToken();
|
|
}
|
|
|
|
// success
|
|
} catch (Exception $e) {
|
|
// error
|
|
print_r($e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create Template Message.
|
|
*
|
|
* @param string $name
|
|
* @param string $category UTILLITY, AUTHENTICATION, MARKETING
|
|
* @param string $description
|
|
*/
|
|
public function createTemplate($name, $category, $description)
|
|
{
|
|
// build form
|
|
$form = json_encode([
|
|
'name' => $name,
|
|
'category' => $category,
|
|
'description' => $description,
|
|
]);
|
|
|
|
return $this->request('POST', 'messages/template', $form);
|
|
}
|
|
|
|
/**
|
|
* Create Template Language.
|
|
*
|
|
* @param string $slug
|
|
* @param string $lang en, id
|
|
* @param string $message
|
|
* @param array $fields ["fields-1", "fields-2", "fields-3"]
|
|
* @param array $header [
|
|
* "type" => "image|document",
|
|
* "url" => "https://example.com/image.png"
|
|
* ]
|
|
* @param string $footer
|
|
* @param array $button
|
|
*/
|
|
public function createTemplateLang($slug, $lang, $message, $fields, $header = null, $footer = null, $button = null)
|
|
{
|
|
// build form
|
|
$form = json_encode([
|
|
'slug' => $slug,
|
|
'language' => $lang,
|
|
'message' => $message,
|
|
'fields' => $fields,
|
|
'header' => isset($header) ? $header : null,
|
|
'footer' => isset($footer) ? $footer : null,
|
|
'button' => isset($button) ? $button : null,
|
|
]);
|
|
|
|
return $this->request('POST', 'messages/template/lang', $form);
|
|
}
|
|
|
|
/**
|
|
* Send Message Text Template with Parameter or Without Parameter.
|
|
*
|
|
* @param string|int $to
|
|
* @param string $templateLanguage
|
|
* @param string $templateName
|
|
* @param array|null $body
|
|
*/
|
|
public function sendMessageTemplateText($to, $templateName, $templateLanguage, $body = null)
|
|
{
|
|
// build form
|
|
$form = [
|
|
'phone' => $to,
|
|
'template_name' => $templateName,
|
|
'template_language' => $templateLanguage,
|
|
];
|
|
|
|
// use body if not null
|
|
if (isset($body) or !empty($body)) {
|
|
$form['template'] = (object) [
|
|
'body' => $body,
|
|
];
|
|
}
|
|
|
|
return $this->request('POST', 'messages', json_encode($form));
|
|
}
|
|
|
|
/**
|
|
* Send Message Image.
|
|
*
|
|
* @param string|int $to
|
|
* @param string $templateLanguage
|
|
* @param string $templateName
|
|
* @param array $body
|
|
* @param string $image
|
|
*
|
|
* @return void
|
|
*/
|
|
public function sendMessageTemplateImage($to, $templateName, $templateLanguage, $body, $image)
|
|
{
|
|
// build form
|
|
$form = json_encode([
|
|
'phone' => $to,
|
|
'template_name' => $templateName,
|
|
'template_language' => $templateLanguage,
|
|
'template' => (object) [
|
|
'body' => $body,
|
|
'header' => [
|
|
'type' => 'image',
|
|
'url' => $image,
|
|
],
|
|
],
|
|
]);
|
|
|
|
return $this->request('POST', 'messages', $form);
|
|
}
|
|
|
|
/**
|
|
* Send Message Document.
|
|
*
|
|
* @param string|int $to
|
|
* @param string $templateLanguage
|
|
* @param string $templateName
|
|
* @param array $body
|
|
* @param string $document
|
|
*
|
|
* @return void
|
|
*/
|
|
public function sendMessageTemplateDocument($to, $templateName, $templateLanguage, $body, $document)
|
|
{
|
|
// build form
|
|
$form = json_encode([
|
|
'phone' => $to,
|
|
'template_name' => $templateName,
|
|
'template_language' => $templateLanguage,
|
|
'template' => (object) [
|
|
'body' => $body,
|
|
'header' => [
|
|
'type' => 'document',
|
|
'url' => $document,
|
|
],
|
|
],
|
|
]);
|
|
|
|
return $this->request('POST', 'messages', $form);
|
|
}
|
|
|
|
/**
|
|
* Send Message Button.
|
|
*
|
|
* @param string|int $to
|
|
* @param string $templateLanguage
|
|
* @param string $templateName
|
|
* @param array $body
|
|
* @param string $button
|
|
*
|
|
* @return void
|
|
*/
|
|
public function sendMessageTemplateButton($to, $templateName, $templateLanguage, $body, $button)
|
|
{
|
|
// build form
|
|
$form = json_encode([
|
|
'phone' => $to,
|
|
'template_name' => $templateName,
|
|
'template_language' => $templateLanguage,
|
|
'template' => (object) [
|
|
'body' => $body,
|
|
'buttons' => [
|
|
'url' => $button,
|
|
],
|
|
],
|
|
]);
|
|
|
|
return $this->request('POST', 'messages', $form);
|
|
}
|
|
|
|
/**
|
|
* Send Reply Text.
|
|
*
|
|
* @param string|int $to
|
|
* @param string $text
|
|
*
|
|
* @return void
|
|
*/
|
|
public function sendReplyText($to, $text)
|
|
{
|
|
// build form
|
|
$form = json_encode([
|
|
'phone' => $to,
|
|
'reply' => (object) [
|
|
'type' => 'text',
|
|
'text' => $text,
|
|
],
|
|
]);
|
|
|
|
return $this->request('POST', 'messages', $form);
|
|
}
|
|
|
|
/**
|
|
* Send Reply Image.
|
|
*
|
|
* @param string|int $to
|
|
* @param string $image
|
|
* @param string $caption
|
|
*
|
|
* @return void
|
|
*/
|
|
public function sendReplyImage($to, $image, $caption = '')
|
|
{
|
|
// build form
|
|
$form = json_encode([
|
|
'phone' => $to,
|
|
'reply' => (object) [
|
|
'type' => 'image',
|
|
'image' => $image,
|
|
'caption' => $caption,
|
|
],
|
|
]);
|
|
|
|
return $this->request('POST', 'messages', $form);
|
|
}
|
|
|
|
/**
|
|
* Send Reply document.
|
|
*
|
|
* @param string|int $to
|
|
* @param string $document
|
|
*
|
|
* @return void
|
|
*/
|
|
public function sendReplyDocument($to, $document)
|
|
{
|
|
// build form
|
|
$form = json_encode([
|
|
'phone' => $to,
|
|
'reply' => (object) [
|
|
'type' => 'image',
|
|
'document' => $document,
|
|
],
|
|
]);
|
|
|
|
return $this->request('POST', 'messages', $form);
|
|
}
|
|
|
|
/**
|
|
* Get Device Data.
|
|
*/
|
|
public function getDevice()
|
|
{
|
|
return $this->request('GET', 'devices');
|
|
}
|
|
|
|
/**
|
|
* Get All Messages.
|
|
*/
|
|
public function getMessages()
|
|
{
|
|
return $this->request('GET', 'messages');
|
|
}
|
|
|
|
public function upload($fileData)
|
|
{
|
|
// parse file and get file information
|
|
// https://www.php.net/manual/en/function.realpath
|
|
$file = realpath($fileData);
|
|
// https://www.php.net/manual/en/function.basename
|
|
$filename = basename($file);
|
|
// https://www.php.net/manual/en/function.mime-content-type
|
|
$filemime = mime_content_type($file);
|
|
|
|
$presign = $this->request('POST', 'files/generate', json_encode([
|
|
'filename' => $filename,
|
|
'mime' => $filemime,
|
|
'expired' => 30,
|
|
]));
|
|
|
|
$resp = json_decode($presign, true);
|
|
|
|
if (!isset($resp['data']) and !isset($resp['data']['url'])) {
|
|
throw new Exception('Failed to generate presign url');
|
|
}
|
|
|
|
$url = $resp['data']['url'];
|
|
$urlClean = explode('?', $url)[0];
|
|
|
|
// Create a cURL handle
|
|
$curl = curl_init();
|
|
|
|
// Set the cURL options
|
|
curl_setopt($curl, CURLOPT_URL, $url);
|
|
curl_setopt($curl, CURLOPT_PUT, true);
|
|
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
|
curl_setopt($curl, CURLOPT_SSL_VERIFYSTATUS, false);
|
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($curl, CURLOPT_INFILE, fopen($fileData, 'r'));
|
|
curl_setopt($curl, CURLOPT_INFILESIZE, filesize($fileData));
|
|
curl_setopt($curl, CURLOPT_HTTPHEADER, ["Content-Type: $filemime"]);
|
|
|
|
// Execute the cURL request
|
|
$response = curl_exec($curl);
|
|
|
|
// Check if the request was successful
|
|
if ($response === false) {
|
|
throw new Exception('Error uploading file: ' . curl_error($curl));
|
|
}
|
|
|
|
// Close the cURL handle
|
|
curl_close($curl);
|
|
|
|
return $urlClean;
|
|
}
|
|
|
|
/**
|
|
* Send Message Template Authentication.
|
|
*
|
|
* @param string|int $to
|
|
* @param string $templateName
|
|
* @param string $templateLanguage
|
|
* @param string $otp
|
|
*/
|
|
public function sendMessageTemplateAuthentication($to, $templateName, $templateLanguage, $otp)
|
|
{
|
|
// build form
|
|
$form = [
|
|
'phone' => $to,
|
|
'template_name' => $templateName,
|
|
'template_language' => $templateLanguage,
|
|
'template' => (object) [
|
|
'body' => [$otp],
|
|
'buttons' => [
|
|
'otp_copy_code' => $otp,
|
|
],
|
|
],
|
|
];
|
|
|
|
return $this->request('POST', 'messages', json_encode($form));
|
|
}
|
|
}
|
|
|