Using the Citrix Webinar API in WordPress

Final product image
What You'll Be Creating

Have you every used GoToWebinar from Citrix? No? Don't worry, you aren't alone. However, have you ever tried tying any service into WordPress? MailChimp, Mad Mimi, PayPal, Twitter? While these services differ in many specific, the general idea of how we can bring in data from external APIs into WordPress is the same. In this article I'll explore this through the eyes of an example integration with GoToWebinar from Citrix. 

What Is GoToWebinar?

GoToWebinar allows you to schedule live webcast events where the audience and presenters join a common user interface. The presenters can then share slides, their screen, their webcams and do all sorts of cool things. 

The service has been around for a while so the inevitable has happened: it now has an API—and a pretty good one at that. 

In a recent project I led, we wanted to keep the registrations on-site, and we also wanted registrant data available within WordPress. Without the API, this just isn't possible. By default, each webinar has a registration link which takes you off-site into GoToWebinar's system, where users register. It works just fine, but we didn't want to confuse users with this sudden jump. 

I thought I'd walk you through the process of how we achieved some of this using surprisingly little code!

Before We Begin

Before we dive into the abyss, you'll need a few things. You should have a GoToWebinar account, and you should also sign in to the Developer Center with your account. Once there, click on the big Add a new App button.

Follow the on-screen instructions and fill out all fields, making sure to select that you are building a GoToWebinar application. For the Application URL make sure to use https://api.citrixonline.com. You'll need to change this when using OAuth, but in our examples we'll be using direct login authentication, which makes this URL the best option. 

Logging In

Once your application has been created, note the Consumer Key. We will be using this later in our API calls. Otherwise, that's it for the setup, so now it's time to get our hands dirty. 

How to Work With REST APIs

APIs nowadays mostly follow REST guidelines, which stands for Representational State Transfer. Without going into the nitty-gritty, it boils down to a simple interface you can communicate with in a very natural way. 

As I mentioned, each API is different in its specifics, but the general way in which we use them is roughly the same:

  1. We need to authenticate our application in some way.
  2. We use HTTP calls to retrieve/send data.
  3. We store or use the retrieved data in our own application.

It really is that simple. If you've tried reading PayPal documentation from scratch (which is horrible), you may have found yourself under the impression that working with APIs is some terribly taxing process. I think part of the confusion comes from the difficulty of authentication and the fact that developers who are only familiar with PHP aren't really used to HTTP calls that are usually represented without any PHP code next to them. Let's clear all that up, shall we? 

Making HTTP Calls With WordPress

A prerequisite for everything we're about to do is making HTTP calls properly. Most of the time you'll see tutorials using CURL or just raw HTTP, but WordPress has us covered (as usual) with its HTTP API

Since HTTP calls can have a number of different parts, I thought it would be a good idea to delve into this a bit deeper. Let's look very briefly at what an HTTP request really is.

An HTTP request is submitted to a specific URL, and this is where API endpoints and specific routes come from. For example, the URL in the GoToWebinar documentation for getting all registrants for a webinar is:

Even if you have your actual Organizer Key and Webinar ID, using the URL is not enough. An HTTP request is more than just a URL. It contains a bunch of other information, chiefly a number of headers and maybe even a body.

This is pretty easy to understand when you are receiving data. Whenever you visit a website, your browser issues a request and gets an HTTP response. The response is not just the website you see before you. It contains a number of headers, like the status code, for example, which will probably be a 200 OK. The code that the browser interprets and displays for you is sent in the body of the response. 

Due to this, the documentation goes into some more detail—it gives an example HTTP request: 

This mess of strings is actually not that difficult to decipher. Even if you don't understand what everything is, you can pretty easily build this request with WordPress's native functions. 

It all starts with GET, which means this will be a get request. WordPress offers the wp_remote_get() function, which will work just fine. This is followed by the URL, which we'll pass as the first parameter to this function. Next we see the HTTP version, which can be set in the second argument which is an array of options. 

Everything afterwards is a header. The Accept header's value is application/json, the Content-Type header's value is application/json and so on. With this information in mind, let's craft our HTTP request in WordPress:

