{"id":22277,"date":"2022-05-30T15:49:14","date_gmt":"2022-05-30T12:49:14","guid":{"rendered":"https:\/\/oz-plugin.com\/?p=22277"},"modified":"2022-07-26T12:03:34","modified_gmt":"2022-07-26T09:03:34","slug":"sms-integration-with-other-sms-services-providers-in-ozapp-plugin","status":"publish","type":"post","link":"https:\/\/oz-plugin.com\/pb\/sms-integration-with-other-sms-services-providers-in-ozapp-plugin\/","title":{"rendered":"(EN) SMS Integration with other SMS services (providers) in OzApp plugin"},"content":{"rendered":"<p class=\"qtranxs-available-languages-message qtranxs-available-languages-message-pb\">Desculpe-nos, mas este texto est\u00e1 apenas dispon\u00edvel em <a href=\"https:\/\/oz-plugin.com\/en\/wp-json\/wp\/v2\/posts\/22277\" class=\"qtranxs-available-language-link qtranxs-available-language-link-en\" title=\"EN\">Ingl\u00eas Americano<\/a> y <a href=\"https:\/\/oz-plugin.com\/ru\/wp-json\/wp\/v2\/posts\/22277\" class=\"qtranxs-available-language-link qtranxs-available-language-link-ru\" title=\"RU\">Russo<\/a>.<\/p><p>Our clients often use requests to see if there is a possibility of alternative SMS integration instead the built-in Twilio and SMSC.<br \/>\nTherefore, in this post we will describe how to create a new way to send SMS.<\/p>\n<p>We use Object-Oriented PHP with class to write the code we need. But experienced php developers can use the functional approach.<br \/>\nSo, let&#8217;s create a custom class for sending sms and call it for example <code>CustomSMSProvider<\/code>. And add a few basic properties and methods to it, which we will write about below.<br \/>\nCode example:<br \/>\n<code><br \/>\nclass CustomSMSProvider {<br \/>\n\tpublic $provider = '';<br \/>\n\tpublic function getOptions($settings) {}<br \/>\n\tpublic function send($to, $message, $sendTime = null) {}<br \/>\n\tpublic function send_book($from,$to,$text,$id,$sendTime = 0) {}<br \/>\n\tpublic function send_otp($response, $to, $message) {}<br \/>\n        public function init() {}<br \/>\n}<br \/>\n<\/code><br \/>\nNow let&#8217;s analyze the properties and methods of our class.<\/p>\n<p><code>public $provider<\/code> &#8211; the value of the property is the value of the option &#8211; this is how the SMS will be sent (we can choose this method in the plugin settings). You can enter any value here, for example: as_custom_sms<br \/>\n<code>public function getOptions($settings) {}<\/code> &#8211; in this method, you need to describe the provider&#8217;s SMS settings. These settings will then be displayed on the SMS tab of the plugin settings.<br \/>\nthis method filters the values \u200b\u200bof all plugin options, so you need to be careful when writing your options. First, it always returns $settings. Second, the sms options are written to the $settings[&#8216;sms&#8217;][&#8216;options&#8217;] array which contains all the options on the sms tab.<br \/>\nPerhaps later we will describe how the array of all plugin options is formed, but now we will describe only what is needed for SMS.<br \/>\nEach plugin option is an array that contains the following options:<\/p>\n<ul>\n<li>&#8216;title&#8217; &#8211; string option name (required)<\/li>\n<li>&#8216;description&#8217; &#8211; string option description (optional)<\/li>\n<li>&#8216;order&#8217; &#8211; number option order (required)<\/li>\n<li>&#8216;fields&#8217; &#8211; array description of the settings associated with this option, contains an array of arrays with the following keys:\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>&#8216;name&#8217; &#8211; string is the name of the option that we will substitute in get_option to get the value (required)<\/li>\n<li>&#8216;value&#8217; &#8211; mix the option value that get_option will return, (required)<\/li>\n<li>&#8216;type&#8217; &#8211; option types. we only use switch and input (required)<\/li>\n<li>&#8216;multiple&#8217; &#8211; bool &#8211; multiple choices (optional),<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&#8216;values&#8217; &#8211; only for option type switch. array of arrays of values in the format [&#8216;label&#8217; => &#8221;, &#8216;value&#8217; => &#8221;] (optional),<\/li>\n<li>&#8216;fields&#8217; &#8211; only for option type switch. array of arrays that will contain nested options that will be visible in the interface if switch is active<\/li>\n<\/ul>\n<h3>Example of code for adding options, using Twilio as an example:<\/h3>\n<p><code><br \/>\npublic function getOptions($settings) {<br \/>\n$opt = [<br \/>\n'title'  =>  'Twilio', \/\/ sms method name<br \/>\n'description'  =>  '',<br \/>\n'order'  =>  40,<br \/>\n\/\/ in fields, be sure to add an array of options of type switch<br \/>\n'fields'  =>  [<br \/>\n[<br \/>\n'name'  =>  'oz_smsType', \/\/ here always oz_smsType<br \/>\n'value'  =>  get_option('oz_smsType') == $this->provider, \/\/ here always this condition<br \/>\n'type'  =>  'switch', \/\/ here always switch<br \/>\n'multiple'  =>  false, \/\/ here always false<br \/>\n\/\/ in values always these values<br \/>\n'values'  =>  [<br \/>\n[<br \/>\n'label'  =>  '',<br \/>\n'value'  =>  $this->provider<br \/>\n]<br \/>\n],<br \/>\n\/\/ here we will describe our options. One option, one array. Using Twilio as an example, three options are needed: SID, Token, Account Phone Number or Alphanumeric Sender ID<br \/>\n'fields'  =>  [<br \/>\n[<br \/>\n'title'  =>  'SID',<br \/>\n'description'  =>  '',<br \/>\n'order'  =>  10,<br \/>\n'fields'  =>  [<br \/>\n[<br \/>\n'name'  =>  'oz_twilio_sid', \/\/ You can come up with any option name. we will write oz_twilio_sid<br \/>\n'value'  =>  get_option('oz_twilio_sid', ''),<br \/>\n'type'  =>  'input',<br \/>\n'multiple'  =>  false,<br \/>\n'values'  =>  [],<br \/>\n],<br \/>\n]<br \/>\n],<br \/>\n[<br \/>\n'title'  =>  'Token',<br \/>\n'description'  =>  '',<br \/>\n'order'  =>  10,<br \/>\n'fields'  =>  [<br \/>\n[<br \/>\n'name'  =>  'oz_twilio_token',<br \/>\n'value'  =>  get_option('oz_twilio_token', ''),<br \/>\n'type'  =>  'input',<br \/>\n'multiple'  =>  false,<br \/>\n'values'  =>  [],<br \/>\n],<br \/>\n]<br \/>\n],<br \/>\n[<br \/>\n'title'  =>  'Account Phone Number or Alphanumeric Sender ID',<br \/>\n'description'  =>  '',<br \/>\n'order'  =>  10,<br \/>\n'fields'  =>  [<br \/>\n[<br \/>\n'name'  =>  'oz_twilio_sender',<br \/>\n'value'  =>  get_option('oz_twilio_sender', ''),<br \/>\n'type'  =>  'input',<br \/>\n'multiple'  =>  false,<br \/>\n'values'  =>  [],<br \/>\n],<br \/>\n]<br \/>\n],<br \/>\n]<br \/>\n]<br \/>\n]<br \/>\n];<br \/>\n$settings['sms']['options'][] = $opt;<br \/>\nreturn $settings;<br \/>\n}<br \/>\n<\/code><\/p>\n<h3>Method that will send SMS:<\/h3>\n<p><code>public function send($to, $message, $sendTime = null) {}<\/code><br \/>\nMethod variables:<br \/>\n<strong>$to<\/strong> &#8211; recipient&#8217;s phone number<br \/>\n<strong>$message<\/strong> &#8211; message text<br \/>\n<strong>$sendTime<\/strong> &#8211; send time (optional)<\/p>\n<p>You must describe the logic of this function yourself using the API of your SMS provider. If successful, the function should return a response from your SMS provider. In case of an error, an array with keys: error &#8211; true, text &#8211; error text<\/p>\n<h3>In our example, you will see an example of submitting code using Twilio:<\/h3>\n<p><code><br \/>\npublic function send($to, $message, $sendTime = null) {<br \/>\n$sid = get_option('oz_twilio_sid');<br \/>\n$token = get_option('oz_twilio_token');<br \/>\n$auth = base64_encode($sid . \":\" . $token);<br \/>\n$from = get_option('oz_twilio_sender');<br \/>\n$data = array(<br \/>\n\"From\"  =>  $from,<br \/>\n\"To\"  =>  $to,<br \/>\n\"Body\"  =>  do_shortcode($message),<br \/>\n);<br \/>\n$url = \"https:\/\/api.twilio.com\/2010-04-01\/Accounts\/\".$sid.\"\/Messages.json\";<br \/>\n$sms = wp_remote_post( $url, array(<br \/>\n'headers'  =>  [ 'Authorization'  =>  \"Basic $auth\" ],<br \/>\n'body'         =>  $data,<br \/>\n) );<br \/>\nif (is_wp_error($sms)) {<br \/>\n$sms = [<br \/>\n'error'  =>  true,<br \/>\n'text'  =>  $sms-> get_error_message(),<br \/>\n];<br \/>\n}<br \/>\nelse {<br \/>\n$sms = json_decode(wp_remote_retrieve_body($sms), true);<br \/>\nif ($sms['status'] &amp;&amp; $sms['status'] == 'queued') {<br \/>\nreturn $sms;<br \/>\n}<br \/>\nelse {<br \/>\n$sms = [<br \/>\n'error'  =>  true,<br \/>\n'text'  =>  $sms['message'],<br \/>\n'response'  =>  $sms<br \/>\n];<br \/>\n}<br \/>\n}<br \/>\nreturn $sms;<br \/>\n}<br \/>\n<\/code><\/p>\n<h3>Method of sending SMS at the time of creating a new record<\/h3>\n<p><code>public function send_book($from,$to,$text,$id,$sendTime = 0) {}<\/code><br \/>\nIt must contain the send method. And optionally, you can describe further actions.<br \/>\nMethod Variables:<br \/>\n<strong>$from<\/strong> &#8211; optional,<br \/>\n<strong>$to<\/strong> &#8211; recipient&#8217;s phone,<br \/>\n<strong>$text<\/strong> &#8211; message,<br \/>\n<strong>$id<\/strong> &#8211; appointment id,<br \/>\n<strong>$sendTime<\/strong> &#8211; optional<\/p>\n<h3>Code example:<\/h3>\n<p><code><br \/>\npublic function send_book($from,$to,$text,$id,$sendTime = 0) {<br \/>\n$this-> send($to, $text);<br \/>\n}<br \/>\n<\/code><\/p>\n<h3>Method of sending SMS code, before booking, to confirm the phone number<\/h3>\n<p><code>public function send_otp($response, $to, $message) {} <\/code><br \/>\nMust return an array with key success and value true or send method error.<\/p>\n<h3>Code example:<\/h3>\n<p><code><br \/>\npublic function send_otp($response, $to, $message) {<br \/>\n$response = $this-> send($to, $message);<br \/>\nif (isset($response['error']) &amp;&amp; $response['error']) {<br \/>\nreturn $response;<br \/>\n}<br \/>\nelse {<br \/>\nreturn [<br \/>\n'success'  =>  true,<br \/>\n];<br \/>\n}<br \/>\n}<br \/>\n<\/code><\/p>\n<h3>The method in which method call hooks are written<\/h3>\n<p><code>public function init() {}<\/code><br \/>\nHere you need to bind to the SMS sending hooks that our plugin uses its own sending method. almost always this code will be like in the example:<\/p>\n<h3>Code example:<\/h3>\n<p><code><br \/>\npublic function init() {<br \/>\nadd_filter('book_oz_plugin_settings', [$this, 'getOptions']);<br \/>\nadd_filter('book_oz_otp_send_'.$this-> provider, [$this,'send_otp'], 10, 3);<br \/>\nadd_action('book_sendingSMS_'.$this-> provider, [$this,'send_book'],10,5);<br \/>\nadd_action('book_sendingSMSRemind_emp_'.$this-> provider, [$this, 'send'], 10,3);<br \/>\n}<br \/>\n<\/code><\/p>\n<p>The class itself can be saved in a separate file or added directly to your theme&#8217;s <code>functions.php<\/code>.<br \/>\nAfter that, you need to create an instance of the class and call the <code>init<\/code> method<br \/>\nSample code for functions.php (class in a separate file in the same folder as functions.php):<br \/>\n<code><br \/>\nrequire_once(dirname(__FILE__).'\/CustomSMSProvider.php');<br \/>\n$customsms = new CustomSMSProvider();<br \/>\n$customsms->init();<br \/>\n<\/code><\/p>\n<p>That&#8217;s all. If everything is done correctly, then in the plugin settings in the SMS tab you will see the settings for your new method and receive SMS in this way when booking.<br \/>\nExample of this code you can find at <a rel=\"nofollow\" href=\"https:\/\/github.com\/ozplugin\/examples\/blob\/main\/CustomSMSProvider.php\">GitHub<\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>Desculpe-nos, mas este texto est\u00e1 apenas dispon\u00edvel em Ingl\u00eas Americano y Russo.Our clients often use requests to see if there is a possibility of alternative SMS integration instead the built-in Twilio and SMSC. Therefore, in this post we will describe how to create a new way to send SMS. We use Object-Oriented PHP with class [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":22690,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/oz-plugin.com\/pb\/wp-json\/wp\/v2\/posts\/22277"}],"collection":[{"href":"https:\/\/oz-plugin.com\/pb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/oz-plugin.com\/pb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/oz-plugin.com\/pb\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/oz-plugin.com\/pb\/wp-json\/wp\/v2\/comments?post=22277"}],"version-history":[{"count":0,"href":"https:\/\/oz-plugin.com\/pb\/wp-json\/wp\/v2\/posts\/22277\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/oz-plugin.com\/pb\/wp-json\/wp\/v2\/media\/22690"}],"wp:attachment":[{"href":"https:\/\/oz-plugin.com\/pb\/wp-json\/wp\/v2\/media?parent=22277"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oz-plugin.com\/pb\/wp-json\/wp\/v2\/categories?post=22277"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oz-plugin.com\/pb\/wp-json\/wp\/v2\/tags?post=22277"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}