Usando la API de seminario web de Citrix en WordPress

Lo que vas a crear

¿Ha utilizado GoToWebinar de Citrix? ¿No? No te preocupes, no estás solo. Sin embargo, ¿alguna vez has intentado vincular algún servicio a WordPress? MailChimp, Mad Mimi, PayPal, Twitter? Si bien estos servicios difieren en muchos aspectos específicos, la idea general de cómo podemos traer datos de API externas a WordPress es la misma. En este artículo, exploraré esto a través de los ojos de un ejemplo de integración con GoToWebinar de Citrix. 

¿Qué es GoToWebinar??

GoToWebinar le permite programar eventos de transmisión web en vivo donde la audiencia y los presentadores se unen a una interfaz de usuario común. Los presentadores pueden compartir diapositivas, su pantalla, sus cámaras web y hacer todo tipo de cosas interesantes.. 

El servicio ha existido por un tiempo, así que ha ocurrido lo inevitable: ahora tiene una API y una muy buena.. 

En un proyecto reciente que dirigí, queríamos mantener los registros en el sitio, y también queríamos que los datos de registrantes estuvieran disponibles dentro de WordPress. Sin la API, esto simplemente no es posible. De forma predeterminada, cada seminario web tiene un enlace de registro que lo lleva fuera del sitio al sistema de GoToWebinar, donde los usuarios se registran. Funciona bien, pero no queríamos confundir a los usuarios con este salto repentino. 

Pensé que te guiaría en el proceso de cómo conseguimos algo de esto utilizando un código sorprendentemente pequeño!

Antes de que comencemos

Antes de sumergirnos en el abismo, necesitarás algunas cosas. Debes tener una cuenta de GoToWebinar y también debes iniciar sesión en el Centro de desarrolladores con tu cuenta. Una vez allí, haga clic en el gran Añadir una nueva aplicación botón.

Siga las instrucciones en pantalla y complete todos los campos, asegurándose de seleccionar que está creando una aplicación GoToWebinar. Para el URL de aplicación asegúrate de usar https://api.citrixonline.com. Tendrá que cambiar esto cuando use OAuth, pero en nuestros ejemplos usaremos la autenticación de inicio de sesión directo, lo que hace que esta URL sea la mejor opción.

Una vez que se haya creado su aplicación, tenga en cuenta la Clave del consumidor. Usaremos esto más adelante en nuestras llamadas a la API. De lo contrario, eso es todo para la configuración, así que ahora es el momento de ensuciarnos las manos. 

Cómo trabajar con las API REST

Las API hoy en día siguen en su mayoría las pautas de REST, que significa Representational State Transfer. Sin entrar en lo esencial, se reduce a una interfaz simple con la que puede comunicarse de una manera muy natural.. 

Como mencioné, cada API es diferente en sus aspectos específicos, pero la forma general en que las usamos es aproximadamente la misma:

  1. Necesitamos autenticar nuestra aplicación de alguna manera..
  2. Usamos llamadas HTTP para recuperar / enviar datos.
  3. Almacenamos o utilizamos los datos recuperados en nuestra propia aplicación..

Es realmente así de simple. Si ha intentado leer la documentación de PayPal desde cero (lo que es horrible), es posible que se haya encontrado con la impresión de que trabajar con API es un proceso terriblemente agotador. Creo que parte de la confusión proviene de la dificultad de la autenticación y el hecho de que los desarrolladores que solo están familiarizados con PHP no están realmente acostumbrados a las llamadas HTTP que generalmente están representadas sin ningún código PHP a su lado. Vamos a aclarar todo eso, vamos a? 

Hacer llamadas HTTP con WordPress

Un requisito previo para todo lo que estamos por hacer es hacer las llamadas HTTP correctamente. La mayoría de las veces verás tutoriales utilizando CURL o solo HTTP sin formato, pero WordPress nos cubre (como es habitual) con su API HTTP. 

Como las llamadas HTTP pueden tener varias partes diferentes, pensé que sería una buena idea profundizar un poco más en esto. Veamos brevemente lo que realmente es una solicitud HTTP.

Una solicitud HTTP se envía a una URL específica, y aquí es donde los puntos finales de la API y las rutas específicas provienen. Por ejemplo, la URL en la documentación de GoToWebinar para obtener todos los solicitantes de registro para un seminario web es:

