{"componentChunkName":"component---src-templates-default-template-tsx","path":"/tutorials/tutorial-google-calendar-connector/","result":{"data":{"asciidoc":{"id":"623b5f38-e113-5308-94bf-0b9bcb29e10c","html":"<div id=\"toc\" class=\"toc\">\n<div id=\"toctitle\">Table of Contents</div>\n<ul class=\"sectlevel1\">\n<li><a href=\"#_overview\">Overview</a></li>\n<li><a href=\"#_prerequisites_preparations\">Prerequisites &amp; Preparations</a>\n<ul class=\"sectlevel2\">\n<li><a href=\"#_preparing_a_google_service_account\">Preparing a Google service account</a></li>\n<li><a href=\"#_preparing_a_google_calendar\">Preparing a Google Calendar</a></li>\n<li><a href=\"#_install_python_libraries_for_google_api\">Install Python libraries for Google API</a></li>\n<li><a href=\"#_preparing_hiro_session\">Preparing HIRO session</a></li>\n</ul>\n</li>\n<li><a href=\"#_connecting_with_the_google_api\">Connecting with the Google API</a></li>\n<li><a href=\"#_reading_calendar_data_from_google\">Reading calendar data from Google</a></li>\n<li><a href=\"#_writing_calendar_data_to_hiro\">Writing calendar data to HIRO</a></li>\n<li><a href=\"#_continuous_synchronization_repeatedly_write_new_or_updated_events\">Continuous synchronization: repeatedly write new or updated events</a></li>\n<li><a href=\"#_summary\">Summary</a></li>\n</ul>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_overview\">Overview</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>In this tutorial, we will show how to write a simple connector for HIRO. We have picked Google Calendar as example application. The connector we develop in this tutorial will read events from a calendar and copy them to the HIRO knowledge core. To keep the connector simple, we will copy the events only in one direction. Synchronization of data will be covered by another tutorial.</p>\n</div>\n<div class=\"paragraph\">\n<p>The code examples are written in Python, but the HIRO API can be used with any other programming language, as well.</p>\n</div>\n<div class=\"imageblock\">\n<div class=\"content\">\n<img src=\"/7.0/images/tutorials/google_connector_architecture.png\" alt=\"google connector architecture\" width=\"Your connector integrates HIRO with Google Calendar\">\n</div>\n<div class=\"title\">Figure 1. Your connector integrates HIRO with Google Calendar</div>\n</div>\n<div class=\"paragraph\">\n<p>We will perform the following steps to implement the connector:</p>\n</div>\n<div class=\"olist arabic\">\n<ol class=\"arabic\">\n<li>\n<p>Prepare prerequisites in Google Calendar / Google Cloud</p>\n</li>\n<li>\n<p>Connect with HIRO</p>\n</li>\n<li>\n<p>Fetch events from Google Calendar</p>\n</li>\n<li>\n<p>Write retrieved events to HIRO</p>\n</li>\n<li>\n<p>Synchronization: only write new or updated events</p>\n</li>\n<li>\n<p>Create a loop to continuously poll events</p>\n</li>\n</ol>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_prerequisites_preparations\">Prerequisites &amp; Preparations</h2>\n<div class=\"sectionbody\">\n<div class=\"sect2\">\n<h3 id=\"_preparing_a_google_service_account\">Preparing a Google service account</h3>\n<div class=\"paragraph\">\n<p>We want to use the Google API to read data from a Google calendar. In order to do this, we need user and application credentials, similiar to the HIRO API. The required steps are:\n. Create a google cloud account\n. Create a new project\n. Create Service Account credentials new app/project</p>\n</div>\n<div class=\"paragraph\">\n<p>If you already have the required accounts and credentials, you may skip to the next section. Otherwise, continue to read the step-by-step\ninstructions.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Create a google cloud account</strong></p>\n</div>\n<div class=\"paragraph\">\n<p>Go to <a href=\"https://cloud.google.com/\" class=\"bare\">https://cloud.google.com/</a>  and sign in. If you don&#8217;t have a Google Cloud account, you have to register first.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Create a new project</strong></p>\n</div>\n<div class=\"paragraph\">\n<p>In the Google Cloud Platform, users, credentials, and permissions are organized in projects. We will create a new project \"HIRO-Connector\" in the Google Cloud.</p>\n</div>\n<div class=\"paragraph\">\n<p>Proceed to the Google Cloud console: <a href=\"https://console.cloud.google.com/\" class=\"bare\">https://console.cloud.google.com/</a> , and click on the project drop-down box on top. Click on \"NEW PROJECT\" to create a new project. Now enter the name of your new project: \"HIRO-Connector\".</p>\n</div>\n<div class=\"imageblock\">\n<div class=\"content\">\n<img src=\"/7.0/images/tutorials/GCP-project-selection.png\" alt=\"GCP project selection\" width=\"Create new GCP project\">\n</div>\n<div class=\"title\">Figure 2. Create new GCP project</div>\n</div>\n<div class=\"imageblock\">\n<div class=\"content\">\n<img src=\"/7.0/images/tutorials/GCP-new-project.png\" alt=\"GCP new project\" width=\"Enter project name\">\n</div>\n<div class=\"title\">Figure 3. Enter project name</div>\n</div>\n<div class=\"paragraph\">\n<p>You have created a new Google Cloud project. As next steps, we will create an API key for our application, and a service account.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Create Service Account credentials new app/project</strong></p>\n</div>\n<div class=\"paragraph\">\n<p>From the Google Cloud Console home screen, select \"Credentials\" from the \"API &amp; Services menu\". Click on \"create credentials\", and then \"Create service account\".</p>\n</div>\n<div class=\"imageblock\">\n<div class=\"content\">\n<img src=\"/7.0/images/tutorials/GCP-create-credentials-1.png\" alt=\"GCP create credentials 1\" width=\"GCP - APIs & Services\">\n</div>\n<div class=\"title\">Figure 4. GCP - APIs &amp; Services</div>\n</div>\n<div class=\"imageblock\">\n<div class=\"content\">\n<img src=\"/7.0/images/tutorials/GCP-create-credentials-2.png\" alt=\"GCP create credentials 2\" width=\"GCP - New credentials\">\n</div>\n<div class=\"title\">Figure 5. GCP - New credentials</div>\n</div>\n<div class=\"paragraph\">\n<p>We enter a new service account name, which we call \"hiro-connector\" and press create. On the next screen  select the role as editor and click continue. On the last screen click done.</p>\n</div>\n<div class=\"imageblock\">\n<div class=\"content\">\n<img src=\"/7.0/images/tutorials/GCP-create-credentials-3.png\" alt=\"GCP create credentials 3\" width=\"GCP - Create service account\">\n</div>\n<div class=\"title\">Figure 6. GCP - Create service account</div>\n</div>\n<div class=\"imageblock\">\n<div class=\"content\">\n<img src=\"/7.0/images/tutorials/GCP-create-credentials-3-1.PNG\" alt=\"GCP create credentials 3 1\" width=\"GCP - Edit role\">\n</div>\n<div class=\"title\">Figure 7. GCP - Edit role</div>\n</div>\n<div class=\"paragraph\">\n<p>On the service account page, click on the button next to key creation date and press create key.</p>\n</div>\n<div class=\"imageblock\">\n<div class=\"content\">\n<img src=\"/7.0/images/tutorials/GCP-create-credentials-3-2.PNG\" alt=\"GCP create credentials 3 2\" width=\"GCP - Create private key\">\n</div>\n<div class=\"title\">Figure 8. GCP - Create private key</div>\n</div>\n<div class=\"paragraph\">\n<p>The key type should be JSON. Press the \"Create\" button, and you&#8217;ll be prompted to save the credentials file to disk. This file contains all necessary credentials data to connect to the API.</p>\n</div>\n<div class=\"imageblock\">\n<div class=\"content\">\n<img src=\"/7.0/images/tutorials/GCP-create-credentials-4.png\" alt=\"GCP create credentials 4\" width=\"GCP - Download private key\">\n</div>\n<div class=\"title\">Figure 9. GCP - Download private key</div>\n</div>\n<div class=\"paragraph\">\n<p>To grant calendar permissions to this service account, you will need the account&#8217;s email address later. Look it up in the GCP console while you are still there. It should look like this: <em>hiro-connector@hiro-connector-123456.iam.gserviceaccount.com</em></p>\n</div>\n</div>\n<div class=\"sect2\">\n<h3 id=\"_preparing_a_google_calendar\">Preparing a Google Calendar</h3>\n<div class=\"paragraph\">\n<p>We will now create a new Google calendar to work with. You may of course also work with an existing calendar, if you prefer.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Create a new Google calendar</strong>\nGo to Google Calendar (<a href=\"https://calendar.google.com/\" class=\"bare\">https://calendar.google.com/</a>) and create a new calendar (\"Other calendars\" -&#8594; \"+\" -&#8594; \"Create new calendar\". Enter \"HIRO-TEST\" as name.</p>\n</div>\n<div class=\"imageblock\">\n<div class=\"content\">\n<img src=\"/7.0/images/tutorials/new-google-calendar.png\" alt=\"new google calendar\" width=\"New Google calendar\">\n</div>\n<div class=\"title\">Figure 10. New Google calendar</div>\n</div>\n<div class=\"paragraph\">\n<p>Next. we enter the calendar setting for the \"HIRO-TEST\" calendar. We share our calendar with the service account <em>hiro-connector@hiro-connector-123456.iam.gserviceaccount.com</em> and provide it edit permissions.</p>\n</div>\n<div class=\"imageblock\">\n<div class=\"content\">\n<img src=\"/7.0/images/tutorials/share-google-calendar.png\" alt=\"share google calendar\" width=\"Share Google calendar\">\n</div>\n<div class=\"title\">Figure 11. Share Google calendar</div>\n</div>\n<div class=\"paragraph\">\n<p>Copy the calendar ID from the settings page - you will need this later to access the calendar through the API.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Enable Calendar API for the new project (in Google Developer Console)</strong></p>\n</div>\n<div class=\"paragraph\">\n<p>There is one last step that we have to perform: enable the Calendar API for your new project. We do this in the Google Developer Console: <a href=\"https://console.developers.google.com/\" class=\"bare\">https://console.developers.google.com/</a></p>\n</div>\n<div class=\"paragraph\">\n<p>Select the \"HIRO Connector\" project, and click on \"+ ENABLE APIS AND SERVICES\". Select \"Google Calendar API\", and enable it on the next screen. Your are ready now to connect via API to your calendar.</p>\n</div>\n<div class=\"imageblock\">\n<div class=\"content\">\n<img src=\"/7.0/images/tutorials/enable-calendar-api.png\" alt=\"enable calendar api\" width=\"Enable calendar API\">\n</div>\n<div class=\"title\">Figure 12. Enable calendar API</div>\n</div>\n</div>\n<div class=\"sect2\">\n<h3 id=\"_install_python_libraries_for_google_api\">Install Python libraries for Google API</h3>\n<div class=\"paragraph\">\n<p>You will need two Python libraries for the Google API. In case you do not have them in your environment yet, install them with the <em>pip</em> command.</p>\n</div>\n<div class=\"paragraph\">\n<p>Google Oauth client:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code>pip install google-auth</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>Google Python client library:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code>pip install google-api-python-client</code></pre>\n</div>\n</div>\n</div>\n<div class=\"sect2\">\n<h3 id=\"_preparing_hiro_session\">Preparing HIRO session</h3>\n<div class=\"paragraph\">\n<p>Finally, we initiate a HIRO session, as seen in the <a href=\"/7.0/tutorials/tutorial-first-steps-with-hiro/\">First Steps with HIRO</a> tutorial:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\"># Initiate session\nhiro_session = initiate_hiro_session('./hiro_credentials.json')</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>We will also need the functions <em>create_vertex</em>, <em>update_vertex</em> and <em>create_edge</em>, which we have defined in the <a href=\"/7.0/tutorials/basic-graph-operations/\">Basic Vertex Operations</a> tutorial.</p>\n</div>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_connecting_with_the_google_api\">Connecting with the Google API</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Before we can read and write data via the Google API, we need to authenticate and create a session with the intended usage scope.\nWe load the service account credentials, which we had downloaded from the Google Cloud Platform Console before (see above), set the scope to 'https://www.googleapis.com/auth/calendar', and create an authenticated session.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\"># google api imports\nfrom google.oauth2 import service_account\nfrom google.auth.transport.requests import AuthorizedSession\nfrom googleapiclient.discovery import build\n\n# configuration\ngoogle_credentials_file = \"./forward-aura-168008-92a0f1f9cd3a.json\"         #replace with your credentials file!\ngoogle_calendar_id = '7hfea2godbmajrspfp30l23q1o@group.calendar.google.com' #replace with the id of your calendar!\n\n# load credentials and authorize session\ncredentials = service_account.Credentials.from_service_account_file(google_credentials_file)\nscoped_credentials = credentials.with_scopes(['https://www.googleapis.com/auth/calendar'])\nauthed_session = AuthorizedSession(scoped_credentials)</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>Once we are authenticated and have created a session with the Google API, we can instantiate a specific service for the Calendar API:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\"># Build Calendar API Service\nservice = build('calendar', 'v3', credentials=scoped_credentials)</code></pre>\n</div>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_reading_calendar_data_from_google\">Reading calendar data from Google</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>As next step, we will check that we can read calendar data through the Google API, to verify that we got everything in place correctly. As a test, we print out the calendar name to the console, and retrieve all calendar events.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\"># get calendar name\ncalendar = service.calendars().get(calendarId=google_calendar_id).execute()\nprint ('Calendar name: ' + calendar['summary']+ '\\n')\n\nprint('Getting all events')\nevents_result = service.events().list(calendarId=google_calendar_id, singleEvents=True, orderBy='startTime').execute()\nevents = events_result.get('items', [])\n\nif not events:\n    print('No upcoming events found.')\nfor event in events:\n    start = event['start'].get('dateTime', event['start'].get('date'))\n    print(start, event['summary'])</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>We have read data from Google Calendar and printed it out to the console. We are ready for the final step: writing the calendar data to HIRO.</p>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_writing_calendar_data_to_hiro\">Writing calendar data to HIRO</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>For writing calendar data to HIRO, we define two helper functions. The first function <em>write_calendar()</em> creates a node in the HIRO Graph, which represents the specific calendar. We add the calendar id as <em>_xid</em> and calendar name as title attribute, so that we know which calendar it is.</p>\n</div>\n<div class=\"paragraph\">\n<p>The second helper function <em>write_event()</em> creates a vertex of type <em>ogit/Schedule/Event</em> in HIRO for the calendar event from Google. In this example, we write the event id, title, start and end time, description, location, and etag as attributes. You might want to extend this with additional attributes in the future. The new event vertex is connected with a <em>ogit:contains</em> edge to the calendar vertex.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">def create_calendar (calendar):\n    vertex_data = {'ogit/title':calendar['summary'],\n                   'ogit/_xid': 'CAL-' + calendar['id'],\n                   '/etag': calendar['etag']\n                  }\n\n    return create_vertex('ogit/Schedule/Calendar', vertex_data)\n\ndef create_event (cal_id, event):\n\n    vertex_data = {'ogit/title':event['summary'],\n                   'ogit/Schedule/startTime': event['start'].get('dateTime', event['start'].get('date', '')),\n                   'ogit/Schedule/endTime': event['end'].get('dateTime', event['end'].get('date','')),\n                   'ogit/_xid': 'CAL-' + cal_id + '-' + event['id'],\n                   '/etag': event['etag']\n                  }\n\n    if 'description' in event:\n        vertex_data['ogit/description'] = event['description']\n    if 'location' in event:\n        vertex_data['ogit/Schedule/location'] = event['location']\n\n    vertex_id = create_vertex('ogit/Schedule/Event', vertex_data)\n    create_edge(cal_id, vertex_id, 'ogit:contains')\n\n    return vertex_id</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>Now we can retrieve the calendar data from Google again, and write the entries to HIRO. We will first create a calendar item in HIRO. Afterwards, we iterate over all calendar events, copy each event to HIRO, and connect it to the calendar vertex.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\"># get calendar name\ncalendar = service.calendars().get(calendarId=google_calendar_id).execute()\n\n# create calendar vertex in HIRO\nhiro_cal_id = create_calendar(calendar)\n\n# retrieve all events from Google calendar\nevents_result = service.events().list(calendarId=google_calendar_id, singleEvents=True, orderBy='startTime').execute()\nevents = events_result.get('items', [])\n\nfor event in events:\n    hiro_event_id = create_event (hiro_cal_id, event)</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>If you check now, you will find your calendar and all events in the HIRO Graph.</p>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_continuous_synchronization_repeatedly_write_new_or_updated_events\">Continuous synchronization: repeatedly write new or updated events</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Of course, we don&#8217;t want to create new data objects every time we check the Google calendar, but we want to update the data in HIRO when there are changes or new events in the Google calendar. Therefore, we need to first check whether there are already nodes in HIRO for the calendar or event; and if they exist, we want to know whether there have been any changes that need to be updated.</p>\n</div>\n<div class=\"paragraph\">\n<p>HIRO offers a special <em>'ogit/_xid'</em> attribute, which should be used to specify the external id that the item has in the original data source. If you write for instance the Google event id to this field, you will be able to check whether a specific event is already stored in HIRO or not. There is also a convenience method in the Graph API that facilitates looking up vetices by external id.</p>\n</div>\n<div class=\"paragraph\">\n<p>External ids are supposed to be unique in the HIRO database. Therefore, we do not just use the calendar or event ids in our example, but add a prefix, so that we reduce the probability of id conflicts. This is a good practice that you might want to adopt already in your first connector.</p>\n</div>\n<div class=\"paragraph\">\n<p>Google has introduced a nice feature for determining whether a data object has changed: there is an <em>etag</em> attribute, which is assigned a new random value when the object is changed. As we have already copied this attribute to the HIRO vertices before, we can simply check whether the etag has changed. Thanks Google!</p>\n</div>\n<div class=\"paragraph\">\n<p>We define helper methods to check whether the calendar and events already exist and whether there are changes:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">def update_calendar (vertex_id, calendar):\n    vertex_data = {'ogit/title': calendar['summary'],\n                   'ogit/description': calendar['description'],\n                   '/etag': calendar['etag']\n                  }\n\n    return update_vertex(vertex_id, vertex_data)\n\ndef read_vertex_by_xid (xid):\n    response = hiro_session['session'].get(hiro_session['graph_api'] + 'xid/' + xid )\n\n    if response.ok:\n        if len(response.json()['items'])==1:\n           return response.json()['items'][0]\n    else:\n        print (str(response.status_code) + \" - \" + response.text)\n        print ('Failed to read vertex.')\n    return None\n\ndef create_or_update_calendar (calendar):\n    xid = 'CAL-' + calendar['id']\n    etag = calendar['etag']\n\n    cal_vertex =  read_vertex_by_xid (xid)\n\n    if cal_vertex == None:\n        return create_calendar (calendar)\n    else:\n        print (cal_vertex)\n        hiro_etag = cal_vertex.get('/etag', '')\n        vertex_id = cal_vertex ['ogit/_id']\n        if etag != hiro_etag:\n            update_calendar (vertex_id, calendar)\n        return vertex_id\n\n\ndef update_event (vertex_id, cal_id, event):\n    vertex_data = {'ogit/title':event['summary'],\n                   'ogit/Schedule/startTime': event['start'].get('dateTime', event['start'].get('date', '')),\n                   'ogit/Schedule/endTime': event['end'].get('dateTime', event['end'].get('date','')),\n                   '/etag': event['etag']\n                  }\n\n    if 'description' in event:\n        vertex_data['ogit/description'] = event['description']\n    if 'location' in event:\n        vertex_data['ogit/Schedule/location'] = event['location']\n\n    return update_vertex(vertex_id, vertex_data)\n\n\ndef create_or_update_event (cal_id, event):\n    xid = 'CAL-' + cal_id + '-' + event['id']\n    etag = event['etag']\n\n    event_vertex =  read_vertex_by_xid (xid)\n\n    if event_vertex == None:\n        create_event (cal_id, event)\n    else:\n        hiro_etag = event_vertex.get('/etag', '')\n        vertex_id = event_vertex ['ogit/_id']\n        if etag != hiro_etag:\n            update_event (vertex_id, cal_id, event)</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>And now we can adapt our synchronization routine to utilize the new methods:</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-python\" data-lang=\"python\">import time\n\n# get calendar name\ncalendar = service.calendars().get(calendarId=google_calendar_id).execute()\n\n# create calendar vertex in HIRO\nhiro_cal_id = create_or_update_calendar(calendar)\n\n#endless loop\nwhile True:\n    # retrieve all events from Google calendar\n    events_result = service.events().list(calendarId=google_calendar_id, singleEvents=True, orderBy='startTime').execute()\n    events = events_result.get('items', [])\n    for event in events:\n        hiro_event_id = create_or_update_event (hiro_cal_id, event)\n\n    time.sleep(60)</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>Try it out by adding new events and changing events in your Google calendar. Within the endless loop, the connector code checks once per minute for new or changed data. Only new or changed events will be written to the HIRO Graph.</p>\n</div>\n<div class=\"listingblock\">\n<div class=\"title\">Calendar event in HIRO Graph</div>\n<div class=\"content\">\n<pre class=\"highlight\"><code class=\"language-json\" data-lang=\"json\">{\n  \"/etag\" : \"3130664879208000\",\n  \"ogit/Schedule/endTime\" : \"2019-08-09T10:30:00+02:00\",\n  \"ogit/Schedule/location\" : \"somewhere else\",\n  \"ogit/Schedule/startTime\" : \"2019-08-09T10:00:00+02:00\",\n  \"ogit/_created-on\" : \"Fri, 09 Aug 2019 06:31:28 GMT\",\n  \"ogit/_creator\" : \"user1@academy.local\",\n  \"ogit/_creator-app\" : \"cjix82rxi000gu473w5kvkpqv\",\n  \"ogit/_graphtype\" : \"vertex\",\n  \"ogit/_id\" : \"cjz3qffjoci6bgp027kuzwx5g\",\n  \"ogit/_is-deleted\" : \"false\",\n  \"ogit/_modified-by\" : \"user1@academy.local\",\n  \"ogit/_modified-by-app\" : \"cjix82rxi000gu473w5kvkpqv\",\n  \"ogit/_modified-on\" : \"Fri, 09 Aug 2019 06:34:30 GMT\",\n  \"ogit/_owner\" : \"academy.local\",\n  \"ogit/_type\" : \"ogit/Schedule/Event\",\n  \"ogit/_v\" : \"3\",\n  \"ogit/_v-id\" : \"1565332470438-Swxvdw\",\n  \"ogit/_xid\" : \"CAL-cjz1frals2bn2gp02iq46j9ex,-57f7qq54o0hf25sr3jcereti4b\",\n  \"ogit/title\" : \"TEST\"\n}</code></pre>\n</div>\n</div>\n</div>\n</div>\n<div class=\"sect1\">\n<h2 id=\"_summary\">Summary</h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>In this tutorial, we have implemented our first HIRO connector.The connector imports calendar events from a Google calendar into the HIRO Graph.</p>\n</div>\n<div class=\"paragraph\">\n<p>We have performed the following steps for implementing this connector:</p>\n</div>\n<div class=\"ulist checklist\">\n<ul class=\"checklist\">\n<li>\n<p><i class=\"fa fa-check-square-o\"></i> Created a new project and a service account in Google Cloud Platform</p>\n</li>\n<li>\n<p><i class=\"fa fa-check-square-o\"></i> Created a new Google Calendar and configured permissions</p>\n</li>\n<li>\n<p><i class=\"fa fa-check-square-o\"></i> Established an authenticated session with HIRO</p>\n</li>\n<li>\n<p><i class=\"fa fa-check-square-o\"></i> Fetched events from Google Calendar</p>\n</li>\n<li>\n<p><i class=\"fa fa-check-square-o\"></i> Written retrieved calendar events to HIRO</p>\n</li>\n<li>\n<p><i class=\"fa fa-check-square-o\"></i> Create a loop to continuously poll events and write changes to HIRO</p>\n</li>\n</ul>\n</div>\n<div class=\"paragraph\">\n<p>As you probably have noticed, we have copied only a subset of the calendar event attributes to HIRO. You may extend the code to make more attributes available.</p>\n</div>\n<div class=\"paragraph\">\n<p>Now that you have calendar data in HIRO, you can automate some tasks to manage your calendar. If you haven&#8217;t read the tutorial about <a href=\"/7.0/tutorials/automation-tasks/\">creating automation tasks</a> yet, we suggest to continue there.</p>\n</div>\n</div>\n</div>","document":{"main":"Tutorial","title":"Tutorial: Developing a Connector for HIRO","subtitle":"Developing a Connector for HIRO"},"fields":{"toc":true,"location":["tutorials","tutorial-google-calendar-connector"]}},"sidebarYaml":{"id":"0acf6fc1-95eb-5854-8f81-d5561b07a582","showIndex":null}},"pageContext":{"id":"623b5f38-e113-5308-94bf-0b9bcb29e10c","parent":"tutorials"}},"staticQueryHashes":["1010459453","1010459453","2356112386","2356112386","2603905930","2603905930","3026652197","3026652197","3167850324","3167850324","63159454","63159454"]}