• I’ve wrapped the basic Twilio SMS sending method into a function in a must-use plugin. I’ve added a form in the admin screen to retrieve a list of users’ and their numbers and can successfully send ($_POST) a message to the user chosen.

    function sendtext() {
    // Account SID and Auth Token from Twilio
    $message_body = $_POST['message_body'];
    $receiver = $_POST['receiver'];
    $my_number = get_option( 'twilio_number' );
    $sid = get_option( 'twilio_account' );
    $token = get_option( 'twilio_auth_token' );
    $client = new Client($sid, $token);
    
    $client->messages->create(
        // the number you'd like to send the message to
        $receiver,
        array(
            'from' => $my_number,
            // the body of the text message you'd like to send
            'body' => $message_body
        )
    );
    }

    THE PROBLEM is calling the same function from my registration screen (script), to which I’ve added fields for mobile number and country.

    Just below the wp_mail() can to send the password change message, I’ve added a reference to the sendtext() function. I have separate numbers for Canada and the USA so I’ve attempted like below to route variables to the sendtext() object but each time I get an error that a message could not be sent because a “To: number” was not included. (But a look at the user profile shows that the number is saved.) $receiver is the “To:” of the error message.

    $user_country = $user->country;
    $receiver = $user->tel;
    /* Send Text to new user*/
     if ($user_country == 'CA'){
       $my_number = get_option( 'twilio_number' );
       $sid = get_option( 'twilio_account' );
       $token = get_option( 'twilio_auth_token' );
     }
     if ($user_country == 'USA'){
       $my_number = get_option( 'twilio_number_usa' );
       $sid = get_option( 'twilio_account_usa' );
       $token = get_option( 'twilio_auth_token' );
     }
      $my_number = $my_number;
      $sid = $sid;
      $token = $token;
      $receiver = $receiver;
      $message_body = $message;
     if(!empty($message)){
      sendtext();
     }

    I’d expect a notice that no message was added but not “no TO: number” since that’s from the user_meta and not a form.

    Any help in the proper structuring would be more than appreciated.

    Thanks.

    • This topic was modified 7 years, 1 month ago by starapple.
Viewing 8 replies - 1 through 8 (of 8 total)
  • Thread Starter starapple

    (@starapple)

    Apparently the problem has to do with the use of the namespacing alias ‘use’. It’s to alias a class name and has to be invoked on a page, outside of the function. The result of not having the class “Client” is that error messages don’t explain that you’re not including the class, but shows one related to the variables that are missing.

    In the end using the below as a function just doesn’t cut it:

    function sendtext() {
      global $sid, $token, $receiver, $my_number, $message_body;
    $client = new Client($sid, $token);
    // Use the client to do fun stuff like send text messages!
    $client->messages->create(
        // the number you'd like to send the message to
        $receiver,
        array(
            // A Twilio phone number you purchased at twilio.com/console
            'from' => $my_number,
            // the body of the text message you'd like to send
            'body' => $message_body
        )
    );
    }

    But if someone can explain how to pass the globals to an invocation of sendtext(), I’d be very happy.

    This is what I need to pass to sendtext():

     $user_country = $user->country;
      $receiver = $user->tel;
      $message_body = $message;
    
     if ($user_country == 'CA'){
       $my_number = get_option( 'twilio_number' );
       $sid = get_option( 'twilio_account' );
       $token = get_option( 'twilio_auth_token' );
     }
     if ($user_country == 'USA'){
       $my_number = get_option( 'twilio_number_usa' );
       $sid = get_option( 'twilio_account_usa' );
       $token = get_option( 'twilio_auth_token' );
     }
    sendtext()

    Thanks.

    • This reply was modified 7 years, 1 month ago by starapple.
    Moderator bcworkz

    (@bcworkz)

    Just declare the sendtext globals within the scope of your calling script.

    global $sid, $token, $receiver, $my_number, $message_body;
    $user_country = $user->country;
    $receiver = $user->tel;
    // etc....
    sendtext();
    Thread Starter starapple

    (@starapple)

    Thanks for the advice @bcworkz, but it doesn’t work. I end up with the uncaught Rest exception ‘[HTTP 400] Unable to create record: A ‘To’ phone number is required.’

    When the “defunctionalize” (new word?) the block of Twilio code, it works perfectly sending a link via text to the newly registered user.

    However, sendtext() hooked into a page in my dashboard accepts the number and message submitted in a form.

    I’ll use the clumsy method until I figure out how to use the function in the three instances I wish to in the site.

    Moderator bcworkz

    (@bcworkz)

    I was only answering your question about how to pass global values. I’ve no idea on the SMS aspect, sorry.

    I will say that $user->tel is not a default user property. Since the error is complaining of a missing To number, I suspect what ever code is getting this property is not working correctly.

    Thread Starter starapple

    (@starapple)

    Thanks again for your response @bcworkz. The problem is everything to do with passing values to the function. As I said, It works perfectly in another instance. To clarify, when I send the same values but don’t declare the block of code as a function, the messages are sent.

    I have added the custom user meta and it’s stored in the user_meta table fine. ALl else is OK. I added custom options on the settings page . Everything is stored and retrieved. The problem is calling sendtext() and passing it values. Even if I take the value from $_POST[‘tel’] the result is the same.

    No worries. Don’t go studying SMS now.

    • This reply was modified 7 years, 1 month ago by starapple.
    Moderator bcworkz

    (@bcworkz)

    I’d suggest var_dumping $receiver from within sendtext(). It may not be what you think it is. Maybe it needs to be run through trim() or stripslashes(). Does it matter if dashes are part of the number or not? Or parenthesis or pluses? Country code? Any of this can be easily adjusted if need be.

    Just random thoughts from one who knows nothing about what Twilio needs. No need to respond (but you can) since I’ve got nothing else to add at this point. Good luck!

    Thread Starter starapple

    (@starapple)

    I really appreciate your sticking with me @bcworkz, because this helkps to think it through. I know for sure that all the variable are accessible because, I said earlier, I successfully send and receive messages when I just don’t make the code into a function.

    With regular functions you make the variables globals so you can acess them outside the function. In this case, when all the variables are not within the function, declaring global does not extend their scope.

    As I’m a hobbyist really, I’m not clear how to format the function so that the variables can be passed by reference,

    $client = new Client($sid, $token);
     sendtext($client, $receiver, $my_number, $message_body){OPERATE on $client, $receiver, $my_number, $message_body}

    I have a feeling that that structure would work but the syntax I’m not clear on. Tomorrow I’ll give it another go after getting other matters out of the way.

    • This reply was modified 7 years, 1 month ago by starapple.
    • This reply was modified 7 years, 1 month ago by starapple.
    • This reply was modified 7 years, 1 month ago by starapple.
    • This reply was modified 7 years, 1 month ago by starapple.
    Moderator bcworkz

    (@bcworkz)

    I can’t help with getting Twilio to cooperate, but I do know something about PHP. I don’t know what OPERATE on is supposed to do, but I do know how to pass by reference. The normal process is to pass by value, which should be more than adequate in your case. Passing by value:

    function test( $value ) {
       $value = "Passed: $value";
       return $value;
    }
    $hello = 'Hello world';
    echo test( $hello );
    echo "<br>$hello";
    /* browser receives:
    Passed: Hello world
    Hello world
    */

    $value gets a copy of $hello, $hello is never affected by the function

    You can pass any number of parameters, but they need to be coordinated between the function declaration and caller. Another way to pass a large number of parameters is as an associative array of values, as is often done to instantiate classes with a large number of possible arguments. WP has a handy function that lets a function declaration specify a set of defaults and any arguments passed in the array are merged with the defaults so we don’t have to worry about any arguments not being set. See wp_parse_args() for an example.

    We don’t see pass by reference too much, but it’s very important when you need it because the function directly affects the original value in memory without the need to return anything. Very useful when you would need to otherwise return multiple values, which is just not possible. (but an array of values is a still single value that can be returned) Passed by reference (note the ‘&’):

    function test( &$reference ) {
       $reference['ten']++;
       $reference['twenty']--;
    }
    $array = array(
       'ten'=> 10,
       'twenty'=> 20,
    );
    test( $array );
    print_r( $array );
    /* Browser receives:
    Array
    (
        [ten] => 11
        [twenty] => 19
    )
    */

    $array is directly affected by the function. $reference is actually a pointer to the memory location of $array.

    I’m unsure how this will help you, but the difference between pass by value and pass by reference is an important programming concept.

Viewing 8 replies - 1 through 8 (of 8 total)
  • The topic ‘Integrating SMS Function With Registration’ is closed to new replies.