https://api.citrixonline.com/G2W/rest/organizers/organizerKey/webinars/webinarKey/registrants

Incluso si tiene su clave de organizador real y su ID de seminario web, usar la URL no es suficiente. Una solicitud HTTP es más que solo una URL. Contiene un montón de otra información, principalmente un número de encabezados y tal vez incluso un cuerpo.

Esto es bastante fácil de entender cuando está recibiendo datos. Cada vez que visita un sitio web, su navegador emite una solicitud y obtiene una respuesta HTTP. La respuesta es no Sólo el sitio web que ves ante ti. Contiene una serie de encabezados, como el código de estado, por ejemplo, que probablemente será un 200 OK. El código que el navegador interpreta y muestra para usted se envía en el cuerpo de la respuesta. 

Debido a esto, la documentación incluye algunos detalles más: proporciona una solicitud HTTP de ejemplo: 

OBTENGA https://api.citrixonline.com/G2W/rest/organizers/7913299991555673093/webinars/2575999967611407361/registrants HTTP / 1.1 Acepta: las partes de los cuadros de las partes de las partes.

Este lío de cadenas no es tan difícil de descifrar. Incluso si no entiende lo que es todo, puede generar esta solicitud fácilmente con las funciones nativas de WordPress. 

Todo comienza con OBTENER, lo que significa que esta será una solicitud de obtención. WordPress ofrece la wp_remote_get () Función, que funcionará bien. A esto le sigue la URL, que pasaremos como primer parámetro a esta función. A continuación vemos la versión HTTP, que se puede establecer en el segundo argumento que es una matriz de opciones. 

Todo después es un encabezado. los Aceptar el valor del encabezado es aplicación / json, la Tipo de contenido el valor del encabezado es aplicación / json y así. Con esta información en mente, diseñemos nuestra solicitud HTTP en WordPress:

$ url = 'https://api.citrixonline.com/G2W/rest/organizers/7215599994255673093/webinars/2575945029611407361/registrants'; $ args = array ('httpversion' => '1.1', 'headers' => array ('Accept' => 'application / json', 'Content-Type' => 'application / json', 'Autorización' => 'OAuth oauth_token = hdKAifAke73gh885ghJTJR5GA4kp')); $ http_request = wp_remote_get ($ url, $ args);

Si bien este es un ejemplo específico que veremos en más detalle pronto, el punto clave es este: las solicitudes HTTP no son tan intimidantes. Por lo general, es necesario establecer una URL, algunos encabezados y, en algunos casos, un cuerpo, y eso es todo. A continuación, recibe algunos datos de vuelta, generalmente en forma JSON, que puede ejecutar json_decode () y luego usar como una matriz u objeto normal. 

Ahora que conocemos la estructura básica de una solicitud HTTP, averigüemos cómo autenticarnos y poder realizar las llamadas que deseamos.. 

Autentificando nuestra aplicación Citrix

En este ejemplo, veré el método de autenticación de inicio de sesión directo. El flujo para OAuth es un poco más complejo, pero lo básico es el mismo: solo necesita hacer dos llamadas HTTP en lugar de una.. 

Dicho esto, recomiendo encarecidamente el uso de OAuth porque es más seguro, y cada vez más API lo integran, o incluso lo requieren.! 

La documentación para el inicio de sesión directo hace que lo que queremos lograr sea muy claro. De hecho, lo que noté en mi propia programación es que cuando descubrí cómo las solicitudes HTTP se pueden hacer fácilmente, encontré toda la documentación de la API como un mucho más fácil de comprender. Esperemos que este artículo haga lo mismo por ti.!

Según la documentación, podemos hacer una OBTENER llamar a https://api.citrixonline.com/oauth/access_token con el apropiado Aceptar y Tipo de contenido encabezados, además de establecer la grant_type, user_id y contraseña Parámetros de URL, y GoToWebinar volverá a escupir nuestras credenciales de autenticación. Intentemos eso ahora:

$ url = 'https://api.citrixonline.com/oauth/[email protected]&password=mysecretpass&client_id=mycitrixapikey'; $ args = array ('headers' => array ('Accept' => 'application / json', 'Content-Type' => 'application / json')); $ http_request = wp_remote_get ($ url, $ args);

