Example - Retrieving Calendar Events

Posted on
Thu Mar 16, 2023 8:24 am
DaveL17 offline
User avatar
Posts: 6742
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Example - Retrieving Calendar Events

Level of Difficulty: Moderate
Knowledge of Shortcuts: Moderate

This example shows how to retrieve Calendar event information using Shortcuts and a short Python script. This is a basic example in that it only shows the mechanism to get the requested events information back to Indigo. What you do with the data after that is up to you. This example doesn't use Indigo's HTTP API or require authentication. It also runs entirely on the Indigo Server machine (i.e., you can run it from your iPhone, but it won't do anything). It's probably best to be at least somewhat familiar with how to build Shortcuts before attempting to use this example.

Python Script
You'll need a way to run the following Python script--whether it be as an embedded script, linked file or something similar.

Code: Select all
import subprocess

def build_list(my_result):
    """ Construct a list of event tuples """
    result_str = result.decode('utf-8')  # Change bytes object into Unicode string
    result_split = [_.split('\n') for _ in result_str.split(' %% ')]  # Split payload into a list of lists, first on '%%' then on '\n'
    zipped = list(zip(*result_split))  # Zip the lists into a list of tuples (the contents are driven by the shortcut)
    return zipped

num_appt = b'3.0'
result = subprocess.run(['/usr/bin/shortcuts', 'run', 'Get Calendar Events'], input=num_appt, check=True, capture_output=True).stdout
appts = build_list(result)
indigo.server.log(f"{appts}")
There are some nuances about the way this script works.
  • First, to set the number of requested events, the number must be provided as a bytes() object. Values less that 10 must be provided as a float. If you send b'3', it *won't* work (but b'10' *will* work for some reason).
  • Second, the data that the shortcut returns to the script is text data in bytes() format. This script doesn't account for complex objects like file attachments to events.
Shortcut
The shortcut layout:

Screenshot 2023-03-16 at 8.36.09 AM-2.png
Screenshot 2023-03-16 at 8.36.09 AM-2.png (868.63 KiB) Viewed 7402 times


The Shortcuts app isn't currently designed to output "complex" data containers like JSON or ordered lists, so the example uses a simple "hack" to work around this limitation. It puts all the requested information on one line in the list element to ensure that the data are all provided in a single payload. It separates the data elements with [space][percent][percent][space] which is used in the Python script to parse the event data. Setting the event details within the list is a bit tricky (and beyond the scope of this example).

There are some nuances about the way this shortcut works:
  • First, notice the tick mark next to "Provide Output". This option must be enabled or the shortcut won't return anything. Even though it looks like the "Provide Output" setting isn't meaningful because "Use as a Quick Action" is disabled, that's not the case.
  • Second, this shortcut outputs the data as a bytes() object that contains nothing but text. If you're going to try to work with Event attachments or other complex objects, you'll need to base64 encode them (beyond the scope of this example). If you use base64 encoding, you can forego the "Stop and Output" action as base64 encoding outputs by default.
  • Third, "Home" is the name of my calendar. You'll need to change it to one of your named calendars (or set it to examine all calendars).
  • Lastly, for simplicity, this example shortcut doesn't include any error handling.

Result
If the script (and shortcut) run successfully, you'll receive output that looks like this (assuming you haven't changed anything)

Code: Select all
 [('My First Event', 'Mar 20, 2023 at 9:30 AM', 'Mar 20, 2023 at 12:30 PM'), ('My Second Event', 'Mar 21, 2023 at 12:00 AM', 'Mar 21, 2023 at 11:59 PM'), ('My Third Event', 'Mar 24, 2023 at 12:00 AM', 'Mar 27, 2023 at 11:59 PM')]
You can download the shortcut from the Indigo File Library.

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Posted on
Wed Nov 29, 2023 1:16 pm
digtrail offline
Posts: 28
Joined: Jun 02, 2016

Re: Example - Retrieving Calendar Events

Dave,
Thank you soooo much for this script. It's close to getting me back to where I want to be w/ calendar integration. I have no problems getting it to run and output to the log. I know my next question is a pretty basic one, but I'm a pretty basic user of Indigo and don't mess with scripting expect on occasion once or twice every couple of years.
So that said, here's my output
Code: Select all
Script                          [('Night Work', 'Nov 29, 2023 at 5:00 PM', 'Nov 30, 2023 at 7:00 AM'), ('OFF', 'Nov 30, 2023 at 12:00 AM', 'Nov 30, 2023 at 11:59 PM'), ('Put keys in Car 10', 'Nov 30, 2023 at 6:45 AM', 'Nov 30, 2023 at 6:46 AM')]

How do I get chosen info from the output above, in this case OFF (it's the all day event that I want) into its correct variable. I can't remember how to call the log and then output from the log and put it into a script. Here's my old script that did that but it referenced another old calendar input that I've left out.
Code: Select all
if "Day Work" in the_string:
   indigo.variable.updateValue(1422763041, value='true')
else:
   indigo.variable.updateValue(1422763041, value='false')

if "Night Work" in the_string:
   indigo.variable.updateValue(15646541, value='true')
else:
   indigo.variable.updateValue(15646541, value='false')

if "OFF" in the_string:
   indigo.variable.updateValue(790632292, value='true')
else:
   indigo.variable.updateValue(790632292, value='false')

if "VAC" in the_string:
   indigo.variable.updateValue(41667262, value='true')
else:
   indigo.variable.updateValue(41667262, value='false')


Thanks!

Posted on
Wed Nov 29, 2023 1:59 pm
DaveL17 offline
User avatar
Posts: 6742
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Re: Example - Retrieving Calendar Events

No problem! I'm glad you found it useful. The line at the bottom of the script
Code: Select all
indigo.server.log(f"{appts}")
is just a placeholder so you can see if the script has worked. You could leave it in if you wanted, but what you're going to need to do is add some more code to the script to process the data that comes in. So ,
Code: Select all
[('Night Work', 'Nov 29, 2023 at 5:00 PM', 'Nov 30, 2023 at 7:00 AM'), ('OFF', 'Nov 30, 2023 at 12:00 AM', 'Nov 30, 2023 at 11:59 PM'), ('Put keys in Car 10', 'Nov 30, 2023 at 6:45 AM', 'Nov 30, 2023 at 6:46 AM')]
is a list of calendar event tuples that you're going to have to parse.
Code: Select all
for appt in appts:
    if appt[0] == "OFF":
        indigo.variable.updateValue(790632292, value='true')

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Posted on
Wed Nov 29, 2023 2:39 pm
digtrail offline
Posts: 28
Joined: Jun 02, 2016

Re: Example - Retrieving Calendar Events

Thanks! Got it working with my else statements and all. Great little thing to build off of. Much appreciated.

Posted on
Wed Nov 29, 2023 5:08 pm
DaveL17 offline
User avatar
Posts: 6742
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Re: Example - Retrieving Calendar Events

That's great. Good luck!

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Page 1 of 1

Who is online

Users browsing this forum: No registered users and 3 guests