title: Google Calendar Integration w/ Oracle APEX
body: <p>I just started programming with SQL and thought to take on Oracle APEX as my first environment.  To better understand Dynamic Actions, I also tried to pick up my first project of accessing the Google Calendar API and using it to make an event in my own Google Calendar.  I was able to successfully establish authentication, however when I tried to actually create or return an event, nothing happened and no event was created in my Google Calendar.  </p>
  
  <p>Fearing it might be an issue with the code, I set up a node server and was able to both create events and return them with ease.  I was curious as to why this occurred and what possible solutions there may be to the problem.  The research I did led me to an outdated plugin which could possibly serve as a workaround, a tutorial attached to the outdated plugin, a tutorial that used non existent features, and a rather confusing oracle forums post, none of which helped me understand or solve my issue.</p>
  
  <p>If anyone is knowledgeable enough to help identify the problem or the solution, I would greatly appreciate it as even my friends who have more experience with APEX and programming in general have been stumped!  I'll provide the code I used for the node server just in case that  will end up being useful:</p>
  
  <pre><code>&lt;html&gt;
    &lt;head&gt;
      &lt;script type="text/javascript"&gt;
        // Your Client ID can be retrieved from your project in the Google
        // Developer Console, https://console.developers.google.com
        var CLIENT_ID = '(--redacted--)';
  
        var SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"];
  
        /**
         * Check if current user has authorized this application.
         */
        function checkAuth() {
          gapi.auth.authorize(
            {
              'client_id': CLIENT_ID,
              'scope': SCOPES.join(' '),
              'immediate': true
            }, handleAuthResult);
        }
  
        /**
         * Handle response from authorization server.
         *
         * @param {Object} authResult Authorization result.
         */
        function handleAuthResult(authResult) {
          var authorizeDiv = document.getElementById('authorize-div');
          if (authResult &amp;&amp; !authResult.error) {
            // Hide auth UI, then load client library.
            authorizeDiv.style.display = 'none';
            loadCalendarApi();
          } else {
            // Show auth UI, allowing the user to initiate authorization by
            // clicking authorize button.
            authorizeDiv.style.display = 'inline';
          }
        }
  
        /**
         * Initiate auth flow in response to user clicking authorize button.
         *
         * @param {Event} event Button click event.
         */
        function handleAuthClick(event) {
          gapi.auth.authorize(
            {client_id: CLIENT_ID, scope: SCOPES, immediate: false},
            handleAuthResult);
          return false;
        }
  
        /**
         * Load Google Calendar client library. List upcoming events
         * once client library is loaded.
         */
        function loadCalendarApi() {
          gapi.client.load('calendar', 'v3', listUpcomingEvents);
        }
  
        /**
         * Print the summary and start datetime/date of the next ten events in
         * the authorized user's calendar. If no events are found an
         * appropriate message is printed.
         */
        function listUpcomingEvents() {
          var request = gapi.client.calendar.events.list({
            'calendarId': 'primary',
            'timeMin': (new Date()).toISOString(),
            'showDeleted': false,
            'singleEvents': true,
            'maxResults': 10,
            'orderBy': 'startTime'
          });
  
          request.execute(function(resp) {
            var events = resp.items;
            appendPre('Upcoming events:');
  
            if (events.length &gt; 0) {
              for (i = 0; i &lt; events.length; i++) {
                var event = events[i];
                var when = event.start.dateTime;
                if (!when) {
                  when = event.start.date;
                }
                appendPre(event.summary + ' (' + when + ')')
              }
            } else {
              appendPre('No upcoming events found.');
            }
  
          });
        }
  
        /**
         * Append a pre element to the body containing the given message
         * as its text node.
         *
         * @param {string} message Text to be placed in pre element.
         */
        function appendPre(message) {
          var pre = document.getElementById('output');
          var textContent = document.createTextNode(message + '\n');
          pre.appendChild(textContent);
        }
  
      function createEventMaster() {
      var event = {
    'summary': 'Google I/O 2015',
    'location': '800 Howard St., San Francisco, CA 94103',
    'description': 'A chance to hear more about Google\'s developer 
  products.',
    'start': {
      'dateTime': '2016-06-05T09:00:00-07:00',
      'timeZone': 'America/Los_Angeles'
    },
    'end': {
      'dateTime': '2016-06-06T17:00:00-07:00',
      'timeZone': 'America/Los_Angeles'
    },
    'recurrence': [
      'RRULE:FREQ=DAILY;COUNT=2'
    ],
    'reminders': {
      'useDefault': false,
      'overrides': [
        {'method': 'email', 'minutes': 24 * 60},
        {'method': 'popup', 'minutes': 10}
      ]
    }
  };
  
  var request = gapi.client.calendar.events.insert({
    'calendarId': 'primary',
    'resource': event
  });
  
  request.execute(function(event) {
    appendPre('Event created: ' + event.htmlLink);
  });
      }
      &lt;/script&gt;
      &lt;script src="https://apis.google.com/js/client.js?onload=checkAuth"&gt;
      console.log('test');
      &lt;/script&gt;
    &lt;/head&gt;
    &lt;body&gt;
  &lt;button id="test" onclick="createEventMaster()"&gt; create event &lt;/button&gt;
      &lt;div id="authorize-div" style="display: none"&gt;
        &lt;span&gt;Authorize access to Google Calendar API&lt;/span&gt;
        &lt;!--Button for the user to click to initiate auth sequence --&gt;
        &lt;button id="authorize-button" onclick="handleAuthClick(event)"&gt;
          Authorize
        &lt;/button&gt;
      &lt;/div&gt;
      &lt;pre id="output"&gt;&lt;/pre&gt;
    &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>TL;DR Oracle APEX won't create google calendar events, same code entered into a node server will, why is this the case?</p>