Calendar access example

This is pretty trivial, but is my first attempt at calendar access, and my first scriptable script. It’s work in progress, currently it just throws up a list of this weeks calendar events. Ultimately I want to replace a Workflow App script I have that creates calendar events in either/both Omnifocus (for home calendars) or Todoist (for Work calendars). But the hard part is done already!

function handleEvents(events) {
    let uiTable = new UITable();
    let i;
    for (i = 0; i < events.length; i++) {
        let uiTableRow = new UITableRow();
        let event = events[i];
        console.log ('Event: ' + event.title);
        let titleCell = uiTableRow.addText(event.title);
        titleCell.widthWeight = 80;
        uiTableRow.height = 40;
        uiTableRow.cellSpacing = 10;
        uiTable.addRow(uiTableRow);
    }
    QuickLook.present(uiTable);
}

function handleErr(val) {
    console.error(val);
}

function handleCalendars(calendars) {
    let i;
    for (i = 0; i < calendars.length; i++) {
        let calendar = calendars[i];
        console.log ('Calendar: ' + calendar.title);
    }
    CalendarEvent.thisWeek().then(handleEvents, handleErr);
}

Calendar.forEvents().then(handleCalendars, handleErr);
4 Likes

Awesome! I’ve tweaked your script to suit my needs, and thought it was worth sharing here:

    let uiTable = new UITable();
    let i;
    for (i = 0; i < events.length; i++) {
        let uiTableRow = new UITableRow();
        let event = events[i];
        if (event.isAllDay) continue;
        let titleCell = uiTableRow.addText(event.title);
        uiTableRow.addText(formatTime(event.startDate));
        uiTableRow.addText(formatTime(event.endDate));
        uiTableRow.height = 40;
        uiTableRow.cellSpacing = 10;
        uiTable.addRow(uiTableRow);
    }
    QuickLook.present(uiTable);
}

function handleErr(val) {
    console.error(val);
}

function handleCalendars(calendars) {
    let i;
    for (i = 0; i < calendars.length; i++) {
        let calendar = calendars[i];
        console.log ('Calendar: ' + calendar.title);
    }
    CalendarEvent.thisWeek().then(handleEvents, handleErr);
}

function formatTime(date) {
  return date.toLocaleTimeString("en-GB", {hour: "2-digit", minute: "2-digit"});
}

CalendarEvent.today().then(handleCalendars, handleErr);

I’m focusing on events for today, which are not all day events, and am displaying the start and end time for each event too :slight_smile:


Edit: Fixed the formatTime function based on a tip from @rob! The original is here:

function formatTime(date) {
  let hours = date.getHours();
  let minutes = date.getMinutes();
  let time = '';
  if (hours < 10) {
    time += '0';
  }
  time += hours;
  time += ':';
  if (minutes < 10) {
    time += '0';
  }
  time += minutes;
  return time;
}
2 Likes

Maybe this would work for you for the formatTime function?

function formatTime(date) {
	return date.toLocaleString("de-AT", {hour: "2-digit", minute: "2-digit"});
}
3 Likes

It would! This is what I get for running with what I remember :laughing:

1 Like

A post was split to a new topic: Showing Upcoming Days off Work

My apologies if this is a basic question, where is the documentation for the .then() method being used in CalendarEvent.thisWeek(), I did not find it within the Scriptable documentation, thank you

NOTE: Found it, standard JS built-in object

Indeed; for those that did not know either (like me some weeks ago):

Just a heads up. I will recommend using await instead of .then, especially in Scriptable. This means that the following:

Photos.latestPhoto().then(photo => {
  // ...
})

Becomes:

let photo = await Photos.latestPhoto()

There’s several reasons I would recommend that, both in general and in terms of Scriptable.

  1. When you get used to it, you’ll most likely find that it’s much more readable and easier to write.
  2. For now it helps Scriptable determine when your script has finished running which is used in various cases. It’s not super critical but it will give a slightly improved experience when using the app and Siri Shortcuts.
  3. Ultimately I’d like to reduce the amount of promises used in the app. This is something I haven’t found the best approach for yet and even if I had, I don’t have the time for it for version 1.0. If you’re using await, migration will most likely be easier when the day comes.

There might be cases where you want to use .then() but for the cases where it doesn’t matter, consider using await.

1 Like

Oops. I recently rewrote a script using a lot of await to .then where possible.

Maybe I should restore the backup then…

Finally got around to migrating my Calendar to OmniFocus workflow to Scriptable:

1 Like

I am getting a parser error as to line 35 of this script. I realize the script is from almost 2 years ago; is there an update to correct this?

The script looks ok to me. The only thing that’s misting is

function handleEvents(events) {

as the very first line.

I’ve just uploaded my latest version, try that. I use this daily but often tweak the default projects/tags it uses and don’t always update with the changes.

I’m on the latest released version of scriptable by the way…

Thank you, @schl3ck, that fixed it!

1 Like