Skip to content

Commit

Permalink
Merge pull request #327 from plivo/SMS-6133
Browse files Browse the repository at this point in the history
SMS-6133 Adding whatsapp support
  • Loading branch information
narayana-plivo authored Aug 8, 2023
2 parents fcb10a6 + 4d426ac commit 18774e0
Show file tree
Hide file tree
Showing 8 changed files with 304 additions and 27 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Change Log

## [4.54.0](https://github.com/plivo/plivo-php/tree/v7.33.0) (2023-08-07)
**Feature - WhatsApp message support**
- Added new param `template` and new message_type `whatsapp` to [send message API](https://www.plivo.com/docs/sms/api/message#send-a-message)
- Added new `message_states` (`read`) `message_type`(`whatsapp`),`conversation_id`, `conversation_origin`, `conversation_expiry_timestamp` in [list all messages API](https://www.plivo.com/docs/sms/api/message#list-all-messages) and [get message details API](https://www.plivo.com/docs/sms/api/message#retrieve-a-message) response

## [4.53.0](https://github.com/plivo/plivo-php/tree/v4.53.0) (2023-08-03)
**Feature - DLT parameters**
- Added new params `DLTEntityID`, `DLTTemplateID`, `DLTTemplateCategory` to the [send message API](https://www.plivo.com/docs/sms/api/message/send-a-message/)
Expand Down
15 changes: 14 additions & 1 deletion src/Plivo/Resources/Message/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
* @property ?string $errorCode
* @property ?string $powerpackID
* @property ?string $requesterIP
* @property ?string $conversationID
* @property ?string $conversationOrigin
* @property ?string $conversationExpirationTimestamp
* @property ?bool $isDomestic
*/
class Message extends Resource
Expand All @@ -38,7 +41,6 @@ public function __construct(
MessageClient $client, $response, $authId, $uri)
{
parent::__construct($client);

$this->properties = [
'from' => $response['from_number'],
'to' => $response['to_number'],
Expand Down Expand Up @@ -90,6 +92,17 @@ public function __construct(
$this->properties['tendlc_registration_status'] = $response['tendlc_registration_status'];
}

if (!empty($response['conversation_id'])) {
$this->properties['conversationID'] = $response['conversation_id'];
}

if (!empty($response['conversation_origin'])) {
$this->properties['conversationOrigin'] = $response['conversation_origin'];
}
if (!empty($response['conversation_expiration_timestamp'])) {
$this->properties['conversationExpirationTimestamp'] = $response['conversation_expiration_timestamp'];
}

if (isset($response['is_domestic'])){
$this->properties['isDomestic'] = $response['is_domestic'];
}
Expand Down
38 changes: 34 additions & 4 deletions src/Plivo/Resources/Message/MessageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use Plivo\Exceptions\PlivoRestException;
use Plivo\Exceptions\PlivoResponseException;
use Plivo\Util\ArrayOperations;
use Plivo\Util\Template;

use Plivo\MessageClient;
use Plivo\Resources\ResourceInterface;

Expand Down Expand Up @@ -74,14 +76,17 @@ public function get($messageUuid)
* <br /> message_time\__lt: lt stands for lesser than. The format expected is YYYY-MM-DD HH:MM[:ss[.uuuuuu]]. Eg:- To get all messages that were sent/received before 2012-03-21 11:47, use message_time\__lt=2012-03-21 11:47
* <br /> message_time\__lte: lte stands for lesser than or equal. The format expected is YYYY-MM-DD HH:MM[:ss[.uuuuuu]]. Eg:- To get all messages that were sent/received before or exactly at 2012-03-21 11:47[:30], use message_time\__lte=2012-03-21 11:47[:30]
* <br /> Note: The above filters can be combined to get messages that were sent/received in a particular time range. The timestamps need to be UTC timestamps.
* + [string] :message_state Status value of the message, is one of "queued", "sent", "failed", "delivered", "undelivered" or "rejected"
* + [string] :message_state Status value of the message, is one of "queued", "sent", "failed","read", "deleted", "delivered", "undelivered" or "rejected"
* + [int] :limit Used to display the number of results per page. The maximum number of results that can be fetched is 20.
* + [int] :offset Denotes the number of value items by which the results should be offset. Eg:- If the result contains a 1000 values and limit is set to 10 and offset is set to 705, then values 706 through 715 are displayed in the results. This parameter is also used for pagination of the results.
* + [string] :error_code Delivery Response code returned by the carrier attempting the delivery. See Supported error codes {https://www.plivo.com/docs/api/message/#standard-plivo-error-codes}.
* + [string] : powerpack_id - Filter the results by Powerpack ID.
* + [string]: tendlc_campaign_id - exact tendlc campaign id search
* + [string]:destination_country_iso2 - valid 2 character country_iso2
* + [string] : tendlc_registration_status - registered or unregistered enum allowed
* + [string] : conversation_id - Filter the results by conversation_id in case of whatsapp messages.
* + [string] : conversation_origin - Filter the results by conversation_origin in case of whatsapp messages.
*
* @return MessageList
*/
protected function getList($optionalArgs = [])
Expand Down Expand Up @@ -116,11 +121,11 @@ protected function getList($optionalArgs = [])
* @param string $text
* @param array $optionalArgs
* + Valid arguments
* + [string] :type - The type of message. Should be `sms` or `mms`. Defaults to `sms`.
* + [string] :type - The type of message. Should be `sms`, `whatsapp` or `mms`. Defaults to `sms`.
* + [string] :url - The URL to which with the status of the message is sent. The following parameters are sent to the URL:
* <br /> To - Phone number of the recipient
* <br /> From - Phone number of the sender
* <br /> Status - Status of the message including "queued", "sent", "failed", "delivered", "undelivered" or "rejected"
* <br /> Status - Status of the message including "queued", "sent", "failed", "delivered", "undelivered", "read", "deleted" or "rejected"
* <br /> MessageUUID - The unique ID for the message
* <br /> ParentMessageUUID - ID of the parent message (see notes about long SMS below)
* <br /> PartInfo - Specifies the sequence of the message (useful for long messages split into multiple text messages; see notes about long SMS below)
Expand All @@ -132,6 +137,8 @@ protected function getList($optionalArgs = [])
* <br /> ErrorCode - Delivery Response code returned by the carrier attempting the delivery. See Supported error codes {https://www.plivo.com/docs/api/message/#standard-plivo-error-codes}.
* + [string] :method - The method used to call the url. Defaults to POST.
* + [string] :log - If set to false, the content of this message will not be logged on the Plivo infrastructure and the dst value will be masked (e.g., 141XXXXX528). Default is set to true.
* + [template] :template - For sending templated whatsapp messages.
*
* [list] : media_urls - If your sending mms message, you can specify the media urls like ['https://yourmedia_urls/test.jpg','https://test.com/test.gif']
* @return MessageCreateResponse output
* @throws PlivoValidationException,PlivoResponseException
Expand All @@ -146,7 +153,8 @@ public function create($src=null, $dst=null, $text=null,array $optionalArgs = []
$dst = isset($optionalArgs['dst']) ? $optionalArgs['dst'] : null;
$text = isset($optionalArgs['text']) ? $optionalArgs['text'] : null;
$powerpackUUID = isset($optionalArgs['powerpackUUID']) ? $optionalArgs['powerpackUUID'] : null;
}
}
$template = isset($optionalArgs['template']) ? $optionalArgs['template'] : null;
if (is_array($dst)){
$mandatoryArgs = [
'dst' => implode('<', $dst),
Expand Down Expand Up @@ -176,7 +184,29 @@ public function create($src=null, $dst=null, $text=null,array $optionalArgs = []
"Both powerpack_uuid and src cannot be specified. Specify either powerpack_uuid or src in request params to send a message."
);
}
if(isset($optionalArgs['type']) && $optionalArgs['type'] == 'whatsapp' && is_null($src))
{
throw new PlivoValidationException(
"src parameter not present"
);
}
if (isset($optionalArgs['type']) && $optionalArgs['type'] != 'whatsapp' && !is_null($template)){
throw new PlivoValidationException(
'Template paramater is only applicable when message_type is whatsapp'
);
}

if(!is_null($template)){
$err = Template::validateTemplate($template);
if (!is_null($err))
{
throw new PlivoValidationException(
$err
);
}
$optionalArgs['template'] = json_decode($template,True);
}

$response = $this->client->update(
$this->uri,
array_merge($mandatoryArgs, $optionalArgs, ['src' => $src, 'powerpack_uuid' => $powerpackUUID, 'text' => $text])
Expand Down
122 changes: 122 additions & 0 deletions src/Plivo/Util/template.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<?php

namespace Plivo\Util;
use Plivo\Exceptions\PlivoValidationException;

function validateNotNullAndDataType($value, $className, $propertyName, $dataType, $checkNull=false)
{
if (is_null($value) && $checkNull) {
throw new PlivoValidationException("Property '$propertyName' of '$className' data_type is mandatory.");
}
if (!is_null($value) && gettype($value) !== $dataType) {
throw new PlivoValidationException("Property '$propertyName' of '$className' data_type should be of type '$dataType'.");
}
}

class Currency {
public $fallback_value;
public $currency_code;
public $amount_1000;

public function __construct(array $data)
{
// Validate the data
$this->fallback_value = isset($data['fallback_value']) ? $data['fallback_value'] : null;
$this->currency_code = isset($data['currency_code']) ? $data['currency_code'] : null;
$this->amount_1000 = isset($data['amount_1000']) ? $data['amount_1000'] : null;

validateNotNullAndDataType($this->fallback_value, 'currency', 'fallback_value', 'string', true);
validateNotNullAndDataType($this->currency_code, 'currency', 'currency_code', 'string', true);
validateNotNullAndDataType($this->amount_1000, 'currency', 'amount_1000', 'integer', true);
}


}

class DateTime {
public $fallback_value;

public function __construct(array $data)
{
// Validate the data
$this->fallback_value = isset($data['fallback_value'])? $data['fallback_value'] : null;
validateNotNullAndDataType($this->fallback_value, 'date_time', 'fallback_value', 'string', true);
}

}

class Parameter {
public $type;
public $text;
public $media;
public $currency;
public $date_time;

public function __construct(array $data)
{
// Validate the data
$this->type = isset($data['type'])? $data['type'] : null;
$this->text = isset($data['text'])? $data['text'] : null;
$this->media = isset($data['media'])? $data['media'] : null;
$this->currency = isset($data['currency'])? new Currency($data['currency']) : null;
$this->date_time = isset($data['date_time']) ? new DateTime($data['date_time']) : null;
validateNotNullAndDataType($this->type, 'parameter', 'type', 'string', true);
validateNotNullAndDataType($this->text, 'parameter', 'text', 'string');
validateNotNullAndDataType($this->media, 'parameter', 'media', 'string');
}


}

class Component {
public $type;
public $sub_type;
public $index;
public $parameters;

public function __construct(array $data)
{
// Validate the data
$this->type = isset($data['type'])? $data['type'] : null;
$this->sub_type = isset($data['sub_type'])? $data['sub_type'] : null;
$this->index = isset($data['index']) ? $data['index'] : null;
$this->parameters = isset($data['parameters']) ? array_map(function($param) {return new Parameter($param);}, $data['parameters']): [];
validateNotNullAndDataType($this->type, 'component', 'type', 'string', true);
validateNotNullAndDataType($this->sub_type, 'component', 'sub_type', 'string');
validateNotNullAndDataType($this->index, 'component', 'index', 'string');
}

}

class Template {
public $name;
public $language;
public $components;

public function __construct(array $data)
{
// Validate the data
$this->name = isset($data['name'])? $data['name'] : null;
$this->language = isset($data['language'])? $data['language'] : null;
$this->components = isset($data['components']) ? array_map(function($component) {return new Component($component);}, $data['components']): [];
validateNotNullAndDataType($this->name, 'template', 'name','string', true);
validateNotNullAndDataType($this->language, 'template', 'language', 'string', true);
}


public static function validateTemplate(string $template)
{
try {
if(is_null(json_decode($template, true)))
{
return "Invalid JSON data for template!";
}
//Validate the JSON data against the Template class
$template = new Template(json_decode($template, true));
return null;
} catch (PlivoValidationException $e) {
// Handle validation errors here
return $e->getMessage();
}
}
}
2 changes: 1 addition & 1 deletion src/Plivo/Version.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class Version
/**
* @const int PHP helper library minor version number
*/
const MINOR = 53;
const MINOR = 54;

/**
* @const int PHP helper library patch number
Expand Down
5 changes: 4 additions & 1 deletion tests/Mocks/messageGetResponse.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@
"replaced_sender": "INSID",
"dlt_entity_id": "1234",
"dlt_template_id": "5678",
"dlt_template_category": "service_implicit"
"dlt_template_category": "service_implicit",
"conversation_id": "9876",
"conversation_origin": "utility",
"conversation_expiration_timestamp": "2023-08-03 23:02:00+05:30"
}
Loading

0 comments on commit 18774e0

Please sign in to comment.