2019-11-12 05:18:32 +01:00
< ? php
2020-01-17 18:19:25 +01:00
/*
* This file is part of RaspiSMS .
*
* ( c ) Pierre - Lin Bonnemaison < plebwebsas @ gmail . com >
*
* This source file is subject to the GPL - 3.0 license that is bundled
* with this source code in the file LICENSE .
*/
namespace adapters ;
use Ovh\Api ;
2019-11-12 05:18:32 +01:00
/**
2020-06-23 21:06:13 +02:00
* OVH SMS service with a shortcode allowing responses .
2019-11-12 05:18:32 +01:00
*/
2020-03-31 02:45:54 +02:00
class OvhSmsShortcodeAdapter implements AdapterInterface
2019-11-12 05:18:32 +01:00
{
2020-01-17 18:19:25 +01:00
/**
* Datas used to configure interaction with the implemented service . ( e . g : Api credentials , ports numbers , etc . ) .
*/
private $datas ;
/**
* OVH Api instance .
*/
private $api ;
/**
* Adapter constructor , called when instanciated by RaspiSMS .
*
* @ param string $number : Phone number the adapter is used for
* @ param json string $datas : JSON string of the datas to configure interaction with the implemented service
*/
2020-03-31 01:28:32 +02:00
public function __construct ( string $datas )
2020-01-17 18:19:25 +01:00
{
$this -> datas = json_decode ( $datas , true );
$this -> api = new Api (
$this -> datas [ 'app_key' ],
$this -> datas [ 'app_secret' ],
2020-03-04 01:40:47 +01:00
'ovh-eu' ,
2020-01-17 18:19:25 +01:00
$this -> datas [ 'consumer_key' ]
);
}
/**
* Classname of the adapter .
2019-11-12 05:18:32 +01:00
*/
2020-01-17 18:19:25 +01:00
public static function meta_classname () : string
{
return __CLASS__ ;
}
2019-11-12 05:18:32 +01:00
2020-04-02 01:55:55 +02:00
/**
* Uniq name of the adapter
2020-06-23 21:06:13 +02:00
* It should be the classname of the adapter un snakecase .
2020-04-02 01:55:55 +02:00
*/
2020-06-23 21:06:13 +02:00
public static function meta_uid () : string
2020-04-02 01:55:55 +02:00
{
return 'ovh_sms_shortcode_adapter' ;
}
2019-11-12 05:18:32 +01:00
/**
* Name of the adapter .
2020-01-17 18:19:25 +01:00
* It should probably be the name of the service it adapt ( e . g : Gammu SMSD , OVH SMS , SIM800L , etc . ) .
2019-11-12 05:18:32 +01:00
*/
2020-01-17 18:19:25 +01:00
public static function meta_name () : string
{
2020-03-31 02:45:54 +02:00
return 'OVH SMS Shortcode' ;
2020-01-17 18:19:25 +01:00
}
2019-11-12 05:18:32 +01:00
/**
* Description of the adapter .
* A short description of the service the adapter implements .
*/
2020-01-17 18:19:25 +01:00
public static function meta_description () : string
{
2020-03-30 01:52:53 +02:00
$generate_credentials_url = 'https://eu.api.ovh.com/createToken/index.cgi?GET=/sms&GET=/sms/*&POST=/sms/*&PUT=/sms/*&DELETE=/sms/*&' ;
2020-03-29 20:55:47 +02:00
return '
2020-07-04 21:35:39 +02:00
Solution de SMS proposé par le groupe < a target = " _blank " href = " https://www.ovhtelecom.fr/sms/ " > OVH </ a >. Pour générer les clefs API OVH , < a target = " _blank " href = " ' . $generate_credentials_url . ' " > cliquez ici .</ a >< br />
Pour plus d\ ' information sur l\ ' utilisation de l\ ' adaptateur , reportez - vous à < a href = " https://documentation.raspisms.fr/users/adapters/ovh_shortcode.html " target = " _blank " > la documentation sur l\ ' adaptateur OVH Shortcode .</ a >
2020-03-29 20:55:47 +02:00
' ;
2020-01-17 18:19:25 +01:00
}
2020-01-09 22:23:58 +01:00
/**
2020-01-17 18:19:25 +01:00
* List of entries we want in datas for the adapter .
*
2020-01-09 22:23:58 +01:00
* @ return array : Every line is a field as an array with keys : name , title , description , required
*/
2020-01-17 18:19:25 +01:00
public static function meta_datas_fields () : array
2020-01-09 22:23:58 +01:00
{
return [
2020-03-29 20:20:07 +02:00
[
'name' => 'service_name' ,
'title' => 'Service Name' ,
'description' => 'Service Name de votre service SMS chez OVH. Il s\'agit du nom associé à votre service SMS dans la console OVH, probablement quelque chose comme "sms-xxxxx-1" ou "xxxx" est votre identifiant client OVH.' ,
'required' => true ,
],
2020-03-31 03:09:21 +02:00
[
'name' => 'sender' ,
'title' => 'Nom de l\'expéditeur' ,
'description' => ' Nom de l\ ' expéditeur à afficher à la place du numéro ( 11 caractères max ) .< br />
2020-05-19 05:00:35 +02:00
< b > Laissez vide pour ne pas utiliser d\ ' expéditeur nommé .</ b >< br />< br />
2020-03-31 03:09:21 +02:00
Le nom doit avoir été validé au préallable . < b > Si vous utilisez un expéditeur nommé , le destinataire ne pourra pas répondre .</ b > ' ,
'required' => false ,
],
2020-01-09 22:23:58 +01:00
[
'name' => 'app_key' ,
'title' => 'Application Key' ,
'description' => 'Paramètre "Application Key" obtenu lors de la génération de la clef API OVH.' ,
'required' => true ,
],
[
'name' => 'app_secret' ,
'title' => 'Application Secret' ,
'description' => 'Paramètre "Application Secret" obtenu lors de la génération de la clef API OVH.' ,
'required' => true ,
],
[
'name' => 'consumer_key' ,
'title' => 'Consumer Key' ,
'description' => 'Paramètre "Consumer Key" obtenu lors de la génération de la clef API OVH.' ,
'required' => true ,
],
];
}
2019-11-12 05:18:32 +01:00
2020-03-31 02:22:40 +02:00
/**
* Does the implemented service support reading smss .
*/
public static function meta_support_read () : bool
{
return true ;
}
2019-11-12 05:18:32 +01:00
/**
2020-01-17 18:19:25 +01:00
* Does the implemented service support flash smss .
2020-01-09 22:23:58 +01:00
*/
2020-01-17 18:19:25 +01:00
public static function meta_support_flash () : bool
{
return false ;
}
2020-01-09 22:23:58 +01:00
/**
2020-01-17 18:19:25 +01:00
* Does the implemented service support status change .
2019-11-12 05:18:32 +01:00
*/
2020-01-17 18:19:25 +01:00
public static function meta_support_status_change () : bool
2019-11-12 05:18:32 +01:00
{
2020-01-17 18:19:25 +01:00
return true ;
2019-11-12 05:18:32 +01:00
}
2020-06-23 21:06:13 +02:00
2020-04-03 02:15:55 +02:00
/**
* Does the implemented service support reception callback .
*/
public static function meta_support_reception () : bool
{
return false ;
}
2019-11-12 05:18:32 +01:00
/**
2020-01-17 18:19:25 +01:00
* Method called to send a SMS to a number .
*
2019-11-12 05:18:32 +01:00
* @ param string $destination : Phone number to send the sms to
2020-01-17 18:19:25 +01:00
* @ param string $text : Text of the SMS to send
* @ param bool $flash : Is the SMS a Flash SMS
*
2020-04-03 03:38:35 +02:00
* @ return array : [
2020-06-23 21:06:13 +02:00
* bool 'error' => false if no error , true else
* ? string 'error_message' => null if no error , else error message
* ? string 'uid' => Uid of the sms created on success
* ]
2019-11-12 05:18:32 +01:00
*/
2020-01-17 18:19:25 +01:00
public function send ( string $destination , string $text , bool $flash = false )
2019-11-12 05:18:32 +01:00
{
2020-04-02 01:55:55 +02:00
$response = [
'error' => false ,
'error_message' => null ,
'uid' => null ,
];
2020-01-17 18:19:25 +01:00
try
2020-01-09 22:23:58 +01:00
{
$success = true ;
2020-03-31 02:45:54 +02:00
$endpoint = '/sms/' . $this -> datas [ 'service_name' ] . '/jobs' ;
2020-01-09 22:23:58 +01:00
$params = [
'message' => $text ,
'receivers' => [ $destination ],
2020-03-31 02:45:54 +02:00
'senderForResponse' => true ,
2020-01-09 22:23:58 +01:00
];
2020-03-31 03:09:21 +02:00
if ( $this -> datas [ 'sender' ])
{
$params [ 'sender' ] = $this -> datas [ 'sender' ];
$params [ 'senderForResponse' ] = false ;
}
2020-01-09 22:23:58 +01:00
$response = $this -> api -> post ( $endpoint , $params );
2020-01-17 18:19:25 +01:00
$nb_invalid_receivers = \count (( $response [ 'invalidReceivers' ] ? ? []));
2020-01-09 22:23:58 +01:00
if ( $nb_invalid_receivers > 0 )
{
2020-04-02 01:55:55 +02:00
$response [ 'error' ] = true ;
$response [ 'error_message' ] = 'Invalid receiver' ;
2020-06-23 21:06:13 +02:00
2020-04-02 01:55:55 +02:00
return $response ;
2020-01-09 22:23:58 +01:00
}
2020-04-02 01:55:55 +02:00
$uid = $response [ 'ids' ][ 0 ] ? ? false ;
if ( ! $uid )
{
$response [ 'error' ] = true ;
$response [ 'error_message' ] = 'Cannot retrieve uid.' ;
2020-06-23 21:06:13 +02:00
2020-04-02 01:55:55 +02:00
return $response ;
}
2020-01-17 18:19:25 +01:00
2020-04-02 01:55:55 +02:00
$response [ 'uid' ] = $uid ;
2020-06-23 21:06:13 +02:00
2020-04-02 01:55:55 +02:00
return $response ;
2020-01-09 22:23:58 +01:00
}
2020-04-02 01:55:55 +02:00
catch ( \Throwable $t )
2020-01-09 22:23:58 +01:00
{
2020-04-02 01:55:55 +02:00
$response [ 'error' ] = true ;
$response [ 'error_message' ] = $t -> getMessage ();
2020-06-23 21:06:13 +02:00
2020-04-02 01:55:55 +02:00
return $response ;
2020-01-09 22:23:58 +01:00
}
2019-11-12 05:18:32 +01:00
}
/**
2020-01-17 18:19:25 +01:00
* Method called to read SMSs of the number .
*
2020-04-02 01:55:55 +02:00
* @ return array : [
2020-06-23 21:06:13 +02:00
* bool 'error' => false if no error , true else
* ? string 'error_message' => null if no error , else error message
* array 'sms' => Array of the sms reads
* ]
2019-11-12 05:18:32 +01:00
*/
2020-01-17 18:19:25 +01:00
public function read () : array
2019-11-12 05:18:32 +01:00
{
2020-04-02 01:55:55 +02:00
$response = [
'error' => false ,
'error_message' => null ,
'smss' => [],
];
2020-01-17 18:19:25 +01:00
try
2020-01-09 22:23:58 +01:00
{
2020-04-02 01:55:55 +02:00
//If we use a sender we cannot receive response, no need to make queries
if ( $this -> datas [ 'sended' ])
{
return $response ;
}
2020-01-09 22:23:58 +01:00
2020-03-31 02:45:54 +02:00
$endpoint = '/sms/' . $this -> datas [ 'service_name' ] . '/incoming' ;
2020-01-09 22:23:58 +01:00
$uids = $this -> api -> get ( $endpoint );
2020-01-17 18:19:25 +01:00
if ( ! \is_array ( $uids ) || ! $uids )
2020-01-09 22:23:58 +01:00
{
2020-04-02 01:55:55 +02:00
return $response ;
2020-01-09 22:23:58 +01:00
}
foreach ( $uids as $uid )
{
2020-03-31 02:45:54 +02:00
$endpoint = '/sms/' . $this -> datas [ 'service_name' ] . '/incoming/' . $uid ;
2020-01-09 22:23:58 +01:00
$sms_details = $this -> api -> get ( $endpoint );
if ( ! isset ( $sms_details [ 'creationDatetime' ], $sms_details [ 'message' ], $sms_details [ 'sender' ]))
{
continue ;
}
2020-04-02 01:55:55 +02:00
$response [ 'smss' ][] = [
2020-01-09 22:23:58 +01:00
'at' => ( new \DateTime ( $sms_details [ 'creationDatetime' ])) -> format ( 'Y-m-d H:i:s' ),
'text' => $sms_details [ 'message' ],
'origin' => $sms_details [ 'sender' ],
];
//Remove the sms to prevent double reading as ovh do not offer a filter for unread messages only
2020-03-31 02:45:54 +02:00
$endpoint = '/sms/' . $this -> datas [ 'service_name' ] . '/incoming/' . $uid ;
2020-01-09 22:23:58 +01:00
$this -> api -> delete ( $endpoint );
}
2020-04-02 01:55:55 +02:00
return $response ;
2020-01-09 22:23:58 +01:00
}
2020-04-02 01:55:55 +02:00
catch ( \Throwable $t )
2020-01-09 22:23:58 +01:00
{
2020-04-02 01:55:55 +02:00
$response [ 'error' ] = true ;
$response [ 'error_message' ] = $t -> getMessage ();
2020-06-23 21:06:13 +02:00
2020-04-02 01:55:55 +02:00
return $response ;
2020-01-09 22:23:58 +01:00
}
}
/**
* Method called to verify if the adapter is working correctly
2020-01-17 18:19:25 +01:00
* should be use for exemple to verify that credentials and number are both valid .
*
* @ return bool : False on error , true else
2020-01-09 22:23:58 +01:00
*/
2020-01-17 18:19:25 +01:00
public function test () : bool
2020-01-09 22:23:58 +01:00
{
2020-01-17 18:19:25 +01:00
try
2020-01-09 22:23:58 +01:00
{
$success = true ;
2020-06-23 21:06:13 +02:00
2020-04-03 02:15:55 +02:00
if ( $this -> datas [ 'sender' ] && ( mb_strlen ( $this -> datas [ 'sender' ]) < 3 || mb_strlen ( $this -> datas [ 'sender' ] > 11 )))
2020-03-31 03:09:21 +02:00
{
return false ;
}
2020-01-09 22:23:58 +01:00
//Check service name
2020-01-17 18:47:08 +01:00
$endpoint = '/sms/' . $this -> datas [ 'service_name' ];
2020-01-09 22:23:58 +01:00
$response = $this -> api -> get ( $endpoint );
2020-01-17 18:19:25 +01:00
2020-06-23 21:06:13 +02:00
return $success && ( bool ) $response ;
2020-01-09 22:23:58 +01:00
}
2020-04-02 01:55:55 +02:00
catch ( \Throwable $t )
2020-01-09 22:23:58 +01:00
{
return false ;
}
2019-11-12 05:18:32 +01:00
}
2020-01-08 02:14:38 +01:00
/**
2020-01-17 18:19:25 +01:00
* Method called on reception of a status update notification for a SMS .
*
2020-04-02 01:55:55 +02:00
* @ return mixed : False on error , else array [ 'uid' => uid of the sms , 'status' => New status of the sms ( \models\Sended :: STATUS_UNKNOWN , \models\Sended :: STATUS_DELIVERED , \models\Sended :: STATUS_FAILED )]
2020-01-08 02:14:38 +01:00
*/
2020-01-17 18:19:25 +01:00
public static function status_change_callback ()
2020-01-08 02:14:38 +01:00
{
2020-01-09 22:23:58 +01:00
$uid = $_GET [ 'id' ] ? ? false ;
$dlr = $_GET [ 'dlr' ] ? ? false ;
2020-01-17 18:19:25 +01:00
if ( false === $uid || false === $dlr )
2020-01-09 22:23:58 +01:00
{
return false ;
}
switch ( $dlr )
{
case 1 :
2020-04-02 01:55:55 +02:00
$status = \models\Sended :: STATUS_DELIVERED ;
2020-01-09 22:23:58 +01:00
2020-01-17 18:19:25 +01:00
break ;
2021-01-14 03:32:17 +01:00
2020-01-09 22:23:58 +01:00
case 2 :
case 16 :
2020-04-02 01:55:55 +02:00
$status = \models\Sended :: STATUS_FAILED ;
2020-01-17 18:19:25 +01:00
2020-01-09 22:23:58 +01:00
break ;
2021-01-14 03:32:17 +01:00
2020-01-09 22:23:58 +01:00
default :
2020-04-02 01:55:55 +02:00
$status = \models\Sended :: STATUS_UNKNOWN ;
2020-01-17 18:19:25 +01:00
2020-01-09 22:23:58 +01:00
break ;
}
return [ 'uid' => $uid , 'status' => $status ];
2020-01-08 02:14:38 +01:00
}
2020-06-23 21:06:13 +02:00
2020-04-03 02:15:55 +02:00
/**
* Method called on reception of a sms notification .
*
* @ return array : [
2020-06-23 21:06:13 +02:00
* bool 'error' => false on success , true on error
* ? string 'error_message' => null on success , error message else
* array 'sms' => array [
* string 'at' : Recepetion date format Y - m - d H : i : s ,
* string 'text' : SMS body ,
* string 'origin' : SMS sender ,
* ]
2020-04-03 02:15:55 +02:00
*
* ]
*/
2020-06-23 21:06:13 +02:00
public static function reception_callback () : array
2020-04-03 02:15:55 +02:00
{
return [];
}
2019-11-12 05:18:32 +01:00
}