Usando el API de Google Calendar

Google Calendar
Google Calendar

Hace algunos días y precisamente antes del GoogleIO de este año estaba tratando de implementar el API de google calendar para agregarlo como funcionalidad en #LeventoCRM, debo decir que la documentación estaba horrible, pero el día de la inauguración del GoogleIO, cambiaron el diseño de las páginas de la documentación y mejoró grandemente a tal grado que pude terminar con mayor facilidad la implementación.

El API de google calendar está bastante completa a excepción de los eventos en los cuales no encontré como crear eventos para todo el día y siempre me forza a establecer horarios de inicio y finalización.

Este es un ejemplo escrito en PHP el cual resume la creación de un calendario a través de esta API.

$client = new Google_Client();
$client->setApplicationName(Yii::app()->name);
$client->setAuthConfigFile(getcwd().'/protected/vendors/google/client_secret.json');
 
$service = new Google_Service_Calendar($client);
 
// Crear un nuevo calendario
$calendar = new Google_Service_Calendar_Calendar();
$calendar->setSummary('TITULO CALENDARIO');
$calendar->setDescription('DESCRIPCION CALENDARIO');
$calendar->setTimeZone('America/Mexico_City');
$createdCalendar = $service->calendars->insert($calendar);
$calendarId = $createdCalendar->getId();
 
// Crear un nuevo evento
$event = new Google_Service_Calendar_Event();
$event->setSummary('TITULO EVENTO');
$event->setDescription('DESCRIPCION EVENTO');
 
// Fecha de inicio (del día actual a las 8am)
$date = new DateTime(date('Y-m-d'), new DateTimeZone('America/Mexico_City'));
$start = new Google_Service_Calendar_EventDateTime();
$start->setDateTime($date->format('Y-m-d').'T08:00:00');
$start->setTimeZone('America/Mexico_City');
$event->setStart($start);
 
// Fecha de cierre (del día actual a las 6pm)
$date = new DateTime(date('Y-m-d'), new DateTimeZone('America/Mexico_City'));
$end = new Google_Service_Calendar_EventDateTime();
$end->setDateTime($date->format('Y-m-d').'T18:00:00');
$end->setTimeZone('America/Mexico_City');
$event->setEnd($end);
 
$remindersArray = array();
 
// Crear recordatorios
$reminder = new Google_Service_Calendar_EventReminder();
$reminder->setMethod('email');
$reminder->setMinutes(25);
$remindersArray[] = $reminder;
 
$reminder = new Google_Service_Calendar_EventReminder();
$reminder->setMethod('popup');
$reminder->setMinutes(15);
$remindersArray[] = $reminder;
 
$reminders = new Google_Service_Calendar_EventReminders();
$reminders->setUseDefault(false);
$reminders->setOverrides($remindersArray);
$event->setReminders($reminders);
 
$attendees = array();
 
// Agregar los Participantes
$attendee = new Google_Service_Calendar_EventAttendee();
$attendee->setEmail('info@qbit.com.mx');
$attendees[] = $attendee;
 
$event->attendees = $attendees;
 
$createdEvent = $service->events->insert($calendarId, $event, array(
     'sendNotifications' => true
));

Más o menos así va el código, aunque como siempre esto se puede mejorar (igual que todo). Otra cosa que no me gustó es que la sincronización con mi teléfono android no es del todo transparente, ya que es necesario ir a las preferencias del calendario y activarle la opción de sincronizarse automáticamente, porque desde el API no existe una opción para pedir que aparezca sincronizado desde los equipos.

Si encuentran un error en el código me avisan y si les funciona, comenten.

Happy Coding! 🙂

Co-fundador de Qbit Mexhico, usuario de linux, Developer en tecnologías web.. Nicaragüense, centro en basketball, primer centro en rugby y pintor los fines de semana. Ortögrafo y ambientalista psicológico (de escritorio).. ese soy yo!

Si te ha servido compártelo y difunde nuestro blog..

Twitter LinkedIn Flickr YouTube 

25 thoughts on “Usando el API de Google Calendar

  1. Hola. Estoy intentando crear eventos en Google Calendar y me está resultando muy lioso. No hay información útil clara y concisa, todo es muy confuso. He llegado a esta entrada y no sé cómo se implementa. Yo copio este código PHP pero está claro que necesito algo más. Pero no sé qué es.

    ¿Cómo podría hacerlo?
    Muchas gracias.

    1. La documentación esta completa, aunque confusa a la vez .. lo primero es descargar el código utilizando composer, luego tienes que configurar el acceso al api de google calendar a través de google console, en mi ejemplo utilicé un arhivo llamado client_secret.json que basicamente contiene las credenciales para conectarse y luego de esto ya se puede empezar a integrar el código de calendario donde desees.

      Dejaré aquí el enlace, el cual es el punto de partida para integrar el api de google calendar en tu proyecto.

      https://developers.google.com/google-apps/calendar/quickstart/php#prerequisites

      Saludos

      1. Hola, muchas gracias por tu respuesta. Estoy encallado en el Paso 4. Donde dice “Browse to the provided URL in your web browser.

        If you are not already logged into your Google account, you will be prompted to log in. If you are logged into multiple Google accounts, you will be asked to select one account to use for the authorization.”

        No sé a qué se refiere con es URL del navegador. ¿Sabes a qué se está refiriendo? En la consola me indica que tengo que insertar un código “Enter verification code”

        En este punto estoy totalmente perdido.

        Muchas gracias por tu tiempo.
        Un saludo.

        1. Parece que ya tienes todo, ahora lo que hace falta es que lo pruebes y para ello debes visitar la url que contiene el código que hiciste, como habrás leído, cuando implementas google calendar, el primero es un enlace para dar permiso a tu usuario de usar google calendar a través de tu aplicación (oauth permissions) .. por eso dice que debes loguearte con tu cuenta de google, una vez que hayas eso, podrás empezar a verificar si tu código funciona o tiene detalles a corregir.

          Saludos

          1. Hola Jack. Muchísimas gracias por tu tiempo, estás siendo muy amable.

            Entiendo que la URL que me aparece en la consola es la que debo ingresar en el navegador y que obtendré el código que me solicita en la consola.

            Lo hago pero me da un error 400 Error: invalid_request – Missing required parameter: redirect_uri

            Te comento que todo lo estoy haciendo en un servidor local bajo Windows usando la plataforma WAMP. ¿Puede ser ese el problema?

            Lo que no sé es cómo usar la consola PHP para poder hacer esta prueba en mi servidor web, tendré que consultarlo con mi proveedor.

            Muchas gracias Jack, me has ayudado muchísimo. Te mantengo informado a ver si soy capaz de conseguirlo.

            🙂

          2. No creo que necesites usar la consola, eso solo se usa para usar el composer e instalar la libreria, igual te funciona di descargas el zip o el paquete q sea .. y bueno recapitulando, necesitas el permiso de google a tu aplicación para que uses el calendario y eso lo haces desde el google console, luego de ahí salen las llaves que usarás en tu código .. implementas la funcionalidad del calendario en tu aplicación web y cuando tengas todo listo solo necesitas apuntar al endpoint donde implementaste, ahí debe aparecerte un enlace hacia google donde te dirá que tu aplicación quiere manejar tu calendario.. lo aceptas y google hará una redirección hacia tu sitio con el token de aceptación.. y una vez q tienes ese token ya puedes controlar el calendario de tu usuario desde tu aplicación ..

            Espero haberlo medio explicado, es confuso, pero seguro podrás, suerte con eso.

  2. Hola nuevamente Jack. No consigo hacerlo 🙁

    Estoy bastante frustrado con este tema. No soy capaz de hacerlo. Esto me está consumiendo mucho tiempo, demasiado para no ver ni un solo adelanto en tantas horas probando cosas diferentes. Incluso buscando soluciones. ¡Qué desastre!

    Mil gracias por todo Jack.

  3. Hola Jack. Claro, comparto contigo todo lo que he hecho hasta ahora. Voy a intentar explicarlo lo mejor posible y lo más detallado posible.

    – Creo una App en https://console.developers.google.com/. Obtengo un NOMBRE-APP, ID, SECRETA.

    – Habilito la API de Google Calendar.

    – Descargo el cliente php de la API de Google, que obtengo de este enlace https://github.com/google/google-api-php-client/tree/v1-master

    – Lo implemento en mi servidor, copiando directamente la carpeta.

    – Creo el archivo obtener_access_token.php ~ Su código es:
    setApplicationName(NOMBRE-APP-GOOGLE);
    $client->setClientId($client_id);
    $client->setClientSecret($client_secret);
    $client->setRedirectUri($redirect_uri);
    $client->setScopes(‘https://www.googleapis.com/auth/calendar’);
    $client->setAccessType(‘offline’);
    if (isset($_GET[‘code’])) {
    $client->authenticate();
    $_SESSION[‘token’] = $client->getAccessToken();
    $myFile = “refreshtoken.conf”;
    $fh = fopen($myFile, ‘w’) or die(“can’t open file”);
    fwrite($fh, $client->getAccessToken());
    fclose($fh);
    } else {
    if (! $client->getAccessToken()) {
    $auth = $client->createAuthUrl();
    header(“Location: $auth”);
    }
    }
    ?>

    – Creo el archivo para la URi de la APP de Google: googcallback.php ~ Su código es:
    access_token){
    $tokendata[‘token_access’]=$res->access_token;
    }
    if ($res->token_type){
    $tokendata[‘token_type’]=$res->token_type;
    }
    if ($res->expires_in){
    $tokendata[‘token_expires_in’]=$res->expires_in;
    }
    if ($res->id_token){
    $tokendata[‘token_id’]=$res->id_token;
    }
    return $tokendata;
    }

    $code=”;
    $param=”;
    $tokendata = array();

    if(isset($_GET[‘code’]) && $_GET[‘code’]){
    $code = $_GET[‘code’];
    }

    if ($code){
    $tokendata = request_token($code);
    }
    ?>

    — HASTA AQUÍ —

    Ahora al entrar en obtener_access_token.php me redirecciona a la URL donde debo dar permiso a mi APP para acceder a mi Google Calendar. Todo perfecto.

    Una vez aceptada, me dirige, supongo, a googcallback.php. Este, como es normal, me muestra una página en blanco. Me imagino que si no me da ningún error es que he conseguido la autentificación adecuada. Pero no sé cómo comprobarlo.

    Mi intención una vez que pueda acceder a este calendario es añadir eventos, crear avisos y eliminar eventos.

    Mi nueva duda es ¿cómo saber si puedo acceder a mi calendario? ¿Es aquí donde debo implementar el código que nos facilitas?

    Muchas gracias Jack por tu tiempo y dedicación.

    1. Parece que se ha cortado parte del código de los archivos php. Vuelvo a compartirlo, esta vez sin llaves para abrir el php.

      obtener_access_token.php ~ CÓDIGO
      $rutaApiGC=RUTA-INSTALACION-API-PHP-GOOGLE’;
      set_include_path($rutaApiGC);
      require_once(‘autoload.php’);

      session_start();

      $client_id = CLIENTE-ID-APP-GOOGLE’;
      $client_secret = ‘SECRETA-APP-GOOGLE’;
      $redirect_uri = ‘REDIRECT-URI-APP-GOOGLE’;

      $client = new Google_Client();
      $client->setApplicationName(NOMBRE-APP-GOOGLE);
      $client->setClientId($client_id);
      $client->setClientSecret($client_secret);
      $client->setRedirectUri($redirect_uri);
      $client->setScopes(‘https://www.googleapis.com/auth/calendar’);
      $client->setAccessType(‘offline’);
      if (isset($_GET[‘code’])) {
      $client->authenticate();
      $_SESSION[‘token’] = $client->getAccessToken();
      $myFile = “refreshtoken.conf”;
      $fh = fopen($myFile, ‘w’) or die(“can’t open file”);
      fwrite($fh, $client->getAccessToken());
      fclose($fh);
      } else {
      if (! $client->getAccessToken()) {
      $auth = $client->createAuthUrl();
      header(“Location: $auth”);
      }
      }

      googcallback.php ~ CÓDIGO
      $client_id = ‘CLIENTE-ID-APP-GOOGLE’;
      $client_secret = ‘SECRETA-APP-GOOGLE’;
      $redirect_uri = ‘REDIRECT-URI-APP-GOOGLE’;
      $url=’MI-URL’;

      define(‘CLIENTID’,$client_id);
      define(‘CLIENTSECRET’,$client_secret);
      define(‘URLCALLBACK’, $redirect_uri);
      define(‘URL’,$url);

      function request_token($code){
      //Solicita el token a google a con el código pasado
      $tokendata = array();

      $ch = curl_init(‘https://accounts.google.com/o/oauth2/token’);
      curl_setopt($ch, CURLOPT_POST, 1);
      curl_setopt($ch, CURLOPT_POSTFIELDS, “code=”.$code.”&client_id=”.CLIENTID.”&client_secret=”.CLIENTSECRET.”&redirect_uri=”.URLCALLBACK.”&grant_type=authorization_code”);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1);
      $result_curl = curl_exec($ch);
      $error_curl = curl_error($ch);
      curl_close($ch);

      $res = json_decode($result_curl);

      if ($res->access_token){
      $tokendata[‘token_access’]=$res->access_token;
      }
      if ($res->token_type){
      $tokendata[‘token_type’]=$res->token_type;
      }
      if ($res->expires_in){
      $tokendata[‘token_expires_in’]=$res->expires_in;
      }
      if ($res->id_token){
      $tokendata[‘token_id’]=$res->id_token;
      }
      return $tokendata;
      }

      $code=”;
      $param=”;
      $tokendata = array();

      if(isset($_GET[‘code’]) && $_GET[‘code’]){
      $code = $_GET[‘code’];
      }

      if ($code){
      $tokendata = request_token($code);
      }

      1. Hola Alejandro,

        Ten en cuenta que al menos se usan 3 archivos.. los cuales llamaré request.php, response.php y sync.php

        Además de que el orden en que serán utilizados es el mismo que describo, donde “request” es el que hace la solicitud del uso del calendario, “response” es el que recibe la autorización y “sync” es el que básicamente maneja el calendario para agregar, crear, modificar, etc.. los calendarios o eventos de google.

        // request.php (esta es la llamada de mi sitio hacia google)
        $client = new Google_Client();
        $client->setApplicationName(‘Mi Calendario Demo’);
        $client->setAuthConfigFile(‘google_config.json’);
        $client->setRedirectUri(‘response.php’);
        $client->setScopes(array(‘https://www.googleapis.com/auth/calendar’));
        // $client->setScopes(array(‘https://www.googleapis.com/auth/calendar’, ‘https://www.googleapis.com/auth/calendar.readonly’));
        $client->setAccessType(‘offline’);
        $client->createAuthUrl();
        // ************ FIN DEL ARCHIVO REQUEST ************

        // response.php (esta es la respuesta desde google hacia mi sitio)
        $client = new Google_Client();
        $client->setApplicationName(‘Mi Calendario Demo’);
        $client->setAuthConfigFile(getcwd().’/protected/vendors/google/client_secret_536651336306-lrqhfg1pmmgr80sbc2es4q0rfesujmd2.apps.googleusercontent.com.json’);

        $code = $_GET[‘code’];
        $error = $_GET[‘error’];

        $client->authenticate($code);
        $access_token = $client->getAccessToken();
        $client->setAccessToken($access_token);

        // Si todo sale bien, access_token será algo como esto
        // {
        // “access_token”:”sKobWy_tdz5bGpA”,
        // “token_type”:”Bearer”,
        // “expires_in”:3600,
        // “refresh_token”:”TktKCNa6SUnDPZOwvBa”,
        // “created”:1434075564
        // }
        echo $access_token;
        // ************ FIN DEL ARCHIVO RESPONSE ************

        // sync.php (este archivo es el que creará un evento en mi calendario y se usa una vez que se tenga el access_token)
        $google_token = json_decode($access_token, true);
        $refresh_token = $google_token[‘refresh_token’];

        $client = new Google_Client();
        $client->setApplicationName(‘Mi Calendario Demo’);
        $client->setAuthConfigFile(‘google_config.json’);
        $client->refreshToken($refresh_token);

        $service = new Google_Service_Calendar($client);
        // Recorrer todos los calendarios del usuario
        $calendarList = $service->calendarList->listCalendarList();

        // Crear un nuevo calendario
        $calendar = new Google_Service_Calendar_Calendar();
        $calendar->setSummary(‘Calendario dinamico’);
        $calendar->setDescription(‘Este calendario tendra eventos creados por mi codigo’);
        $calendar->setTimeZone(‘America/Mexico_City’);

        $createdCalendar = $service->calendars->insert($calendar);
        $calendarId = $createdCalendar->getId();
        echo ‘ID de calendario creado: ‘.$calendarId;

        // Crear un nuevo evento
        $event = new Google_Service_Calendar_Event();
        $event->setSummary(‘Escribir un articulo en el blog’);
        $event->setDescription(‘Deberia ser mas claro y escribir articulos que realmente funcionen’);
        $event->setVisibility(‘default’);

        // Fecha de inicio del evento (16 de mayo 8am)
        $date = new DateTime(‘2016-05-16’, new DateTimeZone(‘America/Mexico_City’));
        $start = new Google_Service_Calendar_EventDateTime();
        $start->setDateTime($date->format(‘Y-m-d’).’T08:00:00′);
        $start->setTimeZone(‘America/Mexico_City’);
        $event->setStart($start);

        // Fecha de fin del evento (16 mayo 18pm)
        $date = new DateTime(‘2016-05-16’, new DateTimeZone(‘America/Mexico_City’));
        $end = new Google_Service_Calendar_EventDateTime();
        $end->setDateTime($date->format(‘Y-m-d’).’T18:00:00′);
        $end->setTimeZone(‘America/Mexico_City’);
        $event->setEnd($end);

        // Establecer recordatorios
        $remindersArray = array();
        $reminder = new Google_Service_Calendar_EventReminder();
        $reminder->setMethod(‘email’);
        $reminder->setMinutes(25);
        $remindersArray[] = $reminder;

        $reminder = new \Google_Service_Calendar_EventReminder();
        $reminder->setMethod(‘popup’);
        $reminder->setMinutes(15);
        $remindersArray[] = $reminder;

        $reminders = new Google_Service_Calendar_EventReminders();
        $reminders->setUseDefault(false);
        $reminders->setOverrides($remindersArray);
        $event->setReminders($reminders);

        // Para agregar otra persona al recordatorio
        $attendees = array();
        $attendee = new Google_Service_Calendar_EventAttendee();
        $attendee->setEmail(‘otra.dirección@correo.com’);
        $attendees[] = $attendee;
        $event->attendees = $attendees;

        // Guardar el evento en el nuevo calendario
        $createdEvent = $service->events->insert($calendarId, $event, array(
        ‘sendNotifications’ => true
        ));
        echo ‘
        ID de evento creado: ‘.$createdEvent->getId();
        // ************ FIN DEL ARCHIVO SYNC ************

        Me salté las validaciones y el cacheo de errores, pero este es el código básico por llamarle de una manera.

        Espero que esto te ayude y no tengas más dudas.

        Saludos

  4. Hola Jack
    hice el tutorial de hasta el que funcionó el quickstart.php (me demoré un poco) pero eso lo ejecute solo en la consola, pero lo que en realidad quiero el poder sacar una lista de los eventos que tengo en el calendario y no se que coaul es el paso que debo seguir.

    Cuando realice el tutorial al final me creo un un archivo oculto en el mi usuario de win pero no se como utilizarlo para la aplicación web.

    Te agradecería mucho si me puedes colaborar un poco

  5. Buenas!! quisiera saber si los recordatorios funcionan en los celulares android, ya que al crear un evento este se sincroniza con el celular pero sin recordatorio. Muchas gracias

    1. Claro que funcionan, solamente depende de que tengas sincronizado tu calendario en tu teléfono, lo malo es q esa tarea se debe hacer manualmente desde la configuración de la aplicación calendar.

      Saludos

  6. Buenas tardes, estoy haciendo mi tesis de la universidad donde creo eventos para la misma, y debo utilizar el API de GOOGLE sigo los pasos de la pagina del quickstart, llego al paso de correr en consola el quickstart.php ir a el URL y me de el TOken lo coloco en consola y me da error no tengo idea que mas hacer. Los pasos que tu diste puede ayudar sin problema??

  7. Hola otra vez, estoy probando tu codigo con los tres archivos y me da este error

    Fatal error: Uncaught exception ‘InvalidArgumentException’ with message ‘Redirect URI must be absolute’ in C:\wamp\www\Eventos_unimet\google-api-php-client\vendor\google\auth\src\OAuth2.php on line 733

    es sobre la autetificacion sera que no estoy colocando algo, si podrias ayudarme

  8. Hola Jackfiallos:

    Estoy intentando modificar un evento de la API Google Calendar. En la documentación encuentro que se hace con UPDATE pero no sé cómo hacerlo. 🙁

    Tengo ya eventos insertados en el calendario y quiero que el usuario elija un evento y pueda modificar su título, la hora de inicio…

    Me podrías ayudar?? Muchas gracias!! Saludos…

  9. Hola. muy buen post… estoy investigando el google calendar. Pregunta se puede leer los eventos cargados en un calendar pero sin hacer el loggin o la pantalla de consentimiento ?

  10. Hola! No se si he caido al lugar indicado, la verdad estoy totalmente perdida en cuanto a conocimientos tecninos, no gtengo formación profesional al respecto y tengo un amigo que es el que me ayuda con los codigos y estas cosas en mi página web. Pero andando navegando me encontre este post que me parece muy bueno y me surgio una pregunta, no se si tu me la podrás contestar.

    Yo quiero usar un calendario en línea, descargable y personalizable como este por ejemplo : https://www.calendario.mx/ y quiero integrarlo a mi página web (que esta en construcción) , creo que hasta ahi mi amigo se las puede arreglar, lo que no tenemos claro es si existe la posibilidad de fusionar un calendario de este tipo con el de google. Suponiendo que usas ambos y hay eventos diferentes en cada uno quieres tener en uno solo. SNo se si me he explicado.

    Gracias por la respuesta!
    Saludos!
    Sara

  11. Hola bien yo estoy trabajando en proyecto que me pidieron y el cliente quiere ver y agendar sus pacientes en un calendario google de momento estoy trabajando servidor local, el quickstart que te dan de ejmplo solo lo puedo ejecutar desde la consola del xamp pero desde la web me dice “his application must be run on the command line.’ in C:\xampp\htdocs\OralCare\vistas\quickstart.php:5 Stack trace: #0 C:\xampp\htdocs\OralCare\vistas\citas.php(4): require_once() #1 {main} thrown in C:\xampp\htdocs\OralCare\vistas\quickstart.php on line 5”, incluso vi un video para hacer las credenciales desde el browser pero no funciona capas estoy omitiendo algo este es el enlace del vídeo por el cual me estaba guiando
    https://www.youtube.com/watch?v=jU79KXENL5k&t=476s

  12. Hola jack, primero quero felicitarte por tu articulo es exelemnte, me a ayudado bastate a entender como funciona el api, pero me a surgido un error y no tengo idea de que es:
    PHP Fatal error: Uncaught exception ‘Google_Service_Exception’ with message ‘{
    “error”: {
    “errors”: [
    {
    “domain”: “global”,
    “reason”: “insufficientPermissions”,
    “message”: “Insufficient Permission: Request had insufficient authentication scopes.”
    }
    ],
    “code”: 403,
    “message”: “Insufficient Permission: Request had insufficient authentication scopes.”
    }
    }

    sabras por que ocurre esto cuando quiero agregar un evento?

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *