Last active 1745770076

Delete ALL unused Todoist labels in one go

Revision 49255c7cc1a98cc7e12dd7fcb81fd231d6394560

del_all_unused_labels.sh Raw
1#!/usr/bin/bash
2set -euo pipefail
3
4TMP_JSON_FILE=/tmp/todoist.json.tmp
5TMP_ALL_LABELS_FILE=/tmp/all.labels.tmp
6TMP_USED_LABELS_FILE=/tmp/used.labels.tmp
7TMP_UNUSED_LABELS_FILE=/tmp/unused.labels.tmp
8TMP_UNUSED_LABEL_IDS_FILE=/tmp/unused.label.ids.tmp
9
10
11if [[ -z "${TODOIST_TOKEN:-}" ]]; then
12 echo "Error: set TODOIST_TOKEN to your Todoist API token" >&2
13 exit 1
14fi
15
16curl https://api.todoist.com/api/v1/sync \
17 -H "Authorization: Bearer $TODOIST_TOKEN" \
18 -d sync_token='*' \
19 -d resource_types='["items", "labels"]' \
20 > $TMP_JSON_FILE
21
22cat $TMP_JSON_FILE \
23 | jq -r '.labels[].name' \
24 | sort \
25 > $TMP_ALL_LABELS_FILE
26
27cat $TMP_JSON_FILE \
28 | jq -r '.items[].labels[]' \
29 | uniq \
30 | sort \
31 > $TMP_USED_LABELS_FILE
32
33comm -3 $TMP_ALL_LABELS_FILE $TMP_USED_LABELS_FILE > $TMP_UNUSED_LABELS_FILE
34
35while IFS= read -r name; do
36 jq -r --arg name "$name" '.labels[] | select(.name == $name) | .id' $TMP_JSON_FILE
37done < $TMP_UNUSED_LABELS_FILE > $TMP_UNUSED_LABEL_IDS_FILE
38
39while IFS= read -r id; do
40 if [ -z "$id" ]; then
41 continue
42 fi
43 echo "Processing ID: $id"
44 curl https://api.todoist.com/api/v1/sync \
45 -H "Authorization: Bearer $TODOIST_TOKEN" \
46 -d commands='[
47 {
48 "type": "label_delete",
49 "uuid": "'"$(uuidgen)"'",
50 "args": {
51 "id": "'"$id"'",
52 "cascade": "none"
53 }
54 }]'
55done < $TMP_UNUSED_LABEL_IDS_FILE
56
57rm $TMP_JSON_FILE
58rm $TMP_ALL_LABELS_FILE
59rm $TMP_USED_LABELS_FILE
60rm $TMP_UNUSED_LABELS_FILE
61rm $TMP_UNUSED_LABEL_IDS_FILE
62