Skip to content

Instantly share code, notes, and snippets.

@tyjak
Last active March 24, 2024 14:43
Show Gist options
  • Save tyjak/c7afb4800057b0e27d7100d1b82fe902 to your computer and use it in GitHub Desktop.
Save tyjak/c7afb4800057b0e27d7100d1b82fe902 to your computer and use it in GitHub Desktop.
#!/bin/bash
# This script serves as a Taskwarrior hook, automating the generation and
# sending of iCal events via email when tasks with specific criteria are
# modified or created. It extracts task details, such as title, due date, and
# annotations, then constructs an iCal event and sends it as an email
# attachment using Mutt. Optionally, it can append event details to a specified
# file. The script enhances Taskwarrior's functionality by seamlessly
# integrating task management with calendar events, streamlining task tracking
# and scheduling processes.
#
# GistID: c7afb4800057b0e27d7100d1b82fe902
# Define the default recipient email using an environment variable
DEFAULT_RECIPIENT_EMAIL_ICS="$EMAIL"
# Define the default path for the Mutt configuration file
MUTT_CONFIG_FILE_PATH="$MUTT_CONF"
# Function to send email with iCal attachment
send_email_with_ics() {
local event_title=$1
local event_date=$2
local event_description=$3
local recipient_email=$4
# Define time zone information
local time_zone="Europe/Berlin" # Modify according to your time zone
# Create VTIMEZONE component
local vtimezone=$(echo "BEGIN:VTIMEZONE
TZID=$time_zone
LAST-MODIFIED:20231222T233358Z
TZURL:https://www.tzurl.org/zoneinfo-outlook/Europe/Berlin
X-LIC-LOCATION:Europe/Berlin
BEGIN:DAYLIGHT
TZNAME:CEST
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
BEGIN:STANDARD
TZNAME:CET
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
END:VTIMEZONE")
# Create iCal entry
local cal=$(echo "BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//ical.tyjak.net/Timewarrior event generator
CALSCALE:GREGORIAN
$vtimezone
BEGIN:VEVENT
DTSTAMP:$(date +"%Y%m%dT%H%M%SZ")
UID:$(date +"%Y%m%d%H%M%S")-$(echo "$event_title" | md5sum | cut -d ' ' -f 1)@ical.tyjak.net
DTSTART;TZID=$time_zone:$event_date
DTEND;TZID=$time_zone:$event_date
SUMMARY:$event_title
DESCRIPTION:$description
END:VEVENT
END:VCALENDAR")
# Create temporary file to store .ics content
local ics_file=$(mktemp /tmp/task_event.XXXXXX.ics)
echo "$cal" > "$ics_file"
# Send email using Mutt
/usr/bin/mutt -e "source $MUTT_CONFIG_FILE_PATH" -s "$event_title" -a "$ics_file" -- "$recipient_email" < <(echo "Please find the event attached.")
rm "$ics_file"
}
# Get JSON task data from input
json_task_data=$(cat)
echo "$(date +'%Y-%m-%d %H:%M:%S') - $json_task_data" >> /tmp/tw_hook.error.log
# Check if JSON task data is empty
if [ -z "$json_task_data" ]; then
echo "Error: No JSON task data received." >&2
exit 1
fi
# Extract task details from JSON data
task_id=$(echo "$json_task_data" | jq -r '.id')
task_description=$(echo "$json_task_data" | jq -r '.description')
task_tags=$(echo "$json_task_data" | jq -r '.tags | @tsv')
task_due=$(echo "$json_task_data" | jq -r '.due')
# The active selection is the description
description=$(xclip -o -selection primary | sed ':a;N;$!ba;s/\n/\\n/g')
# Check if the task has the "cal" tag and a due date
if [[ "$task_tags" =~ "cal" && -n "$task_due" ]]; then
# Extract event title
event_title="$task_description"
# Use task due date as event date
event_date="$task_due"
# Send email with iCal attachment
send_email_with_ics "$event_title" "$event_date" "$description" "$DEFAULT_RECIPIENT_EMAIL_ICS"
# Check if PALCAL environment variable is set and not empty
if [[ -n "${PALCAL}" ]]; then
# Format event date as 'YYYYMMDD'
formatted_event_date=$(date -d "${event_date::-5}" +'%Y%m%d')
# Construct line to append
line_to_append="${formatted_event_date} ${event_title}"
# Append line to file specified by PALCAL environment variable
echo "$line_to_append" >> "${PALCAL}"
fi
# Output the JSON task data
echo "$json_task_data"
else
# No changes, output original JSON task data
echo "$json_task_data"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment