This project's code uses the CircuitPython OAuth Library for authentication with Google services. Due to Google's update to the OAuth "authentication flow", the library became incompatible. As a result, this project does not currently work (but may in the future)!
Before you can use the Google Calendar API to request events on your calendar, you must first authenticate the device with Google's authentication server.
We've handled this authorization "flow" by creating a CircuitPython library for Google's implementation of OAuth2.0 and an application to run on your device.
Secrets File Setup
Open the settings.toml file on your CircuitPython device using Mu or your favorite text editor. If you don't have one, copy the generic one below. You're going to edit this file to enter your Google API credentials.
-
Change
ADAFRUIT_AIO_USERNAMEto your Adafruit IO username -
Change
ADAFRUIT_AIO_KEYto your Adafruit IO active key -
Change
timezoneto"Etc/UTC" -
Change
google_client_idto the Google client ID you obtained in the previous step -
Change
google_client_secretto the Google client ID you obtained in the previous step
Your settings.toml file should look like this:
# This file is where you keep secret settings, passwords, and tokens! # If you put them in the code you risk committing that info or sharing it CIRCUITPY_WIFI_SSID="your-wifi-ssid" CIRCUITPY_WIFI_PASSWORD="your-wifi-password" ADAFRUIT_AIO_USERNAME="my_username" ADAFRUIT_AIO_KEY="my_key" timezone="America/New_York" # http://worldtimeapi.org/timezones google_client_id="YOUR_GOOGLE_CLIENT_ID" google_client_secret="YOUR_GOOGLE_CLIENT_SECRET"
Add CircuitPython Code and Project Assets
To use with CircuitPython, you need to first install a few libraries, into the lib folder on your CIRCUITPY drive. Then you need to update code.py with the example script.
Thankfully, we can do this in one go. In the example below, click the Download Project Bundle button below to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, open the directory MagTag_Google_Calendar/ and then click on the directory that matches the version of CircuitPython you're using and copy the contents of that directory to your CIRCUITPY drive.
CIRCUITPY
# SPDX-FileCopyrightText: 2021 Brent Rubell, written for Adafruit Industries
#
# SPDX-License-Identifier: Unlicense
from os import getenv
from adafruit_oauth2 import OAuth2
from adafruit_display_text.label import Label
from adafruit_bitmap_font import bitmap_font
from adafruit_magtag.magtag import Graphics, Network
from adafruit_display_shapes.rect import Rect
# Get WiFi details, ensure these are setup in settings.toml
ssid = getenv("CIRCUITPY_WIFI_SSID")
password = getenv("CIRCUITPY_WIFI_PASSWORD")
if None in [ssid, password]:
raise RuntimeError(
"WiFi settings are kept in settings.toml, "
"please add them there. The settings file must contain "
"'CIRCUITPY_WIFI_SSID', 'CIRCUITPY_WIFI_PASSWORD', "
"at a minimum."
)
network = Network()
network.connect()
# DisplayIO setup
font_small = bitmap_font.load_font("/fonts/Arial-12.pcf")
font_large = bitmap_font.load_font("/fonts/Arial-14.pcf")
graphics = Graphics(auto_refresh=False)
display = graphics.display
background = Rect(0, 0, 296, 128, fill=0xFFFFFF)
graphics.root_group.append(background)
label_overview_text = Label(
font_large,
x=0,
y=10,
line_spacing=0.75,
color=0x000000,
text="Authorize this device with Google:",
)
graphics.root_group.append(label_overview_text)
label_verification_url = Label(font_small, x=0, y=40, line_spacing=0.75, color=0x000000)
graphics.root_group.append(label_verification_url)
label_user_code = Label(font_small, x=0, y=80, color=0x000000, line_spacing=0.75)
graphics.root_group.append(label_user_code)
label_qr_code = Label(
font_small, x=0, y=100, color=0x000000, text="Or scan the QR code:"
)
graphics.root_group.append(label_qr_code)
# Set scope(s) of access required by the API you're using
scopes = ["https://www.googleapis.com/auth/calendar.readonly"]
# Initialize an OAuth2 object
google_auth = OAuth2(
network.requests,
getenv("google_client_id"),
getenv("google_client_secret"),
scopes,
)
# Request device and user codes
# https://developers.google.com/identity/protocols/oauth2/limited-input-device#step-1:-request-device-and-user-codes
google_auth.request_codes()
# Display user code and verification url
# NOTE: If you are displaying this on a screen, ensure the text label fields are
# long enough to handle the user_code and verification_url.
# Details in link below:
# https://developers.google.com/identity/protocols/oauth2/limited-input-device#displayingthecode
print(
"1) Navigate to the following URL in a web browser:", google_auth.verification_url
)
print("2) Enter the following code:", google_auth.user_code)
label_verification_url.text = (
"1. On your computer or mobile device,\ngo to %s" % google_auth.verification_url
)
label_user_code.text = "2. Enter code: %s" % google_auth.user_code
graphics.qrcode(google_auth.verification_url.encode(), qr_size=2, x=240, y=70)
graphics.display.root_group = graphics.root_group
display.refresh()
# Poll Google's authorization server
print("Waiting for browser authorization...")
if not google_auth.wait_for_authorization():
raise RuntimeError("Timed out waiting for browser response!")
print("Successfully Authenticated with Google!")
print("Add the following lines to your settings.toml file:")
print(f'google_access_token="{google_auth.access_token}"')
print(f'google_refresh_token="{google_auth.refresh_token}"')
graphics.root_group.pop()
graphics.root_group.pop()
graphics.root_group.pop()
label_overview_text.text = "Successfully Authenticated!"
label_verification_url.text = (
"Check the REPL for tokens to add\n\tto your settings.toml file"
)
display.refresh()
Authenticator Code Usage
On your CIRCUITPY drive, rename authenticator.py to code.py. Then, open the CircuitPython REPL using Mu or another serial monitor.
Your CircuitPython device should boot into the Google Authenticator code and display a code and URL.
Navigate to the Google Device page and enter the code you see on your device.
Click Next
Select the Google Account you'd like to use with the calendar viewer.
- We are using the
https://www.googleapis.com/auth/calendar.readonlyscope which will gives an application read-only access to your calendar events.
Since Google has not formally verified the application you created in the previous step, you'll be greeted with a warning.
- Click Advanced
- Then, Click the Go to {your application name} link
Finally, a dialog will appear displaying the application's requested permissions.
Click Allow.
You'll be presented with a dialog telling you the device has been authenticated.
After 5 seconds, the CircuitPython REPL should display a google_access_token and google_refresh_token.
Copy and paste these lines into the settings.toml file.
Your settings.toml file should look like this:
# This file is where you keep secret settings, passwords, and tokens! # If you put them in the code you risk committing that info or sharing it CIRCUITPY_WIFI_SSID="your-wifi-ssid" CIRCUITPY_WIFI_PASSWORD="your-wifi-password" ADAFRUIT_AIO_USERNAME="my_username" ADAFRUIT_AIO_KEY="my_key" timezone="America/New_York" # http://worldtimeapi.org/timezones google_client_id="YOUR_GOOGLE_CLIENT_ID" google_client_secret="YOUR_GOOGLE_CLIENT_SECRET" google_access_token="YOUR_GOOGLE_ACCESS_TOKEN" google_refresh_token="YOUR_GOOGLE_REFRESH_TOKEN"
Now that your device is authorized to make requests to the Google Calendar API, let's use it to fetch calendar events!
Page last edited May 06, 2025
Text editor powered by tinymce.