Tenga en cuenta que los valores de todos estos parámetros son falsos. Tendrá que usar el user_id (correo electrónico) y la contraseña de una cuenta real de GoToWebinar. los Identificación del cliente debe ser la "Clave del consumidor" de su aplicación, que configuramos en la sección "Antes de comenzar" de arriba. 

Si utiliza var_dump () para visualizar los contenidos de la $ http_request variable, encontrará que se trata de una matriz que consta de varios miembros, como "encabezados", "cuerpo", "respuesta", etc. Para nuestros propósitos, el "cuerpo" contiene la información más importante: 

Como bien habrá notado, esta es una cadena JSON que deberemos convertir a una forma utilizable. Pasándolo por json_decode () nos dará una matriz PHP adecuada si establecemos el segundo parámetro en verdadero (de lo contrario, será una matriz).

$ body = json_decode ($ http_request, true);

De todos estos datos necesitarás dos cosas: la access_token y tu organizer_key. El token de acceso es su "contraseña temporal". La idea es evitar la necesidad de enviar sus real contraseña con cada solicitud: usted solicita un token de acceso temporal con sus credenciales solo una vez, luego lo usa para "firmar" cada solicitud subsiguiente. 

Revisemos nuestro ejemplo de la sección de Llamadas HTTP, y quizás el ejemplo ahora sea mucho más claro. Aquí está el mismo código con marcadores de posición para toda la información que ahora tenemos:

$ organizer_key = '2893726'; $ webinar_id = '849927254829281838'; $ access_token = 'h7dwo20vAsXI8GLaGvun0wOJ6H5I'; $ url = "https://api.citrixonline.com/G2W/rest/organizers/$organizer_key/webinars/$webinar_id/registrants"; $ args = array ('httpversion' => '1.1', 'headers' => array ('Accept' => 'application / json', 'Content-Type' => 'application / json', 'Autorización' => "OAuth oauth_token = $ access_token")); $ http_request = wp_remote_get ($ url, $ args);

los webinar_id ahí viene de un seminario web real que he creado en GoToWebinar, y puede encontrar la ID en la URL al final. En esta etapa debe quedar claro dónde Los datos provienen de, pero en el ejemplo es esencialmente un código duro, aclarémoslo hasta!

Almacenamiento de datos de autenticación

¿Necesitamos almacenar datos de autenticación, y caducan? Sí y sí, y como la palabra "expirar" se usó junto con "almacén", estamos hablando de una situación transitoria aquí, así que ingrese la API de transitorios. 

Si no tienes idea de qué es eso, ¡no te preocupes! Es bastante simple: le permite almacenar cosas utilizando las funciones de WordPress con una marca de tiempo en la que los datos caducan. Escribamos una mini clase para poder manejar la creación de un token de acceso simplemente. Esto parecerá aterrador al principio, pero es una explicación súper simple.!

clase Citrix_WP var $ client_id; var $ password; var $ user_id; var $ acceso; función __construct () $ this-> client_id = 'sI48T4iXP0J6720G9wAB0Ghfg37576301'; $ this-> user_id = '[email protected]'; $ this-> password = 'superpassword'; $ this-> access_field = 'citrix_access'; $ this-> set_access ();  función set_access () $ access = $ this-> get_access (); $ this-> access = $ access;  función get_access () $ access = get_transient ($ this-> access_field); if (vacío ($ acceso)) $ acceso = $ esto-> request_access (); $ this-> set_access_transient ($ access);  devolver $ acceso;  función set_access_transient ($ access) set_transient ($ this-> access_field, $ access, DAY_IN_SECONDS);  function request_data ($ url, $ args = array ()) $ defaults = array ('httpversion' => '1.1', 'headers' => array ('Accept' => 'application / json', 'Content- Escriba '=>' application / json ',' Autorización '=>' OAuth oauth_token = ". $ This-> access [" access_token '])); $ args = wp_parse_args ($ args, $ defaults); $ http_request = wp_remote_get ($ url, $ args); $ body = json_decode ($ http_request ['body'], true); if (! empty ($ body ['int_err_code'])) $ this-> get_access (); $ this-> request_data ($ url, $ args);  else return $ body;  function request_access () $ url = 'https://api.citrixonline.com/oauth/access_token?grant_type=password&user_id='. $ this-> user_id. '& contraseña ='. $ esta-> contraseña. '& client_id ='. $ this-> client_id; $ args = array ('headers' => array ('Accept' => 'application / json', 'Content-Type' => 'application / json')); $ result = wp_remote_get ($ url, $ args); devuelve json_decode ($ resultado ['cuerpo'], verdadero); 

