Google Calendar API / App Inventor 2 Tutorial

22766 views
Skip to first unread message

Steve Marcus

unread,
Mar 15, 2014, 7:37:23 PM3/15/14
to app-inventor-de...@googlegroups.com

GOOGLE CALENDAR API / APP INVENTOR 2 TUTORIAL


How to view and INSERT calendar events using App Inventor 2 (with no web service scripts).


What's  new for AI2?


- The Parse procedure has gone. I found an easier way to extract data from the json response - the lookup in pairs block. This block is great as it does most of the work for you. You can see where it is being used in the screenshots.


- I have provided the .aia file here for you. In order for it to work, you must first get your own clientID by signing up to google apis (as per the instructions below), and enter it into the strClientID variable in the blocks editor.


- I have only used global variables in this example, in AI2 you now have the option of using local variables, which can make the app slightly more efficient. For an exercise, see if you can convert some of the globals to locals.



1. SETUP

First you need to register your app to use google api here https://console.developers.google.com/project


At the top select ‘CREATE PROJECT’


0.png

Then on the top left, select APIs & Auth, then select Calendar API and turn ON.


1.png

Then go to Credentials and click on ‘CREATE NEW CLIENT ID’.


2.png

In the pop-up box, select ‘Installed Application’. For Installed Application Type, select ‘Android’.


It will then ask you for your package name* and SHA1 fingerprint**. Enter these into the boxes.


* Your package name is of the form appinventor.ai_<yourusername>.<yourappname>

(without the <>).



**How to get SHA1 fingerprint (on PC):

Open Command Prompt on your PC. Navigate to your Java bin directory and type:

keytool -list -keystore c:\path_to_your_key_here.keystore

It will prompt to enter your keystore password, then will display your SHA1 fingerprint. Copy and paste it into the above screen. Then click Create Client ID.


You will then get a summary of your Client ID etc. We need to put these into your app.



2. GETTING AUTHORISATION

a). Get the user to login using Oauth


These sections take place in AppInventor. Here we will use a Webviewer component and some variables.


Enter your Client ID and Redirect URI (the urn:ietf:wg:oauth:2.0:oob one) into two variables (see screenshot below). The variable strResponseType should be initialized as the string “code”.


Construct the OAuth URL as outlined here https://developers.google.com/accounts/docs/OAuth2Login.


The scopes we need to use are:



We also need to make sure to include &access_type=offline.


Then start the Webviewer at the constructed URL:



In the Webviewer, the user is then prompted to enter their google account info and then to ‘Allow access’.



We will use Taifun’s trick of using a clock to monitor the WebViewer PageTitle. This returns an AuthCode. So we want to put this in a variable.



We can now exchange this AuthCode for an Access Token and a Refresh Token.


b). Get an Access Token and Refresh Token -

We then need to do a Web POST using the Web component, to get an access token and a refresh token. We point the Web url to https://accounts.google.com/o/oauth2/token.


We then construct the headers, URL and POST data like so (note the AuthCode we got in the previous step is sent in the POST data):



NOTE: As you can see above, the Request Header must contain

Content-Type: application/x-www-form-urlencoded.


The Post Data must contain the following key value pairs, which are put in lists:

Code: {your AuthCode}

client_id: {your ClientID}

redirect_uri: {your RedirectURI}

grant_type: authorization_code


You can see in the above screenshot we are using the AuthCode from step 2a) in this call.


Now we use the Web1.GotText block to let us know if the response was successful, and if so, extract from the response content the access token and refresh token, using some lookup in pairs blocks.


We then put these values into two variables strAccessToken and strRefreshToken:




NOW WE HAVE ACCESS AND WE CAN DO LOTS OF CALENDAR THINGS! Here are three examples from the app:


3. GETTING A LIST OF CALENDARS


A user can have more than one calendar, so we can get a list of all of their calendars so they can choose which one they want to work on. We do this by using the Web component again and doing a Web1.Get to the following URL:

https://www.googleapis.com/calendar/v3/users/me/calendarList?access_token={your access token}


(Note we are using the access token we received in the previous step). Here’s the blocks to do that:



We then use the Web1.GotText block for the response. When the response is successful (if response code = 200), we can get all their calendar IDs and put them in a list:


The getCalendarIds procedure we have called above is shown here: Note we are using lookup in pairs again to extract the data.



We can then stick these values into some buttons and offer the user an option to choose which calendar they want to work on:



The example .apk and .aia contains 2 further examples of working with the calendar API - displaying calendar entries, and inserting a calendar entry.


4. DISPLAYING CALENDAR ENTRIES


Now that the user has selected a calendar, we can retrieve a list of entries from their calendar and display it in the app.


We do this by using Web1.Get again. According to the API docu, the URL for getting calendar entries is:

https://www.googleapis.com/calendar/v3/calendars/calendarId/events


So we simply construct this URL (including the access token) in App Inventor like so (note we are using the selected CalendarID from the previous step). For the example we are also making MaxResults=5 and SingleEvents=true.


Then we use Web1.GotText again to see if we get a successful response. If successful, we can again start a procedure which uses lookup in pairs to extract the results and display the items on the screen:


Here is the procedure getEventData that grabs the data and displays it on the screen:



And the result:




5. INSERTING A CALENDAR ENTRY


Now we come to inserting a calendar entry. According to the API docu, we need to do a Web HTTP POST to the following URL.

https://www.googleapis.com/calendar/v3/calendars/calendarId/events


We have done a POST before so we can do the same again easily enough.


The example app uses Textboxes so the user can enter the details of the event. We want the following things from the user:


Date

Start Time

End Time

Event Title

Event Description

Location (where is it?)

Do they want a reminder?




When the user submits this form, first we need to construct the start dateTime and end dateTime in RFC3339 format, which is what google calendar accepts. We can do this by using a text join block, getting the items from the text boxes and interspersing them with the correct text pieces (note we are also setting addReminder to true or false depending on the checkbox input):



Next we need to construct the POST Data in JSON format as outlined here. I made a variable called strPostText and constructed it there, again using a make text block, the previously constructed RFC3339 dateTimes, and the remaining textbox inputs:


Atfer that is done, we now make another POST call using the Web component.


In the header we need

Content-Type: application/json

Authorization: Bearer {your access token}


Then we use Web1.PostText to post the strPostText variable we constructed above:




Then we use Web1.GotText again to receive the response:




THAT’S IT! If we get a successful response, the event was created!


Now refresh/re-sync the calendar on your phone, or jump on the internet, go to your google calendar, and you will see the event has been created!




So there you have it. Happy google calendar API’ing!


GoogleCalendarAPI.aia
GoogleCalendarAPI.apk

Scott Ferguson

unread,
Mar 16, 2014, 12:05:22 AM3/16/14
to app-inventor-de...@googlegroups.com
Nicely done, Steve!
Thanks for sharing this :)
---
hAPPy INVENTORing!
Scott

Now we come to inserting a calendar entry. According to the API docu<span style="font

...

Zoran Kukulj

unread,
Mar 16, 2014, 4:08:52 AM3/16/14
to app-inventor-de...@googlegroups.com
Great stuff, thanks Marcus!


--
(you have received this message from the App Inventor Developers Library)
---
You received this message because you are subscribed to the Google Groups "App Inventor Developers Library" group.
To unsubscribe from this group and stop receiving emails from it, send an email to app-inventor-develope...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Akash Pi

unread,
Mar 18, 2014, 1:03:34 AM3/18/14
to app-inventor-de...@googlegroups.com
This is great! I am planning to make a project that helps you manage your homework assignments and test for school. Do you know how I could get it to remind me whenever there is an upcoming event?

Now we come to inserting a calendar entry. According to the API docu<span style="font

...

phantomfoot

unread,
Mar 18, 2014, 1:51:01 AM3/18/14
to app-inventor-de...@googlegroups.com
Yes, have a look at inserting the calendar event, you have the option there of setting a reminder. If it is set, a reminder will pop up on your phone. You can also look at sending reminder type and reminder time (e.g 15 minutes before, 1 hour before) in your call.

Forest chung

unread,
Mar 20, 2014, 11:52:55 AM3/20/14
to app-inventor-de...@googlegroups.com
Hi,

I download and installed the apk file, the first step OAuth, I have no problem, but when I click the 2. get Token, it return Error getting data - try again. may I know did I miss some steps that I might have to do before I can get it run?

Al
Great stuff, thanks Marcus!


<s
...

phantomfoot

unread,
Mar 21, 2014, 6:11:35 PM3/21/14
to app-inventor-de...@googlegroups.com
Hmm not sure what it could be, it worked for me. You could try load the aia file and run the app that way to find out where the error is (maybe see what you get back in the response content for getToken).

TripleT

unread,
Mar 21, 2014, 6:21:21 PM3/21/14
to app-inventor-de...@googlegroups.com
Hi,

Thanks again for all your help! I was wondering was the web1.gottext block cropped because we don't need to fill that part out or was there something there?

phantomfoot

unread,
Mar 21, 2014, 8:09:20 PM3/21/14
to app-inventor-de...@googlegroups.com
It was cropped just because some blocks were not relevant to that particular step. They appear in the previous steps.

Forest chung

unread,
Mar 21, 2014, 11:09:02 PM3/21/14
to app-inventor-de...@googlegroups.com
Actually, I don't even see "In the Webviewer, the user is then prompted to enter their google account info and then to ‘Allow access’. " this step, after I click the Start OAuth and loged in..., is this somethings wrong with my OAuth keystore? I am new to use gen keystore here... and suggestion?

