Last active
April 2, 2020 22:46
-
-
Save hepcat72/476652c48547cae0972f157bac35f50a to your computer and use it in GitHub Desktop.
Applescript to post webhooks triggered by newly completed iOS reminders in specific list(s)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--Look for newly completed reminders (since the last check) and if there is a new one, make a webhook post with date, title, and list JSON values | |
--by Robert W. Leach, based on scripts by Craig Eley, Samantha Hilton, and Nick Morris | |
--This is not foolproof. If you have more than 1 device you use to "complete" reminders and a reminder is completed while offline, after which, a reminder is completed from a second online device, the completion of the reminders in the offline device (once it comes online) will be missed. However, it's done this way so that the script doesn't take forever looking at all reminders each time. | |
--Schedule it to run as frequently as you would like using osascript in a cron job and forget about it. Run once manually in order to "allow" this script to run in the security settings by responding to the resulting dialog. | |
--Cron job every 30 minutes looking for newly completed reminders in list "MyReminders" example (execute `crontab -e` in terminal and enter): */30 * * * * osascript /Users/username/Scripts/completion_notifier.scpt "/Users/username/reminder_completions.txt" "http://maker.ifttt.com/trigger/myeventname/with/key/mykeyfromiftttmaker" -1 "MyReminders" | |
--Run without command line arguments to get the usage | |
--Command line argument examples: | |
-- "~/completed_reminders.txt" --No spaces allowed in file path. File does not need to pre-exist (but directories do). | |
-- "http://maker.ifttt.com/trigger/{event}/with/key/{key}" --Empty = don't make a webhook call (for testing) | |
-- -1 --Priority level cutoff. -1 = all. 1 = !, 2 = !!, 3 = !!!. Considers only reminders with priority greater than this value. | |
-- "ToDo" --Empty = all. Example: "Grocery" "ToDo" "Work" "Home" - only provided lists are checked for newly completed items | |
on run argv | |
set debug to false | |
if (count of argv) is less than 3 then | |
return "Usage: osascript completion_notifier.scpt \"/path/to/outfile.txt\" \"http://webhook_url\" priority_level [reminder list names...]" & linefeed & "Example: osascript completion_notifier.scpt \"/Users/jsmith/completed_reminders.txt\" \"http://test.com/webhook\" -1" | |
end if | |
set lastcompletionfile to item 1 of argv | |
set webhookurl to item 2 of argv | |
set prilev to item 3 of argv | |
set liststocheck to {} | |
if (count of argv) is equal to 4 then | |
set liststocheck to {item 4 of argv} | |
else if (count of argv) is greater than 3 then | |
set liststocheck to {items 4 thru (count of argv) of argv} | |
end if | |
tell application "Reminders" | |
set {startdate, firsttime} to my getStart(lastcompletionfile) | |
if debug is true then | |
display dialog "Starting datetime: " & startdate as text | |
end if | |
set output to "" | |
set lastcompletion to startdate | |
set mostrecentdate to "" | |
set mostrecenttitle to "" | |
set mostrecentlist to "" | |
--Find entries completed today from each list | |
set hasOne to false | |
repeat with alist in every list | |
set mylist to name of alist as text | |
if (count of liststocheck) is 0 or liststocheck contains mylist then | |
--set listid to id of alist as text | |
if debug is true then | |
--display dialog mylist & linefeed & listid | |
display dialog mylist | |
end if | |
repeat with reminderObj in (reminders in alist whose (completed is true) and (completion date is greater than startdate) and (priority is greater than prilev)) | |
set nameObj to name of reminderObj | |
set compDateObj to completion date of reminderObj | |
set timeStr to date string of compDateObj & " at " & time string of compDateObj | |
--set idObj to id of reminderObj | |
if compDateObj is greater than lastcompletion then | |
set hasOne to true | |
set lastcompletion to compDateObj | |
set mostrecentdate to timeStr | |
set mostrecenttitle to nameObj | |
set mostrecentlist to mylist | |
end if | |
if debug is true then | |
display dialog idObj & tab & timeStr & tab & nameObj | |
end if | |
--set output to output & listid & tab & idObj & tab & timeStr & tab & mylist & tab & nameObj & linefeed | |
set output to output & timeStr & tab & mylist & tab & nameObj & linefeed | |
if debug is true then | |
--display dialog listid & tab & idObj & tab & timeStr & tab & mylist & tab & nameObj | |
display dialog timeStr & tab & mylist & tab & nameObj | |
end if | |
end repeat | |
end if | |
end repeat | |
if hasOne is true then | |
--save the newly completed items found this time so that next time, we can look for newer items | |
set shellTxt to "echo \"" & output & "\" > " & lastcompletionfile | |
if debug is true then | |
display dialog shellTxt | |
end if | |
do shell script shellTxt | |
--Make the webhook call (if the webhookurl is not an empty string) | |
if webhookurl is not "" then | |
--Use this example to send json data | |
--set shellScript to "curl -X POST --data-urlencode 'payload={\"channel\": \"#general\", \"username\": \"Completion Notifier Bot\", \"icon_emoji\": \":ghost:\"}' " & webhookurl | |
set jsonoption to "--data-urlencode 'payload={\"value1\": \"" & mostrecentdate & "\", \"value2\": \"" & mostrecenttitle & "\", \"value3\": \"" & mostrecentlist & "\"}'" | |
set shellTxt to "curl -X POST " & jsonoption & " \"" & webhookurl & "\" > /dev/null" | |
if debug is true then | |
display dialog shellTxt | |
end if | |
do shell script shellTxt | |
end if | |
else | |
--Save the date this was run so it can be parsed later the next time it's run | |
if firsttime is true then | |
set shellTxt to "echo \"" & startdate & tab & "initial run" & tab & "no completed reminders" & linefeed & "\" > " & lastcompletionfile | |
if debug is true then | |
display dialog shellTxt | |
end if | |
do shell script shellTxt | |
end if | |
if debug is true then | |
display dialog "Nothing is newly completed" | |
end if | |
end if | |
end tell | |
end run | |
--Takes the file containing the last determined most recent completion date (since the last time this script ran). | |
--Returns from the file, the most recent reminder completion date and a boolean indicating whether write an initial start record into the file | |
on getStart(lastcompletionfile) | |
set startdate to the current date | |
set checkscript to "if [ -e \"`eval echo " & lastcompletionfile & "`\" ]; then echo yes; else echo no; fi" | |
--display dialog checkscript | |
set fileisthere to first paragraph of (do shell script checkscript) | |
--display dialog lastcompletionfile & " exists? [" & fileisthere & "]" | |
set gotone to false | |
if fileisthere is equal to "yes" then | |
set lastdate to missing value | |
set datescript to "cut -f 3 " & "\"`eval echo " & lastcompletionfile & "`\"" | |
--display dialog datescript | |
set datelines to paragraphs of (do shell script "cut -f 1 " & "\"`eval echo " & lastcompletionfile & "`\"") | |
repeat with adateline in datelines | |
--display dialog "Checking [" & adateline & "]" | |
try | |
set tmpdate to date adateline | |
if lastdate is missing value or tmpdate is greater than lastdate then | |
set lastdate to tmpdate | |
set gotone to true | |
--display dialog "Later: " & lastdate as text | |
end if | |
end try | |
end repeat | |
if gotone is true then | |
--display dialog "Setting start date: " & lastdate as text | |
set startdate to lastdate | |
end if | |
end if | |
--display dialog "Returning start date: " & startdate as text | |
return {startdate, not gotone} | |
end getStart |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment