Created
November 10, 2023 20:39
-
-
Save YohannParis/5d47dda2deae8a14030b07aa6c13b877 to your computer and use it in GitHub Desktop.
Bash script to synchronize GitHub task to Things.app
This file contains 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
#!/bin/bash | |
# Script to sync GitHub tasks with Things locally | |
# Run this script with a cron job every hour on weekdays from 8 AM to 6 PM. | |
# Commands to make it happen: | |
# > brew install jq | |
# > chmod +x script.sh | |
# > crontab -e | |
# > 0 8-18 * * 1-5 /path/to/github_to_things.sh | |
# GitHub organization name and your GitHub username | |
github_org_name="your_github_organization" | |
github_username="your_github_userbane" | |
github_token="your_github_token" | |
# Things URL scheme | |
things_token="your_things_token" | |
things_area="your_things_area" | |
# File to store GitHub issue IDs and Things task IDs | |
data_file="./data.txt" | |
temp_file="./temporary.txt" | |
# Check if the data file exists, and create it if it doesn't | |
if [ ! -e "$data_file" ]; then | |
touch "$data_file" | |
fi | |
# Check if the temporary file exists, and create it if it doesn't | |
if [ ! -e "$temp_file" ]; then | |
touch "$temp_file" | |
fi | |
# Function to call x-callback-url and retrieve x-things-id | |
# Protocol: https://x-callback-url.com | |
# Tool: https://github.com/martinfinke/xcall | |
# Example: https://utf9k.net/questions/macos-invoke-x-callback-url/ | |
xcall() { | |
local json_response | |
json_response=$(/Applications/xcall.app/Contents/MacOS/xcall -url $1 -activateApp NO) | |
# Extract the value of "x-things-id" key from the JSON response | |
x_things_id=$(echo "$json_response" | jq --raw-output '.["x-things-id"]') | |
# Check if x-things-id is not empty | |
if [ -n "$x_things_id" ]; then | |
echo "$x_things_id" | |
else | |
echo "x-things-id not found in JSON response." | |
fi | |
} | |
# Function to save key-value pairs to a file | |
save_key_value() { | |
echo "$1=$2" >> "$data_file" | |
echo "Line with ID $1 saved with Things ID $2" | |
} | |
# Function to retrieve a value by key from the file | |
get_value_by_key() { | |
grep --extended-regexp "^$1=" "$data_file" | cut -d "=" -f 2 | |
} | |
# Function to remove a line from the data file based on an ID | |
remove_key_value() { | |
local id_to_remove="$1" | |
# Check if the line with the ID exists in the data file | |
if grep --quiet "^$id_to_remove=" "$data_file"; then | |
# Create a temporary file without the line to be removed | |
grep --invert-match "^$id_to_remove=" "$data_file" > "$temp_file" | |
# Overwrite the original data file with the updated content | |
mv "$temp_file" "$data_file" | |
echo "Line with ID $id_to_remove removed from the data file." | |
else | |
echo "Line with ID $id_to_remove not found in the data file." | |
fi | |
} | |
# Fetch GitHub issues assigned to you | |
issues=$(curl --silent --header "Authorization: token $github_token" \ | |
"https://api.github.com/orgs/$github_org_name/issues?assignee=$github_username&state=all&per_page=100") | |
# Loop through the issues and create/update tasks in Things | |
for row in $(echo "$issues" | jq --raw-output '.[] | @base64'); do | |
# Decode each line, then make sure it is URI encoded | |
_jq() { | |
echo "$row" | base64 --decode | jq --raw-output "$1" | |
} | |
issue_id=$(_jq '.id') | |
issue_title=$(_jq '.title') | |
issue_title_encoded=$(jq --slurp --raw-input --raw-output @uri <<< $issue_title) | |
issue_state=$(_jq '.state') | |
issue_url=$(jq --slurp --raw-input --raw-output @uri <<< $(_jq '.html_url')) | |
issue_created_at=$(_jq '.created_at') | |
echo "--" | |
echo "Issue ($issue_state) - $issue_title" | |
# Retrieve Things task ID for this GitHub issue (if it exists) | |
things_task_id=$(get_value_by_key "$issue_id") | |
# Depending on the GitHub issue state, create or update tasks in Things | |
if [ "$issue_state" = "open" ]; then | |
# Create a new task and save the Things task ID | |
if [ -z "$things_task_id" ]; then | |
url="things:///add?auth-token=$things_token&list=$things_area&title=$issue_title_encoded¬es=$issue_url&tags=GitHub&creation-date=$issue_created_at" | |
things_task_id=$(xcall $url) | |
save_key_value "$issue_id" "$things_task_id" | |
else | |
# Update the existing task | |
xcall "things:///update?auth-token=$things_token&id=$things_task_id" | |
fi | |
elif [ "$issue_state" = "closed" ]; then | |
# Close the task if the GitHub issue is closed | |
if [ -n "$things_task_id" ]; then | |
xcall "things:///update?auth-token=$things_token&id=$things_task_id&completed=true" | |
remove_key_value "$things_task_id" | |
fi | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment