Google Calendar Connector
Google Calendar Connector Help
Version 4
ZappySys Logo File Version: v4
Supported Engine: 4

Google Calendar Connector - Source Code


<?xml version="1.0" encoding="utf-8"?>
<ApiConfig Name="Google Calendar"
           Desc="Read / write Google Calendar data inside your app; perform many Google Calendar operations without coding, just using easy to use high performance API Connector for Google Calendar"
           Slug="google-calendar-connector"
           Id="4ebd0208-8328-5d69-8c44-ec50939c0967"
           Logo="data:image/jpeg;base64,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"
           Version="4"
           EngineVersion="4"
           >
  <VersionHistory>
    <Change Type="Modified" Date="2022-10-13">Added retry logic on error code 429 (Too many requests).</Change>
    <Change Date="2021-11-26">Initial version</Change>
  </VersionHistory>

  <ServiceUrls>
    <ServiceUrl Name="Google Calendar API v3" Url="https://www.googleapis.com/calendar/v3/" />
  </ServiceUrls>
  <Auths>
    <Auth Name="OAuth" Label="User Account" HelpLink="https://zappysys.com/links/?id=10002"
          Type="OAuth" ConnStr="Provider=Google;ScopeSeparator={space};"
          TestEndPoint="list_calendars"
      >
      <Notes>
        <![CDATA[
        <p>To make this work you will have to create an OAuth application. To register an App, perform the following steps (Detailed steps found in the help link at the end):<p />
<ol>
  <li>Go to <a target="_blank" href="https://console.developers.google.com/">Google API Console</a></li>
  <li>From the Project Dropdown (usually found at the top bar) click Select Project</li>
  <li>On Project Propup click <b>CREATE PROJECT</b></li>
  <li>Once project is created you can click Select Project to switch the context (You can click on Notification link or Choose from Top Dropdown)</b></li>
  <li>Click <b>ENABLE APIS AND SERVICES</b></li>
  <li>Now we need to enable Google Drive API.</li>
  <li>Search <b>Google Drive API</b>. Select and click <b>ENABLE</b></li>
  <li>Go to back to main screen of <a target="_blank" href="https://console.developers.google.com/">Google API Console</a></li>
  <li>Click <b>OAuth Concent Screen</b> Tab. Enter necessary details and Save.</li>
  <li>Click <b>Credentials Tab</b></li>
  <li>Click <b>CREATE CREDENTIALS</b> (some where in topbar) and select <b>OAuth Client ID</b> option.</li>
  <li>When prompted Select Application Type as <b>Desktop App</b> and click Create to receive your ClientID and Secret. You can use this information now to configure Connection with UseCustomApp=true.</li>
</ol>
        ]]>
      </Notes>
      <Params>
        <Param Name="UseCustomApp" Value="True" Required="True" Hidden="False" Desc="Use your own app credentials or inbuilt app provided by ZappySys for ease of use. If you choose UseCustomApp=true then make sure to obtain your own ClientId and Secret using steps provided (Click [Steps to Configure] link found next to Authentication Type dropdown)" />
        <Param Name="ClientId" VisibleIf="UseCustomApp" RequiredIf="UseCustomApp"/>
        <Param Name="ClientSecret" Secret="True" VisibleIf="UseCustomApp" RequiredIf="UseCustomApp" />
        <Param Name="Scope" Value="https://www.googleapis.com/auth/calendar" />
        <Param Name="RetryMode" Value="RetryWhenStatusCodeMatch" Options="None;RetryAny;RetryWhenStatusCodeMatch;" Hidden="True" />
        <Param Name="RetryStatusCodeList" Value="403|429" Hidden="True" />
        <Param Name="RetryCountMax" Value="5" Hidden="True" />
        <Param Name="RetryMultiplyWaitTime" Value="True" Hidden="True" />   		
      </Params>
    </Auth>

    <Auth Name="ServiceAccount" Label="Service Account (Using Private Key File)" HelpLink="https://cloud.google.com/docs/authentication/production#create_service_account"
        Type="OAuth" ConnStr="Provider=Google;UseCustomApp=True;UseClientCertificate=True;CertificateStorageType=PfxFile;CertificatePath=[$PrivateKeyPath$];GrantType=ClientCredentials;"
        TestEndPoint="list_calendars"
  >
      <Params>
        <Param Name="ClientId" Label="Service Account Email" Desc="This is service account email ID (e.g. some_name@my_project.iam.gserviceaccount.com)" Required="True" />
        <Param Name="PrivateKeyPath" Label="Service Account Private Key Path (i.e. *.p12)" Desc="File path for p12 file (i.e. Private Key file for service account). Keep this key file secure" Required="True" />
        <Param Name="Scope" Value="https://www.googleapis.com/auth/calendar" />
        <Param Name="RetryMode" Value="RetryWhenStatusCodeMatch" Options="None;RetryAny;RetryWhenStatusCodeMatch;" Hidden="True" />
        <Param Name="RetryStatusCodeList" Value="403|429" Hidden="True" />
        <Param Name="RetryCountMax" Value="5" Hidden="True" />
        <Param Name="RetryMultiplyWaitTime" Value="True" Hidden="True" />   
      </Params>

      <Notes>
        <![CDATA[Use these steps to authenticate as service account rather than Google / GSuite User. Learn more about service account <a href="https://cloud.google.com/iam/docs/service-accounts" target="_blank">here</a><p />
Basically to call Google API as Service account we need to perform following steps listed in 3 sections (Detailed steps found in the help link at the end)<p />
<h3>Create Project</h3>
First thing is create a Project so we can call Google API. Skip this section if you already have Project (Go to next section)
<ol>
  <li>Go to <a target="_blank" href="https://console.developers.google.com/">Google API Console</a>
  <li>From the Project Dropdown (usually found at the top bar) click Select Project</li>
  <li>On Project Propup click <b>CREATE PROJECT</b></li>
  <li>Once project is created you can click Select Project to switch the context (You can click on Notification link or Choose from Top Dropdown)</b></li>
  <li>Click <b>ENABLE APIS AND SERVICES</b></li>
  <li>Now we need to enable API - Google Calendar API</li>
  <li>Search <b>Drive</b>. Select and click <b>ENABLE</b></li>
</ol>

<h3>Create Service Account</h3> 
Once Project is created and APIs are enabled we can now create a service account under that project. Service account has its ID which looks like some email ID (not to confuse with Google /Gmail email ID)
<ol>
  <li>Go to <a target="_blank" href="https://console.cloud.google.com/projectselector/iam-admin/serviceaccounts/create?supportedpurview=project/">Create Service Account</a>
  <li>From the Project Dropdown (usually found at the top bar) click Select Project</li>
  <li>Enter <b>Service account name</b> and <b>Service account description</b></li>
  <li>For Role, do not select anything for now and Click <b>Continue</b> and then click <b>Done</b>. Next we will create Key.</li>
</ol>

<h3>Create Key</h3>
Once service account is created we need to create key file (i.e. credentials).
<ol>
  <li>In the Cloud Console, click the email address for the service account that you created.</li>
  <li>Click <b>Keys</b>.</li>
  <li>Click <b>Add key</b>, then click <b>Create new key</b>.</li>
  <li>Click <b>Create</b> and select <b>P12</b> format. A <b>P12 key file</b> is downloaded to your computer. We will use this file in our API connection.</li>
  <li>Click <b>Close</b>.</li>
  <li>Now you may use downloaded *.p12 key file as secret file and Service Account Email as Client ID (e.g. <b>some-service-account-name@your-project-id.iam.gserviceaccount.com</b> ).</li>
</ol>

<h3>Add Permission</h3>
Now last thing is give read/write permission to Service Account for Calendar you like to access using API. 
<ol>
  <li>Copy the email address of your service account we created in previous step (its usually like this some-service-account-name@your-project-id.iam.gserviceaccount.com).</li>
  <li>Login to https://calendar.google.com/calendar and make sure you see the calendar you like to access via API</li>
  <li>On the left, find the "My calendars" section. To expand it, click the Down arrow Down arrow.</li>
  <li>Hover over the calendar you want to share, and click 3 dots next to it. Click "Settings and sharing".</li>
  <li>Find "Share with specific people", Click Add people button and enter the service account email id we obtained in the previous section. </li>
  <li>Select correct permission you like to give for sharing. Click Send button to share. Thats it now we can read / write Calendar Events using Service account approach.</li>
  <li>For more information check this link https://support.google.com/calendar/answer/37082?hl=en</li>
</ol>

]]>
      </Notes>
    </Auth>

  
  </Auths>


  <Template> 
  </Template>

  <EndPoints>
    <!--=====================================
        ========= LIST CALENDARS ============
        =====================================-->  
    <EndPoint Name="list_calendars" 
              Label="List calendars" 
              Desc="Lists calendars"
	          Url="/users/me/calendarList" 
              Method="GET"
              Filter="$.items"
              CachedTtl="0"
              >
        <OutputColumns>
            <Column Name="id" Label="Id" DataType="DT_WSTR" Length="300" />
            <Column Name="summary" Label="Summary" DataType="DT_WSTR" Length="300" />
            <Column Name="description" Label="Description" DataType="DT_WSTR" Length="1500" />
            <Column Name="timeZone" Label="TimeZone" DataType="DT_WSTR" Length="300" />
        </OutputColumns>                  
    </EndPoint>

    <!--=====================================
        =========== LIST EVENTS =============
        =====================================-->  
    <EndPoint Name="list_events" 
              Label="List events" 
              Desc="Lists events"
	          Url="/calendars/[$CalendarId$]/events"
              Method="GET"
              Filter="$.items"
              >    
        <Params>
            <Param Name="CalendarId"
                   OptionsEndPoint="list_calendars"
                   OptionsEndPointValueColumn="Id"
                   OptionsEndPointLabelColumn="Summary"
                   Required="True"/>
            <Param Name="NextUrlAttributeOrExpr"
                    Value="$.nextPageToken"
                    Type="Property"
            />
            <Param Name="NextUrlSuffix"
                    Value="pageToken=&lt;%nextlink%&gt;"
                    Type="Property"
            />                    
        </Params>      
        <OutputColumns>
            <Column Name="id" Label="Id" DataType="DT_WSTR" Length="300" />
            <Column Name="kind" Label="Kind" DataType="DT_WSTR" Length="300" />
            <Column Name="status" Label="Status" DataType="DT_WSTR" Length="300" />
            <Column Name="htmlLink" Label="HtmlLink" DataType="DT_WSTR" Length="1000" />
            <Column Name="created" Label="CreatedAt" DataType="DT_DBTIMESTAMP" />
            <Column Name="updated" Label="UpdatedAt" DataType="DT_DBTIMESTAMP" />
            <Column Name="summary" Label="Summary" DataType="DT_WSTR" Length="300" />
            <Column Name="description" Label="Description" DataType="DT_WSTR" Length="4000" />
            <Column Name="creator.email" Label="CreatorEmail" DataType="DT_WSTR" Length="300" />
            <Column Name="organizer.email" Label="OrganizerEmail" DataType="DT_WSTR" Length="300" />
            <Column Name="organizer.displayName" Label="OrganizerDisplayName" DataType="DT_WSTR" Length="300" />

            <Column Name="start.dateTime" Label="StartsAt" DataType="DT_DBTIMESTAMP" />
            <Column Name="start.timeZone" Label="StartTimeZone" DataType="DT_WSTR" Length="300" />
            <Column Name="end.dateTime" Label="EndsAt" DataType="DT_DBTIMESTAMP" />
            <Column Name="end.timeZone" Label="EndTimeZone" DataType="DT_WSTR" Length="300" />
            <Column Name="attendees" Label="Attendees" DataType="DT_NTEXT"/>
        </OutputColumns>                      
    </EndPoint>    

    <!--=====================================
        ============ GET EVENT ==============
        =====================================-->  
    <EndPoint Name="get_event" 
              Label="Get event" 
              Desc="Gets event"
	          Url="/calendars/[$CalendarId$]/events/[$EventId$]"
              Method="GET"
              >    
        <Params>
            <Param Name="CalendarId"
                   OptionsEndPoint="list_calendars"
                   OptionsEndPointValueColumn="Id"
                   OptionsEndPointLabelColumn="Summary"
                   Required="True"/>
            <Param Name="EventId"
                   OptionsEndPoint="list_events"
                   OptionsEndPointValueColumn="Id"
                   OptionsEndPointLabelColumn="Summary"
                   OptionEndPointParameters="CalendarId=[$CalendarId$];"
                   Required="True"/>                   
        </Params>      
        <OutputColumns>
            <Column Name="id" Label="Id" DataType="DT_WSTR" Length="300" />
            <Column Name="kind" Label="Kind" DataType="DT_WSTR" Length="300" />
            <Column Name="status" Label="Status" DataType="DT_WSTR" Length="300" />
            <Column Name="htmlLink" Label="HtmlLink" DataType="DT_WSTR" Length="1000" />
            <Column Name="created" Label="CreatedAt" DataType="DT_DBTIMESTAMP" />
            <Column Name="updated" Label="UpdatedAt" DataType="DT_DBTIMESTAMP" />
            <Column Name="summary" Label="Summary" DataType="DT_WSTR" Length="300" />
            <Column Name="description" Label="Description" DataType="DT_WSTR" Length="4000" />
            <Column Name="creator.email" Label="CreatorEmail" DataType="DT_WSTR" Length="300" />
            <Column Name="organizer.email" Label="OrganizerEmail" DataType="DT_WSTR" Length="300" />
            <Column Name="organizer.displayName" Label="OrganizerDisplayName" DataType="DT_WSTR" Length="300" />
            <Column Name="start.dateTime" Label="StartsAt" DataType="DT_DBTIMESTAMP" />
            <Column Name="start.timeZone" Label="StartTimeZone" DataType="DT_WSTR" Length="300" />
            <Column Name="end.dateTime" Label="EndsAt" DataType="DT_DBTIMESTAMP" />
            <Column Name="end.timeZone" Label="EndTimeZone" DataType="DT_WSTR" Length="300" />
            <Column Name="attendees" Label="Attendees" DataType="DT_NTEXT"/>
        </OutputColumns>                                    
    </EndPoint>      

    <!--=====================================
        =========== CREATE EVENT ============
        =====================================-->  
    <EndPoint Name="create_event" 
              Label="Create event" 
              Desc="Creates event"
	          Url="/calendars/[$CalendarId$]/events"
              Method="POST"
              DotAsPath="True"
              ContentType="application/json"
              JsonRowFormat="Multicontent"
              >    
        <Params>
            <Param Name="CalendarId"
                   OptionsEndPoint="list_calendars"
                   OptionsEndPointValueColumn="Id"
                   OptionsEndPointLabelColumn="Summary"
                   Required="True"/>
        </Params>      
        <Body><![CDATA[{$rows$}]]></Body>
        <InputColumns>
            <Column Name="start.date" Label="StartsOn" Desc="Use StartsOn OR StartsAt" Example="2021-12-24" DataType="DT_DBDATE" />
            <Column Name="start.dateTime" Label="StartsAt" Desc="Use StartsOn OR StartsAt" Example="2021-12-24T18:30:00" DataType="DT_DBTIMESTAMP" />
            <Column Name="start.timeZone" Label="StartsInTimeZone" DataType="DT_WSTR" Length="300" />
            <Column Name="end.date" Label="EndsOn" DataType="DT_DBDATE" Example="2021-12-24"/>
            <Column Name="end.dateTime" Label="EndsAt" DataType="DT_DBTIMESTAMP" Example="2021-12-24T18:30:00" />
            <Column Name="end.timeZone" Label="EndsInTimeZone" DataType="DT_WSTR" Length="300" />
            <Column Name="attachments.fileUrl" Label="Kind" DataType="DT_WSTR" Length="300" />
            <Column Name="attendees" Label="Attendees" DataType="DT_NTEXT"/>
            <Column Name="description" Label="Description" DataType="DT_WSTR" Length="4000" />
            <Column Name="guestsCanInviteOthers" Label="GuestsCanInviteOthers" DateType="DT_BOOL" />
            <Column Name="guestsCanModify" Label="GuestsCanModify" DateType="DT_BOOL" />
            <Column Name="guestsCanSeeOtherGuests" Label="GuestsCanSeeOtherGuests" DateType="DT_BOOL" />
            <Column Name="location" Label="Location" DateType="DT_WSTR" Length="1024" />
            <Column Name="recurrence" Label="Recurrence" HelpLink="https://developers.google.com/calendar/api/v3/reference/events/insert" DataType="DT_WSTR" Length="1024"/>
            <Column Name="status" Label="Status" DataType="DT_WSTR" Length="50" Example="confirmed OR tentative OR cancelled"/>
            <Column Name="summary" Label="Summary" DataType="DT_WSTR" Length="300" />
            <Column Name="transparency" Label="Transparency" DataType="DT_WSTR" Length="300" Example="opaque OR transparent"/>
            <Column Name="visibility" Label="Visibility" DataType="DT_WSTR" Length="300" Example="default OR public OR private OR confidential"/>            
        </InputColumns>                                    
        <OutputColumns>
            <Column Name="id" Label="Id" DataType="DT_WSTR" Length="50" />
            <Column Name="status" Label="Status" DataType="DT_WSTR" Length="50" />
            <Column Name="created" Label="Created" DataType="DT_DBTIMESTAMP"/>
            <Column Name="updated" Label="Updated" DataType="DT_DBTIMESTAMP"/>
            <Column Name="htmlLink" Label="HtmlLink" DataType="DT_WSTR" Length="4000"/>
            <Column Name="iCalUID" DataType="DT_WSTR" Length="1024"/>
            <Column Name="eventType" DataType="DT_WSTR" Length="128"/>
        </OutputColumns>
    </EndPoint>    

    <!--=====================================
        =========== DELETE EVENT ============
        =====================================-->  
    <EndPoint Name="delete_event" 
              Label="Delete event" 
              Desc="Deletes event"
	          Url="/calendars/[$CalendarId$]/events/[$EventId$]"
              Method="DELETE"
              DotAsPath="True"
              ContentType="application/json"
              JsonRowFormat="Multicontent"
              >    
        <Params>
            <Param Name="CalendarId"
                   OptionsEndPoint="list_calendars"
                   OptionsEndPointValueColumn="Id"
                   OptionsEndPointLabelColumn="Summary"
                   Required="True"/>
            <Param Name="EventId"
                   OptionsEndPoint="list_events"
                   OptionsEndPointValueColumn="Id"
                   OptionsEndPointLabelColumn="Summary"
                   Required="True"/>                   
        </Params>      
        <OutputColumns>
            <Column Name="id" Label="Id" DataType="DT_WSTR" Length="50" />
        </OutputColumns>
    </EndPoint>             

    <!--=====================================
        ============ MOVE EVENT =============
        =====================================-->  
    <EndPoint Name="move_event" 
              Label="Move event to another calendar" 
              Desc="Moves event from one calendar to another"
	            Url="/calendars/[$SourceCalendarId$]/events/[$EventId$]/move?destination=[$TargetCalendarId$]"
              Method="POST"
              DotAsPath="True"
              ContentType="application/json"
              JsonRowFormat="Multicontent"
              >    
        <Params>
            <Param Name="SourceCalendarId"
                   OptionsEndPoint="list_calendars"
                   OptionsEndPointValueColumn="Id"
                   OptionsEndPointLabelColumn="Summary"
                   Required="True"/>
            <Param Name="TargetCalendarId"
                   OptionsEndPoint="list_calendars"
                   OptionsEndPointValueColumn="Id"
                   OptionsEndPointLabelColumn="Summary"
                   Required="True"/>                   
            <Param Name="EventId"
                   OptionsEndPoint="list_events"
                   OptionsEndPointValueColumn="Id"
                   OptionsEndPointLabelColumn="Summary"
                   Required="True"/>                   
        </Params>      
        <OutputColumns>
            <Column Name="id" Label="Id" DataType="DT_WSTR" Length="50" />
        </OutputColumns>
    </EndPoint>     
  </EndPoints>



  <!--=====================================
      ============= TABLES ================
      =====================================--> 

  <Tables> 
      <Table Name="Events" 
             Desc="Insert, update, delete and list datasets"
             SelectEndPoint="list_events"
             InsertEndPoint="create_event"
             DeleteEndPoint="delete_event" 
      />
      <Table Name="Calendars"
             SelectEndPoint="list_calendars"
      />
  </Tables>    


  <!--=====================================
      ============ EXAMPLES ===============
      =====================================-->
  <Examples>
    <!-- LIST CALENDARS -->
    <Example Group="ODBC" Label="List calendars" Desc="Lists calendars">
        <Code>
            <![CDATA[SELECT * FROM Calendars]]>
        </Code>
    </Example> 

    <!-- LIST EVENTS -->
    <Example Group="ODBC" Label="List events" Desc="Lists events">
        <Code>
            <![CDATA[SELECT * FROM Events
  WITH (CalendarId='MyCalendarId')]]>
        </Code>
    </Example> 

    <!-- GET EVENT -->
    <Example Group="ODBC" Label="Get event" Desc="Gets event">
        <Code>
            <![CDATA[SELECT * FROM get_event
  WITH (CalendarId='MyCalendarId'
       ,EventId='MyEventId')]]>
        </Code>
    </Example> 

    <!-- CREATE EVENT -->
    <Example Group="ODBC" Label="Create event" Desc="Creates event">
        <Code>
            <![CDATA[INSERT INTO Events(StartsAt, StartsInTimeZone, EndsAt, EndsInTimeZone, Summary,
  Attendees, Description, Location, Status, Transparency, Visibility)
  VALUES ('2021-11-26T16:30:50', 'Europe/Vilnius', '2021-11-27T16:30:50','Europe/Vilnius', 'This is an event',
          null, 'My Description', 'Vilnius', 'confirmed', 'opaque', 'default')
  WITH (CalendarId='YourCalendarId')
        ]]>
        </Code>
    </Example> 

    <!-- DELETE EVENT -->
    <Example Group="ODBC" Label="Get event" Desc="Gets event">
        <Code>
            <![CDATA[DELETE FROM Events
    WITH (CalendarId='MyCalendarId',
    EventId='MyEventId')]]>
        </Code>
    </Example> 

    <!-- MOVE EVENT -->
    <Example Group="ODBC" Label="Move event to a different calendar" Desc="Moves event to a different calendar">
        <Code>
            <![CDATA[UPDATE move_event
  WITH (SourceCalendarId='MySourceCalendarId',
  TargetCalendarId='MyTargetCalendarId',
  EventId='MyEventId'
  )]]>
        </Code>
    </Example>
  </Examples>
</ApiConfig>