close
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <div id = "twilio-video-container" >     <div id = "agent-prompt" >         Speak with an Agent         <button id = "enter-queue" > Connect </button>         <div id = "wait-interstitial" style = "display:none" >         Connecting you to an agent         <div id = "conversation-view" style = "display:none;" >         <div id = "remote-media" >         <div id = "controls" >             <div id = "preview" >                 <div id = "local-media" >                     <!— /controls —>     Save that file and open your WordPress site in a browser.  You should see the plugin show up as a fixed element in the lower right corner of the site. Let’s look at the HTML template we added.  It has three basic parts to it: A that prompts the user to talk to an agent for support. A that tells the user they are connecting to an agent. A that shows the user andagent video streams allowing them to converse. As the user interacts with the plugin UI, we’ll use JavaScript to show and hide those different elements.  Open the twilio-video.js file where we’ll add that client side logic to our plugin.   To start, we first need to use jQuery to make an asynchronous request to get the contents of the twilio-video.html file and then append that HTML to the element of the web page. JavaScript jQuery(function() {     jQuery.ajax({ url: "/wp-content/plugins/twilio-video/twilio-video.html" }).done(function( content ) {         jQuery(content).appendTo('body');     }); }); 1 2 3 4 5 jQuery ( function ( ) {     jQuery . ajax ( { url : "/wp-content/plugins/twilio-video/twilio-video.html" } ) . done ( function ( content ) {         jQuery ( content ) . appendTo ( 'body' ) ;     } ) ; } ) ; Save the file and load up your WordPress site in browser to see the plugin UI come to life. Now that we’ve got a bit of UI for our plugin, let’s add some interactivity. Back in our JavaScript file, add a click handler to the enter-queue button.  When that button is clicked we will toggle the plugin UI to the next stage letting the user know that we’re connecting them to an agent. JavaScript jQuery(function() {     jQuery.ajax({ url: "/wp-content/plugins/twilio-video/twilio-video.html" }).done(function( content ) {         jQuery(content).appendTo('body');         document.getElementById('enter-queue').onclick = function () {             jQuery('#agent-prompt').toggle();             jQuery('#wait-interstitial').toggle();         };     }); }); 1 2 3 4 5 6 7 8 9 10 11 jQuery ( function ( ) {     jQuery . ajax ( { url : "/wp-content/plugins/twilio-video/twilio-video.html" } ) . done ( function ( content ) {         jQuery ( content ) . appendTo ( 'body' ) ;           document . getElementById ( 'enter-queue' ) . onclick = function ( ) {             jQuery ( '#agent-prompt' ) . toggle ( ) ;             jQuery ( '#wait-interstitial' ) .toggle ( ) ;         } ;       } ) ; } ) ; Refresh your browser, click the “Connect” button. Great, you’re being connected to an agent!  No, not really because we’ve not wired up Twilio Video yet.   In order to start a video conversation between the user and an agent we need to create a new Conversation Client for the user and have that client begin listening for conversation invitations.  We want to do that only when the user presses “Connect” telling us they want to talk to an agent. Creating a Conversation Client requires an  which encapsulates the identity of the client and the credentials they need to authenticate with Twilio.  Creating an Access Token requires Twilio secrets.  To help keep those secrets well, secret, we’ll generate the token on the server and expose it via a REST API that can be called by our JavaScript. WordPress already exposes its own  and makes it really easy to add your own endpoints to it.  Pop open twilio-video.php again and use the add_action function towire up the  action. PHP define('TWILIO_VIDEO_PLUGIN_URL', plugin_dir_url(__FILE__)); add_action( 'wp_enqueue_scripts', 'twilio_video_enqueue_scripts' ); add_action( 'rest_api_init', 'twilio_video_register_api_routes' ); 1 2 3 define ( 'TWILIO_VIDEO_PLUGIN_URL' , plugin_dir_url ( __FILE__ ) ) ; add_action ( 'wp_enqueue_scripts' , 'twilio_video_enqueue_scripts' ) ; add_action ( 'rest_api_init' , 'twilio_video_register_api_routes' ) ; This action gets called when WordPress initializes its REST API and gives us a chance to register our own routes using the  function. PHP function twilio_video_register_api_routes() {     $namespace = 'twilio-video-api/v1';     register_rest_route( $namespace, '/twilio-video-token/', array(         'methods' => 'GET',         'callback' => 'twilio_video_get_token')     ); } 1 2 3 4 5 6 7 function twilio_video_register_api_routes ( ) {     $namespace = 'twilio-video-api/v1' ;     register_rest_route ( $namespace , '/twilio-video-token/' , array (        'methods' = > 'GET' ,         'callback' = > 'twilio_video_get_token' )     ) ; } Here we are telling WordPress to register a route that responds to GET requests at the path /wp-json/twilio-video-api/v1/twilio-video-token/.  When a request is made to that URL, WordPress calls the twilio_video_get_token function which uses the twilio-php helper library to generate a new Access Token that contains a  allowing the client to participate in a Video Conversation.  This token along with a randomly chosen identity is returned as a JSON object from the function. PHP function twilio_video_get_token() {     require_once ('lib/Twilio/Twilio.php');     require_once ('randos.php');     // An identifier for your app - can be anything you'd like     $appName = 'TwilioVideoDemo';     // choose a random username for the connecting user     $identity = randomUsername();     // Create access token, which we will serialize and send to the client     $token = newServices_Twilio_AccessToken(         /*$TWILIO_ACCOUNT_SID, */         /*$TWILIO_API_KEY, */         /*$TWILIO_API_SECRET, */         3600,         $identity     );              // Grant access to Conversations     $grant = new Services_Twilio_Auth_ConversationsGrant();     $grant->setConfigurationProfileSid(/*$TWILIO_CONFIGURATION_SID*/);     $token->addGrant($grant);     $return = array(         'identity' => $identity,         'token' => $token->toJWT(),     );     $response = new WP_REST_Response( $return );     return $response; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 function twilio_video_get_token ( ) {     require_once ( 'lib/Twilio/Twilio.php' ) ;     require_once ( 'randos.php' ) ;       // An identifier for your app - can be anything you'd like     $appName = 'TwilioVideoDemo' ;       // choose a random username for the connecting user     $identity = randomUsername ( ) ;       // Create access token,which we will serialize and send to the client     $token = new Services_Twilio_AccessToken (         /*$TWILIO_ACCOUNT_SID, */         /*$TWILIO_API_KEY, */         /*$TWILIO_API_SECRET, */         3600 ,         $identity     ) ;              // Grant access to Conversations     $grant = new Services_Twilio_Auth_ConversationsGrant ( ) ;     $grant -> setConfigurationProfileSid ( /*$TWILIO_CONFIGURATION_SID*/ ) ;     $token -> addGrant ( $grant ) ;       $return = array (         'identity' = > $identity ,         'token' = > $token -> toJWT ( ) ,     ) ;       $response = new WP_REST_Response ( $return ) ;     return $response ; } With the code in place the last thing we need to do is add our Twilio secrets.  The secrets we need are: Account SID API Key SID API Secret Configuration Profile SID To get all of these secrets we’ll need to head on over to the  section of the Twilio Developer Console.  Once there grab your Account SID: Next create a new . A Configuration Profile is a setof configuration values for webhooks and other options for Programmable Video. Drop in a Friendly Name for your Configuration Profile, click Save and grab the RTC Profile SID: Finally we need an .  These are used to authenticate our Conversation Client with Twilio.  Create a new API Key and grab its SID and Secret: Put your Twilio secrets into the PHP code and give your new WordPress REST API endpoint a spin by opening up a browser pointed to the API URL.   Fantastic!  Now we can get back to creating that video conversation. Back in twilio-video.js we’ll reach for jQuery again to grab a newly generated Access Token from the API we just created.  Using that token, create a new  object to pass into the  objects constructor. JavaScript var conversationsClient; jQuery(function() {     jQuery.ajax({ url: "/wp-content/plugins/twilio-video/twilio-video.html" }).done(function( content ) {         jQuery(content).appendTo('body');         document.getElementById('enter-queue').onclick= function () {             jQuery('#agent-prompt').toggle();             jQuery('#wait-interstitial').toggle();         };         jQuery.getJSON('/wp-json/twilio-video-api/v1/twilio-video-token', function(data) {             identity = data.identity;             var accessManager = new Twilio.AccessManager(data.token);             // Check the browser console to see your generated identity.             // Send an invite to yourself if you want!             console.log(identity);             // Create a Conversations Client and connect to Twilio             conversationsClient = new Twilio.Conversations.Client(accessManager);         });     }); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 var conversationsClient ;   jQuery ( function ( ) {     jQuery . ajax ( { url : "/wp-content/plugins/twilio-video/twilio-video.html" } ) . done ( function ( content ) {         jQuery ( content ) . appendTo ( 'body' ) ;           document . getElementById( 'enter-queue' ) . onclick = function ( ) {             jQuery ( '#agent-prompt' ) . toggle ( ) ;             jQuery ( '#wait-interstitial' ) . toggle ( ) ;         } ;           jQuery . getJSON ( '/wp-json/twilio-video-api/v1/twilio-video-token' , function ( data ) {             identity = data . identity ;             var accessManager = new Twilio . AccessManager ( data . token ) ;               // Check the browser console to see your generated identity.             // Send an invite to yourself if you want!             console . log ( identity ) ;               // Create a Conversations Client and connect to Twilio             conversationsClient = new Twilio . Conversations . Client ( accessManager ) ;         } ) ;     } ) ; } ) ; Once we have an instance of a Conversation Client we tell it to connect to Twilio and start  for incoming conversation invitations. JavaScript // Create a Conversations Client and connect to Twilio conversationsClient = newTwilio.Conversations.Client(accessManager); conversationsClient.listen().then(function() {     console.log("Connected to Twilio. Listening for incoming Invites as '" conversationsClient.identity "'"); }, function (error) {     console.log('Could not connect to Twilio: ' error.message); }); 1 2 3 4 5 6 7 // Create a Conversations Client and connect to Twilio conversationsClient = new Twilio . Conversations . Client ( accessManager ) ; conversationsClient . listen ( ) . then ( function ( ) {     console . log ( "Connected to Twilio. Listening for incoming Invites as '"    conversationsClient . identity    "'" ) ; } , function ( error ) {     console . log ( 'Could not connect to Twilio: '    error . message ) ; } ) ; The final step is to handle the incoming invitation and let the user and agent actually converse.  To do that we’ll wire up the Conversation Clients  event handler.  This event hands us an  object which we’ll use to have the client automatically accept theinvitation.  Once the invite is accepted we’re ready to start the call which we do by calling the conversationStarted function. JavaScript conversationsClient.listen().then(function() {     console.log("Connected to Twilio. Listening for incoming Invites as '" conversationsClient.identity "'");     conversationsClient.on('invite', function (invite) {         console.log('Incoming invite from: ' invite.from);         invite.accept().then(conversationStarted);     }); }, function (error) {     console.log('Could not connect to Twilio: ' error.message); }); 1 2 3 4 5 6 7 8 9 10 11 conversationsClient . listen ( ) . then ( function ( ) {     console . log ( "Connected to Twilio. Listening for incoming Invites as '"    conversationsClient . identity    "'" ) ;       conversationsClient . on ( 'invite' , function ( invite ) {         console . log ( 'Incoming invite from: '    invite . from ) ;         invite . accept ( ) . then ( conversationStarted ) ;     } ) ;   } ,function ( error ) {     console . log ( 'Could not connect to Twilio: '    error . message ) ; } ) ; The conversationStarted function starts by swapping the plugin UI to the conversation view, and using the  function of the object exposed by the provided  object, directs the local video stream into the plugin UI. It also starts to listen for the  event which will fire once the agent who invited the user begins to stream their video.  When that event fires the plugin uses the attach function of the  object exposed by the  object passed into the event to direct that video stream into the plugin UI. Finally, the function starts listening for the conversations  and disconnected events which tell it to reset the plugin back to its original state. JavaScript var activeConversation; var previewMedia; function conversationStarted(conversation) {     jQuery('#wait-interstitial').toggle();     jQuery('#conversation-view').toggle();              console.log('In an activeConversation');     activeConversation = conversation;     // Draw local video, if not already previewing     if (!previewMedia) {         conversation.localMedia.attach('#local-media');     }     // When a participant joins, draw their video on screen     conversation.on('participantConnected', function (participant) {         console.log("Participant '" participant.identity "' connected");         participant.media.attach('#remote-media');     });     // When a participant disconnects, note in log     conversation.on('participantDisconnected', function (participant) {         console.log("Participant '" participant.identity "' disconnected");     });     // When the conversation ends, stop capturing local video     conversation.on('disconnected', function (conversation) {         console.log("Connected to Twilio. Listening for incoming Invites as '" conversationsClient.identity "'");         conversation.localMedia.stop();        conversation.disconnect();         activeConversation = null;     }); }; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 var activeConversation ; var previewMedia ;   function conversationStarted ( conversation ) {       jQuery ( '#wait-interstitial' ) . toggle ( ) ;     jQuery ( '#conversation-view' ) . toggle ( ) ;              console . log ( 'In an active Conversation' ) ;     activeConversation = conversation ;       // Draw local video, if not already previewing     if ( ! previewMedia ) {         conversation . localMedia . attach ( '#local-media' ) ;     }       // When a participant joins, draw their video on screen     conversation . on ( 'participantConnected' , function ( participant ) {         console . log ( "Participant '"    participant . identity    "' connected" ) ;         participant . media . attach ( '#remote-media' ) ;     } ) ;       // When a participant disconnects, note in log     conversation . on ('participantDisconnected' , function ( participant ) {         console . log ( "Participant '"    participant . identity    "' disconnected" ) ;     } ) ;       // When the conversation ends, stop capturing local video     conversation . on ( 'disconnected' , function ( conversation ) {         console . log ( "Connected to Twilio. Listening for incoming Invites as '"    conversationsClient . identity    "'" ) ;         conversation . localMedia . stop ( ) ;         conversation . disconnect ( ) ;         activeConversation = null ;     } ) ; } ; That completes the code for our video chat plugin.  To give it an end-to-end test, reload your browser and press the “Connect” button to have the client wait for a conversation invite.  Open up the developer console in your browser and grab the identity that was logged to it.  We’ll need that in order to have the agent know what client to invite. To test the role of the Agent head back into the Programmable Video section of the DeveloperConsole and open up the Testing Tools section of the Dev Tools tab.  These testing tools allow you to create a Conversation Client connected to your Configuration Profile and invite another client into a conversation. Enter a name like “Agent” into the Client Identity field, select your Configuration Profile from the drop down and click the Generate Token button.   Now scroll down, enter the identity you grabbed earlier from the browser’s console and click the Create Conversation button.   This will send an invite to the client running in the browser plugin and start a video conversation between the testing tools and your WordPress user. Congratulations!  You now have Video Chat plugin that you can drop into any WordPress powered site. Wrapup WordPress underlies an impressive number of websites and is used to build everything from personal blogs to full featured e-commerce applications.  If you or your company use it as the foundation of a website, adding Twilio-powered video chat is ahigh-fidelity way to connect with your customers.  Plugins are a great way to enhance your site with this capability. In this post I showed how with a bit of PHP and JavaScript you can build a plugin that inserts Twilio Video Chat.  The sample in this post is just the start of what you could do with Twilio Video and WordPress.   and start experimenting. Some cool ways you could continue this project would be adding video controls to the plugin UI, integrating the WordPress user system into the plugin so the Agent knows which customer is calling, and even integrating  to route incoming video calls to the right available agent. I’d love to see where you take Twilio Video and WordPress. Drop me an or hit me up on  with your hacks.
gfi endpoint security 4     gfi endpoint security 2013
close