¿Qué diablos está pasando aquí? Hay una explicación perfectamente simple: queremos escribir el menor código posible al manejar llamadas HTTP reales. Ya sabemos que necesitamos un token de acceso para cada uno y que este token de acceso caducará en algún momento. Por lo tanto, para cada una de las llamadas que hagamos, deberíamos comprobar si el token de acceso es válido. Si no es así, deberíamos solicitar una nueva y luego rehacer la llamada original. Esta clase se encarga de todo eso..

En la función de construcción, que se ejecuta tan pronto como se crea una instancia de un objeto, he codificado mi código Identificación del cliente, user_id y contraseña. En realidad, es una buena idea usar constantes o incluso pasarlas a la función de construcción, pero simplemente pensé que lo haría todo autónomo para esta lección.. 

Una cosa más que necesitamos es un lugar para almacenar las credenciales de acceso que recibimos de Citrix. Usaré un transitorio, y su nombre será "citrix_access". Almaceno este nombre de campo como una propiedad de la clase. Finalmente ejecutamos el set_access () método. 

Esto asegura que tengamos credenciales válidas y las almacenemos en el acceso Propiedad para fácil acceso. ¿Cómo se asegura de que todo sea válido? Utiliza el tener acceso() método. Este método recupera las credenciales de acceso de nuestro transitorio. Si el transitorio no está vacío, devuelve el valor del transitorio. Si el transitorio está vacío, usa el solicitar acceso() método para obtener nuevas credenciales de Citrix, establece el valor transitorio a las nuevas credenciales y lo devuelve también. 

En esta etapa, tenemos credenciales de acceso disponibles para que podamos comenzar a realizar solicitudes. Hay otro problema: las credenciales en el lado de Citrix pueden haber caducado por razones de seguridad. Si este es el caso, nuestras solicitudes volverán con un error. Debido a esto, he añadido un request_data () Método que puede manejar esto por nosotros.. 

Este método contiene casi el mismo código que escribimos anteriormente, utilizando las propiedades de la clase para completar la llamada. Tenga en cuenta que he añadido algunos encabezados por defecto. Es muy probable que estos no cambien de una llamada a otra, eliminando la necesidad de pasar argumentos en la mayoría de los casos. 

Además, el método verifica la respuesta del cuerpo. Si contiene un código de error, genera nuevas credenciales de acceso y recuerda el método con los mismos parámetros. 

Usando nuestra nueva clase

Aquí es donde nuestro trabajo duro da sus frutos. Para obtener una lista de los solicitantes de registro, esto es todo lo que necesitamos hacer: 

$ citrix = nuevo Citrix_WP; $ registrants = $ citrix-> request_data ('https://api.citrixonline.com/G2W/rest/organizers/'. $ citrix-> access ['organizer_key']. '/ webinars / 849927252521582337 / registrants');

No necesitamos agregar argumentos, solo la URL y recibimos todos los datos deliciosos de Citrix.. 

Una nota de advertencia: la clase que he escrito es una clase de demostración muy rápida. Funciona bien para mí ahora mismo, pero no recomiendo usarlo tal como está en producción. Aquí hay algunos problemas: 

  • Como mencioné, los datos están codificados en la función de constructor. Debe pasar estos a la clase al crear instancias, o tal vez usar constantes.
  • La comprobación de errores en el request_data () La función no es genial. Si la solicitud falla por cualquier otro motivo que no sea un token invalidado, puede ingresar a un bucle infinito.
  • En este momento, la clase es muy específica de la plataforma (usa transitorios directamente). En realidad querrías codificar a una interfaz.

Como ejemplo, el ejemplo está bien, pero tenga cuidado con los errores al usarlo. 

Una clase de terceros

Como siempre, alguien ya ha tenido la amabilidad de hacer una clase para nosotros, que es mucho más completa que la que acabo de mostrarte como un caso de estudio. Teodor Talov escribió una Clase Wrapper para las API de Citrix que está disponible a través de GitHub. 

Usaré su clase para interactuar con GoToWebinar a partir de este momento. Para lograr lo mismo que hicimos anteriormente, necesitará algo de preparación y algunas líneas de código. En primer lugar, usar la clase es más fácil si lo obtiene a través de Composer. Composer es muy fácil de instalar si aún no lo tiene, siga la Guía de introducción y reúnase conmigo aquí en cinco minutos.. 

Use el terminal o el símbolo del sistema para ir al directorio de su complemento y escriba el siguiente comando: 

compositor requiere teodortalov / citrix

Esto capturará los archivos que necesita y los colocará en el directorio de proveedores. Luego, dentro de tu plugin deberás incluir el archivo de carga automática así:

include (plugin_dir_path (__FILE__). '/vendor/autoload.php');

Eso es todo para la preparación, así que ahora podemos usar la clase. Aquí hay un fragmento que extraerá los próximos seminarios web de Citrix. 

$ client = new \ Citrix \ Authentication \ Direct ('sI48T4iXP0J6720G9wAB0GHIHiIoyw20'); $ client-> auth ('[email protected]', 'gnasher1'); $ goToWebinar = new \ Citrix \ GoToWebinar ($ client); $ webinars = $ goToWebinar-> getUpcoming ();

Easy-peasy, ¿verdad? Con esta clase más poderosa en nuestro cinturón de herramientas, ¡construyamos algo bueno! Parte de nuestro plan era utilizar tipos de publicaciones personalizadas para almacenar seminarios web para enumerarlos en el sitio. Todo lo que necesitamos es un metacampo que almacene el ID de seminario web de Citrix y podemos extraer todo lo demás de Citrix, por ejemplo: los solicitantes de registro. Vamos a crear un cuadro de meta que enumera los registrantes de un seminario web ahora!

Listado de solicitantes de registro en una caja de Meta

Dejemos de lado las cosas principales de WordPress: la meta box en sí misma. Aquí hay un código que mostrará una meta caja vacía con un buen título: 

function my_registrants_metabox () add_meta_box ('webinar_registrants', 'Registrants', 'my_registrants_metabox_content', 'webinar');  function my_registrants_metabox_content ($ post) // Aquí hay contenido de metabox. 

Por supuesto, necesitará un tipo de publicación personalizada con el nombre "webinar" para que aparezca. Si necesita leer más sobre eso, tenemos una guía de creación de tipo de publicación personalizada.. 

Me gusta hacer un pequeño prototipo HTML de cuál es el resultado final previsto, así que hagámoslo. Datos ficticios pero una interfaz de usuario real. Planeo usar Datatables, un complemento de la tabla jQuery, así que también pondré en cola los scripts y los estilos para eso. Aquí va:  

function my_backend_assets () wp_register_script ('datatables', '//cdn.datatables.net/1.10.7/js/jquery.dataTables.min.js', array ('jquery', 'customselect'), '1.0' cierto ); wp_register_style ('datatables', '//cdn.datatables.net/1.10.7/css/jquery.dataTables.min.css'); wp_enqueue_script ('my-app', plugin_dir_path (__FILE__). '/js/app.js', array ('datatables'), '1.0', true);  function my_registrants_metabox () add_meta_box ('webinar_registrants', 'Registrants', 'my_registrants_metabox_content', 'webinar');  function my_registrants_metabox_content ($ post) wp_enqueue_script ('datatables'); wp_enqueue_style ('datatables'); ?> 
';
Nombre de pila Apellido Email Fecha Zona
Daniel Pataki [email protected] 2015-08-12 Nueva York
Alguien Más [email protected] 2015-08-13 París

Esto creará el marcado que necesitamos y encolará los estilos. Todo lo que necesitamos hacer es crear js / app.js en nuestro plugin con el siguiente contenido:

(function ($) $ (document) .ready (function ($) $ ('.my-data-table table') .DataTable (););) (jQuery);

El resultado debería ser similar a la captura de pantalla de abajo.. 

No es súper bonito, pero lo arreglaré agregando otra hoja de estilo y sobrescribiendo algunos de los valores predeterminados impuestos por Datatables. El siguiente paso es capturar datos de Citrix en lugar de falsificarlos. 