Forest chung

unread,
Mar 22, 2014, 12:21:54 AM3/22/14
to app-inventor-de...@googlegroups.com
Thanks phantomfoot, 

I got this: response code: 400, response type: application/json, response content: {error: invalid_grant}

do you have any cue?

Al

phantomfoot

unread,
Mar 24, 2014, 8:18:07 PM3/24/14
to app-inventor-de...@googlegroups.com
I cannot replicate the invalid_grant error.

Some things to try:

Add access_type=offline in your request

Double check the redirect_uri is the same as in your google api console

Make sure the time on your clock is the correct time

The refresh token limit has been exceeded



phantomfoot

unread,
Mar 24, 2014, 8:25:45 PM3/24/14
to app-inventor-de...@googlegroups.com
Also of course check your AuthCode is a valid code and it is returning AuthCode properly in the previous step (since we use that in the call).

Susan M.

unread,
Apr 11, 2014, 5:54:05 PM4/11/14
to app-inventor-de...@googlegroups.com
Thanks so much for posting the .aia file. No one else has indicated that they have had this problem. But when I download the .aia to my computer, then import it into AI2, the blocks don't load properly. For example, for Screen1 in Blocks mode, I get the message, "The blocks area did not load properly. Changes to the blocks for screen 4618364592848896_Screen1 will not be saved.". I get similar messages for both of the other screens. Any insights?
-- Susan

The example .apk and .aia contains 2 further examples of working with the calendar API - <span style="font-siz

...

phantomfoot

unread,
Apr 12, 2014, 5:10:56 AM4/12/14
to app-inventor-de...@googlegroups.com
Hi Susan,

Hmm not sure what that could be. I just tested it and it is loading up fine for me.

Have a look over at the MIT App Inventor forums, there are some posts about it..

Otherwise create a new post there and maybe someone can help you.

Susan M.

unread,
Apr 13, 2014, 9:56:03 PM4/13/14
to app-inventor-de...@googlegroups.com
Steve,

I posted to the App Inventor forum and got the answer. For others: I imported the .aia using Chrome (I was using Firefox), closed all of the comment bubbles, and switched back over to Firefox. No error message and all of the code was there! Thanks so much! -- Susan

Scott Ferguson

unread,
Apr 14, 2014, 5:36:45 PM4/14/14
to app-inventor-de...@googlegroups.com
Hi Susan M.-
Scott here.
Glad you got it sorted out.
I used to use Firefox with App Inventor but as my projects grew in size started to have memory issues.
I moved to Chrome which seems to handle memory better.
---
hAPPy INVENTORing!

Shay Ben Dov

unread,
Apr 26, 2014, 5:02:24 PM4/26/14
to app-inventor-de...@googlegroups.com

I'm getting error 400 when start using the GoogleCalendarAPI demo apk

How can avoid this message

Thanks

Shay Ben Dov

The example .apk and .aia contains 2 further examples of working with the calendar API - <span style="font-siz

...

Scott Ferguson

unread,
Apr 26, 2014, 7:27:44 PM4/26/14
to app-inventor-de...@googlegroups.com
I am not familiar with phantomfoot's calendar app, but a search for the error 400 would indicate that the problem may be in the data you are entering that gets attached to the url for the calendar api.
Check if you are entering the correct data. Does he provide an example to use for testing?
---
Scott

Gabriele Cozzolino

unread,
May 3, 2014, 7:12:06 AM5/3/14
to app-inventor-de...@googlegroups.com
This is an awesome tutorial, thanks! Can this be used just to identify the user and gets its data?

Scott Ferguson

unread,
May 3, 2014, 8:54:07 AM5/3/14
to app-inventor-de...@googlegroups.com
I think you would need the user's password as well as their email address.
---

Scott

Gabriele Cozzolino

unread,
May 4, 2014, 10:24:40 AM5/4/14
to app-inventor-de...@googlegroups.com
This is not working I'm receiving error invalid_grant and I already check what you suggest above, any other hint? Thanks

Scott Ferguson

unread,
May 4, 2014, 6:53:52 PM5/4/14
to app-inventor-de...@googlegroups.com
Hi Gabriele-
I host the tutorial here but unfortunately don't know how the demo app works.
---
Scott

phantomfoot

unread,
May 4, 2014, 7:29:16 PM5/4/14
to app-inventor-de...@googlegroups.com
As stated before I cannot replicate the error, so I am not sure why you are getting it. Are you using the apk or aia? And where exactly is the error occurring?

Gabriele Cozzolino

unread,
May 5, 2014, 1:30:52 AM5/5/14