While this a specific example we'll look at in more detail soon, the takeaway point is this: HTTP requests are not that intimidating. You usually need to set a URL, some headers and in some cases a body, and that's it. You then receive some data back, usually in JSON form, which you can run through json_decode() and then use as a normal array or object. 

Now that we know the basic structure of an HTTP Request, let's figure out how to authenticate ourselves and be able to make any calls we want. 

Authenticating Our Citrix App

In this example I'll be looking at the direct login method of authentication. The flow for OAuth is slightly more complex, but the basics are the same—you just need to make two HTTP calls instead of one. 

That being said, I highly recommend using OAuth because it is more secure, and more and more APIs are integrating it, or even requiring it! 

The documentation for direct login makes what we want to achieve very clear. In fact, what I noticed in my own programming is that when I figured out how HTTP requests can be made easily, I found all API documentation a lot easier to comprehend. Hopefully this article will do the same for you!

According to the documentation, we can make a GET call to https://api.citrixonline.com/oauth/access_token with the appropriate Accept and Content-Type headers in addition to setting the grant_type, user_id and password URL parameters, and GoToWebinar will spit back our authentication credentials. Let's try that now:

Note that the values of all these parameters are fake. You will need to use the user_id (email) and password of an actual GoToWebinar account. The client_id should be the "Consumer Key" of your application, which we set up in the "Before We Begin" section above. 

If you use var_dump() to display the contents of the $http_request variable, you'll find that it is an array consisting of a number of members such as "headers", "body", "response" and so on. For our purposes the "body" holds the most important information: 

body section of vardump

As you may well have noticed, this is a JSON string which we'll need to convert to a usable form. Running it through json_decode() will give us a proper PHP array if we set the second parameter to true (otherwise it will be an array).

Out of all this data you'll need two things: the access_token and your organizer_key. The access token is your "temporary password". The idea is to prevent the need to send your actual password with every request—you request a temporary access token with your credentials only once, then use it to "sign" each subsequent request. 

Let's revisit our example from the HTTP Calls section, and perhaps the example will be a lot clearer now. Here is the same code with placeholders for all the information we now have:

The webinar_id in there comes from an actual webinar I've created in GoToWebinar, and you can find the ID in the URL at the very end. At this stage it should be clear where the data comes from, but in the example it's still essentially hard-coded—let's clear that right up!

Storing Authentication Data

Do we need to store authentication data, and does it expire? Yes and yes, and since the word "expire" was used in conjunction with "store", we're talking about a transient situation here, so enter the Transients API

If you have no idea what that is, worry not! It's quite simple—it allows you to store things using WordPress functions with a timestamp at which time the data expires. Let's write ourselves a mini class to be able to handle the creation of an access token simply. This will seem scary at first, but it's super-simple—explanation ensues!

What the heck is going on here?! There's a perfectly simple explanation—we want to write as little code as possible when handling actual HTTP calls. We already know that we need an access token for each one and that this access token will expire at some point. So for each and every call we make, we would need to check if the access token is valid. If it isn't, we would need to request a new one and then redo the original call. This class takes care of all that.

In the construct function, which runs as soon as an object is instantiated, I've hard-coded my client_id, user_id and password. In reality it is a good idea to use constants or even pass them to the construct function, but I just thought I'd make it all self-contained for this lesson. 

One more thing we need is a place to store the access credentials we receive from Citrix. I will be using a transient, and its name will be "citrix_access". I store this field name as a property of the class. Finally we run the set_access() method. 

This makes sure that we have valid credentials and stores them in the access property for easy access. How does it make sure everything is valid? It uses the get_access() method. This method retrieves the access credentials from our transient. If the transient is not empty, it returns the transient's value. If the transient is empty, it uses the request_access() method to get new credentials from Citrix, sets the transient value to the new credentials, and returns it as well. 

At this stage we have access credentials available to us, so we can start making requests. There is one other issue: the credentials on the Citrix side may have expired for safety reasons. If this is the case, our requests will come back with an error. Due to this, I've added a request_data() method which can handle this for us. 

This method contains almost the same code we wrote before, using the properties of the class to populate the call. Note that I've added some headers as defaults. These will most likely not change from call to call, removing the need to pass arguments in most cases. 

In addition, the method checks the body response. If it contains an error code, it generates new access credentials and recalls the method with the same parameters. 

Using Our New Class

Here's where our hard work pays off. To grab a list of registrants, here's all we need to do: 

We don't need to add any args, just the URL and we receive all the yummy data from Citrix right back. 

A note of warning: the class I've written is a very quick demonstration class. It works just fine for me right now, but I don't recommend using it as-is in production. Here are just some issues: 

  • As I mentioned, data is hard-coded into the constructor function. You should pass these to the class when instantiating, or perhaps use constants.
  • The error-checking on the request_data() function is not great. If the request fails for any other reason than an invalidated token, you may go into an infinite loop.
  • Right now the class is very platform-specific (it uses transients directly). In reality you would want to code to an interface.

As a case-in-point, the example is just fine, but just be cautious of errors when using it. 

A Third-Party Class

As always, someone has already been nice enough to make a class for us to use which is a lot more complete than the one I just showed you as a case study. Teodor Talov wrote a Wrapper Class for the Citrix APIs which is available via GitHub

I will be using his class to interact with GoToWebinar from this point on. To achieve the same thing we did above, you'll need some preparation and a few lines of code. First of all, using the class is easiest if you get it via Composer. Composer is super easy to install if you don't already have it—follow the Getting Started Guide and meet me back here in five minutes. 

Use the terminal or command prompt to go into the directory of your plugin and type the following command: 

This will grab the files you need and put them in the vendor directory. Then, within your plugin you'll need to include the autoload file like so:

That's it for preparation, so we can now use the class. Here's a snippet that will pull upcoming webinars from Citrix. 

Easy-peasy, right? With this more powerful class in our toolbelt, let's build something nice! Part of our plan was to use custom post types to store webinars to list them on-site. All we need is a meta field that stores the Citrix Webinar ID and we can pull everything else from Citrix, for example: the registrants. Let's create a meta box that lists a webinar's registrants now!

Listing Registrants in a Meta Box

Let's get the core WordPress stuff out of the way first: the meta box itself. Here's some code that will display an empty meta box with a nice title: 

You will of course need a custom post type with the name "webinar" to get this to show up. If you need to read up on that, we have a handy custom post type creation guide

I like to do a little HTML prototype of what the intended end result is, so let's do just that. Dummy data but a real UI. I plan on using Datatables, a jQuery table plugin, so I'll enqueue the scripts and styles for that as well. Here goes:  

This will create the markup we need and enqueue the styles. All we need to do is create js/app.js in our plugin with the following content:

The result should look something like the screenshot below. 

Registrants

It's not super-pretty, but I'll fix that by enqueuing another stylesheet and overwriting some of the defaults imposed by Datatables. The next step is to grab data from Citrix instead of faking it. 

I decided to use transients again to make sure we don't bombard Citrix with requests each time an edit webinar page is viewed. We'll grab the list of registrants and store them in a transient with an hour's worth of expiration time. This means that the list will only refresh each hour, but it does reduce our requests to one per hour instead of one per visit.

We'll also need to use a meta field for the webinar ID. I usually use Advanced Custom Fields, but since this is a simple example, let's just use the default custom fields option in WordPress and store a webinar ID in with the key webinar_id. Here's the final code:

A couple of things have happened here. First of all, I added a new stylesheet, just to add some visual distinction to the list which you'll see in the screenshot below. 

I then try to get the registrants list from the transients. If this returns empty, that means that the transient was either never set, or it has expired. If this is the case, we retrieve registrants and put them in a transient. 

We then loop through the registrants to populate the table, and we're all done! Here's what this all looks like with some added styles:

Registrants

Conclusion

And there you have it: data pulled from an external API, cached and displayed, all with native WordPress mechanisms and functions. While this takes some time to read and digest, especially if you are doing something like this for the first time, it really doesn't take very long once you wrap your head around it. 

In fact, once you have some experience with external APIs, most of your time will be spent figuring out what methods and options they have, not how to make HTTP requests and how to store data and so on. 

I can heartily recommend using the HTTP API coupled with the Transients API. It has proved to be a valuable and speedy asset in my toolbelt. 

Tags:

Comments

Related Articles