Search code examples
apisymfonyserviceovh

I can not connect to the Ovh API to send sms


I am working on sending SMS on Symfony, I go through the ovh API, I created a form to type the message to send and I can display it but when I click send, I have this error : Cannot use object of type Symfony\Bridge\Monolog\Logger as array

the problem is when i try to connect to the api ovh Thanks for the help

my service :

 class SmsProvider
 {
/** @var array */
private $config;
/** @var LoggerInterface */
private $logger;

public function __construct($config, LoggerInterface $logger)
{
    $this->config = $config;
    $this->logger = $logger;
}

public function sendMessage($phoneNumbers, $message)
{
    $conn = $this->connectToApi();
    $phoneNumbers = (array)$phoneNumbers;

    $content = [
        'charset' => 'UTF-8',
        'class' => 'phoneDisplay',
        'coding' => '7bit',
        'message' => $message,
        'noStopClause' => true,
        'priority' => 'high',
        'receivers' => $phoneNumbers,
        'senderForResponse' => true,
    ];

    try {
        $smsServices = $conn->get('/sms/');
        $result = $conn->post(sprintf('/sms/%s/jobs/', 
        $smsServices[0]), $content);

    } catch (\Exception $e) {
        if (null !== $this->logger) {
            $this->logger->critical(
                sprintf("Erreur lors de l'envoi SMS : %s . Trace : 
                %s", $e->getMessage(), $e->getTraceAsString()), [
                    'paramsOvh' => $content
                ]
            );
        }

        $result = false;
    }

    return $result;
}

private function connectToApi()
{
    if (!isset($this->config['application_key'],
        $this->config['application_secret'],
        $this->config['consumer_key'],
        $this->config['end_point'])
    ) {
        $this->logger->error('OVH config parameters are missing');
        throw new \Exception('OVH config parameters are missing');
    }

    $applicationKey = $this->config['application_key'];
    $applicationSecret = $this->config['application_secret'];
    $consumerKey = $this->config['consumer_key'];
    $endPoint = $this->config['end_point'];

    try {
        $conn = new Api(
            $applicationKey,
            $applicationSecret,
            $endPoint,
            $consumerKey
        );
    } catch (InvalidParameterException $e) {
        $this->logger->critical(
            sprintf("Erreur lors de la connexion à l'API OVH : %s . 
            Trace : %s", $e->getMessage(), $e->getTraceAsString())
        );

        throw $e;
    }

    return $conn;
  }
  }

Controller :

  public function sendSmsAction(Request $request)
 {

    $telephones = $request->get('telephone');
    $form = $this->createForm(smsFormType::class);
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {
        $message = $form->get('message')->getData();
        $smsProvider = $this->get('app.sms.provider');
        $smsProvider->sendMessage($message, $telephones);
         }
        return $this->render('
        CeUtilisateurBundle:Utilisateur:sms.html.twig', array(
        'form' => $form->createView()));
      }

service.yml

  app.sms.provider:
             class: Ce\UtilisateurBundle\Services\SmsProvider
             arguments: ['@logger']
             public: true

Solution

  • IMO you should create another class that have to return you an Api object rightly configured to communicate.

    So this service takes 3 scalars parameters (or your config array)

    You should define it this way

    app.ovh_connection:
        class: Ce\UtilisateurBundle\Services\OvhConnection
        arguments:
            $applicationKey: '%application_key%'
            $applicationSecret: '%application_secret%'
            $consumerKey: '%consumer_key%'
    

    The class handling the connection look like this

    class OvhConnection {   
        private $applicationKey;
    
        private $applicationSecret;
    
        private $consumerKey;
    
        constructor($applicationKey, $applicationSecret, $consumerKey)  {       
            $this->applicationKey = $applicationKey; 
            $this->applicationSecret = $applicationSecret;
            $this->consumerKey = $consumerKey;  
        }
    
        public function getConnection($endpoint)    {
            return new Api(
                $this->applicationKey,
                $this->applicationSecret,
                $endPoint,
                $this->consumerKey
            );  
        } 
    }
    

    Pretty simple, so the connection part is handled only here. If you want to use another service of this API (like email sending for example) you just have to use this class.

    Then you have to adapt your SmsProvider class to retrieve the connection from your new class

    class SmsProvider
    {   
        /** @var OvhConnection */
        private $connection;
    
        /** @var LoggerInterface */
        private $logger;
    
        public function __construct(OvhConnection $connection, LoggerInterface $logger)
        {
            $this->connection = $connection;
            $this->logger = $logger;
        }
    
        // Call $this->connection->getConnection('your_endpoint'); to retrieve an OvhConnection configured
    }
    

    Finally you have to update SmsProvider's definition this way

    app.sms.provider:
        class: Ce\UtilisateurBundle\Services\SmsProvider
        arguments: ['@app.ovh_connection', '@logger']
        public: true