Skip to content

Instantly share code, notes, and snippets.

@zieglar
Forked from janlay/README.md
Created November 20, 2019 17:08
Show Gist options
  • Save zieglar/d7c3787d79fa42a3eb9385316642d68a to your computer and use it in GitHub Desktop.
Save zieglar/d7c3787d79fa42a3eb9385316642d68a to your computer and use it in GitHub Desktop.
delete-tweets

delete-tweets.sh

This util deletes your historical tweets from a downloaded archive file.

No guarantee, no support, use it at your own risk.

Preparations

  1. Apply to become a Twitter developer first. Once your Twitter developer account application is approved, You can create a new app and get its Consumer API keys and generate Access token. These keys are used to configure tweet.sh
  2. Obtain archived tweets by requesting to download your Twitter data. You can extract tweet.js file from the downloaded .zip file.
  3. Download tweet.sh from the forked repo. Configure it following its README. tweet.sh requires curl, jq, nkf, openssl.
  4. Download delete-tweets.sh from this gist. chmod +x delete-tweets.sh is recommended.
  5. Install GNU date by running brew install coreutils if you decide to run this util on macOS.

Usage

Run command in your terminal: delete-tweets.sh /path/to/tweet.js

Whenever you quit the task, or it crashes accidentally, run again and it should resume the task from last working entry.

Configuration

  • Change variable KEEP_DAYS to 365 in delete-tweets.sh, if you want to keep tweets posted within recent one year.
  • Delete the file declared by LAST_TWEET_FILE, if you want to start over.
#!/bin/bash
# author: janlay@gmail.com
set -e
KEEP_DAYS=90
LAST_TWEET_FILE="$HOME/.delete-tweets"
TWEET_UTIL="tweet.sh"
function delete_tweet {
# empty buffer before calling tweet.sh
echo -n '' | "$TWEET_UTIL" delete $1 2>&1 || true
}
function undo_retweet {
echo -n '' | "$TWEET_UTIL" unretweet $1 2>&1 || true
}
function raise_error {
echo "${1:-Error occurred.}" >&2
exit ${2:-1}
}
function main {
echo -n "Preparing... "
[ -f "$1" ] || raise_error "Missing archived tweets file: tweet.js."
[ -f "$TWEET_UTIL" ] || raise_error "tweet.sh is required." 2
local nickname="$("$TWEET_UTIL" whoami)"
[ "$nickname" == "null" ] && raise_error "tweet.sh is not configured correctly." 3
local date_cmd=date
if [ "$(uname)" == "Darwin" ]; then
which gdate > /dev/null || raise_error "gdate, the GNU date utility is required." 4
date_cmd=gdate
fi
echo Done.
local timestamp=$($date_cmd -d "$($date_cmd +%Y-%m-%d) -$(($KEEP_DAYS-1)) days" +%s)
echo "This utility will delete tweets for $nickname before $($date_cmd -d @$timestamp +%D)"
echo -n "Loading tweets from $1... "
local items="`(echo '[{'; tail -n +2 "$1") | jq -r 'map([.created_at, .id_str, (.full_text | startswith("RT @") | tostring)] | join(",")) | .[]'`"
local count=$(echo "$items" | wc -l | tr -d ' ')
echo "$count tweets."
local started=1
local last_deleted
if [ -f "$LAST_TWEET_FILE" ]; then
last_deleted=$(cat "$LAST_TWEET_FILE")
echo -n "Resuming... "
started=0
fi
local index=0
echo "$items" | while IFS=, read -r tweet_date tweet_id retweeted; do
index=$(($index + 1))
# resuming from last working entry
if [ $started -eq 0 ]; then
if [ "$tweet_id" == "$last_deleted" ]; then
echo Found.
started=1
fi
continue
fi
# print prograss and current entry
echo -n "[$(echo "scale = 2; $index * 100 / $count" | bc)%] "
[ "$retweeted" == "true" ] && echo -n "Unretweeting" || echo -n "Deleting"
echo -n " tweet $tweet_id posted on $($date_cmd -d "$tweet_date" +%D)... "
# compare dates
if [ $($date_cmd -d "$tweet_date" +%s) -ge $timestamp ]; then
printf "Kept.\e[0E\e[K\r"
continue
fi
# execute
RESULT="$(([ "$retweeted" == "true" ] && undo_retweet $tweet_id || delete_tweet $tweet_id) | jq -r '.errors | first | .message // empty')"
[ -z "$RESULT" ] && printf "OK.\e[0E\e[K\r" || echo "ERROR: $RESULT"
# save working entry
echo $tweet_id > "$LAST_TWEET_FILE"
done
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment