wordpresstwiliowordpress-rest-apitwilio-php

How to fix confusion between Twiml and TwiML - 'Invalid Content-Type' or 'retrieval failure'


I want to write a plugin for WordPress which says 'Hello World' for incoming calls to my Twillio phone-number. I set a POST webhook for incoming calls on Twilio admin: https://myWPsite.com/wp-json/callcenter/incoming. I created a WP-plugin with the following code (found in Twilio Docs), and placed the Twilio PHP helper lib into it's folder:

<?php
require_once( plugin_dir_path( __FILE__ ) . 'twilio-php-master/Twilio/autoload.php');
use Twilio\TwiML;

defined( 'ABSPATH' ) or die( 'Nope!' );

function respond_incoming( $data ) {
  $response = new TwiML;
  $response->say("hello world!", array('voice' => 'alice'));
  echo $response;
}

add_action( 'rest_api_init', function () {
  register_rest_route( 'callcenter', '/incoming/', array(
    'methods' => array('POST'),
    'callback' => 'respond_incoming',
  ) );
} );

If I make a phone call to my Twillio number, I see the following error in the Twilio-Debugger: Invalid Content-Type, and I see the following in the response body:

Warning: require(/wp-content/plugins/twilio-for-DNH/twilio-php-master/Twilio/TwiML.php): failed to open stream: No such file or directory in /wp-content/plugins/twilio-for-DNH/twilio-php-master/Twilio/autoload.php on line 140

Fatal error: require(): Failed opening required '/wp-content/plugins/twilio-for-DNH/twilio-php-master/Twilio/TwiML.php' (include_path='.:/opt/alt/php73/usr/share/pear') in /wp-content/plugins/twilio-for-DNH/twilio-php-master/Twilio/autoload.php on line 140

Solution

  • To solve this error, I changed use Twilio\TwiML; to use Twilio\Twiml;, although I read that Twiml is depracted, but I could not make it work another way.

    After this I still get Invalid Content-Type error, and I see in the debugger that the content type is:Content-Type application/json; charset=UTF-8. So I added the following line to my function: header('content-type: text/xml');.

    Now I get an Document parse failure error, and my response body looks the following:

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Say voice="alice">hello world!</Say>
    </Response>
    null
    

    To solve this, I added the die() function to the end of my function. And now finally it's works. The full working code is:

    <?php
    require_once( plugin_dir_path( __FILE__ ) . 'twilio-php-master/Twilio/autoload.php');
    use Twilio\Twiml;
    
    defined( 'ABSPATH' ) or die( 'Nope!' );
    
    function respond_incoming( $data ) {
      $response = new TwiML;
      $response->say("hello world!", array('voice' => 'alice'));
      header('content-type: text/xml');
      echo $response;
      die();
    }
    
    add_action( 'rest_api_init', function () {
      register_rest_route( 'callcenter', '/incoming/', array(
        'methods' => array('POST'),
        'callback' => 'respond_incoming',
      ) );
    } );