Decidí usar los transitorios nuevamente para asegurarme de que no bombardeamos Citrix con solicitudes cada vez que se visualiza una página de edición de seminario web. Tomaremos la lista de solicitantes de registro y los almacenaremos en un período transitorio con una hora de vencimiento. Esto significa que la lista solo se actualizará cada hora, pero reduce nuestras solicitudes a una por hora en lugar de una por visita.

También necesitaremos usar un campo de metadatos para la ID del seminario web. Usualmente uso Campos personalizados avanzados, pero como es un ejemplo simple, solo usemos la opción predeterminada de campos personalizados en WordPress y almacenemos un ID de seminario web con la tecla webinar_id. Aquí está el código final:

function my_backend_assets () wp_register_script ('datatables', '//cdn.datatables.net/1.10.7/js/jquery.dataTables.min.js', array ('jquery', 'customselect'), '1.0' cierto ); wp_register_style ('datatables', '//cdn.datatables.net/1.10.7/css/jquery.dataTables.min.css'); wp_enqueue_script ('my-app', plugin_dir_path (__FILE__). '/js/app.js', array ('datatables'), '1.0', true); wp_register_style ('my-datatables', plugin_dir_path (__FILE__). '/css/my-datatables.css');  function my_registrants_metabox () add_meta_box ('webinar_registrants', 'Registrants', 'my_registrants_metabox_content', 'webinar');  function my_registrants_metabox_content ($ post) wp_enqueue_script ('datatables'); wp_enqueue_style ('datatables'); wp_enqueue_style ('my-datatables'); $ webinar_id = get_field ('webinar_id', $ post-> ID); $ registrants = get_transient ('registrants_'. $ webinar_id); if (vacío ($ registrants)) $ client = new \ Citrix \ Authentication \ Direct ('consumer_key'); $ cliente-> auth ('id_usuario', 'contraseña'); $ goToWebinar = new \ Citrix \ GoToWebinar ($ client); $ webinars = $ goToWebinar-> getRegistrants ($ webinar_id); set_transient ('registrants_'. $ webinar_id, $ registrants, HOUR_IN_SECONDS);  if (count ($ registrants)> 0) echo '
'; eco''; eco ''; eco ''; eco ''; eco ''; eco ''; eco ''; eco ''; eco ''; eco ''; eco ''; foreach ($ registra como $ registrant) $ time_zone = explode ('/', $ registrant ['timeZone']); eco ''; eco ''; eco ''; eco ''; eco ''; eco ''; eco ''; eco ''; eco '
Nombre de pilaApellidoEmailFechaZona
'. $ registrant ['firstName']. ''. $ registrant ['lastName']. ''. $ registrant ['email']. ''. fecha ('Y-m-d', strtotime ($ registrant ['registrationDate'])). ''. str_replace ('_', ", $ time_zone [1]). '
'; eco '
';

Un par de cosas han sucedido aquí. En primer lugar, agregué una nueva hoja de estilo, solo para agregar una distinción visual a la lista que verá en la siguiente captura de pantalla. 

Luego trato de obtener la lista de solicitantes de los transitorios. Si esto se vuelve vacío, eso significa que el transitorio nunca se configuró o ha caducado. Si este es el caso, recuperamos a los solicitantes de registro y los colocamos en un estado transitorio.. 

Luego hacemos un bucle a través de los registrantes para llenar la tabla, ¡y todos hemos terminado! Aquí es cómo se ve todo esto con algunos estilos agregados:

Conclusión

Y ahí lo tienen: datos extraídos de una API externa, almacenados en caché y mostrados, todos con mecanismos y funciones nativas de WordPress. Si bien esto toma algo de tiempo para leer y digerir, especialmente si está haciendo algo como esto por primera vez, realmente no toma mucho tiempo una vez que lo rodea.. 

De hecho, una vez que tenga alguna experiencia con API externas, pasará la mayor parte del tiempo pensando en qué métodos y opciones tienen, no cómo realizar solicitudes HTTP y cómo almacenar datos, etc.. 

Puedo recomendar de todo corazón el uso de la API HTTP junto con la API de transitorios. Ha demostrado ser un activo valioso y rápido en mi cinturón de herramientas.