Every time I look over at the channels I'm subscribed to in YouTube I have this internal discussion:
- My gosh, how did that list of subscriptions get so big? I sure wish I had a way to trim it down without going through the tedious process of manually unusbscribing.
- I know, I'll write a command line script to manage my YouTube subscriptions!
- But that will take time ... let me just muscle through and manually unsubscribe from channels I don't want to follow any longer.
- (Goes through the process of unsubscribing from two channels)
- Ugh! This is painful. I give up.
- And repeat...
Today, however, I finally broke the cycle! I decided to write a tool that will let me list and delete subscriptions from the command line. This wasn't really a stretch, I've written code that works with the Blogger Data API, so I figured working with the YouTube Data API wouldn't be any more difficult.
Step 1, I created a small command line utility to grant me OAuth access to my YouTube account:
#!/bin/bash ## ## Authenticate with YouTube Data API ## USAGE="`basename $0` {auth|refresh|token} ctx" CTX_DIR=$HOME/.youtube_auth CLIENT_ID=703261074341-e1vpmqq8kh2v9ke0mveve7dakpbobkft.apps.googleusercontent.com CLIENT_SECRET=uRhAcxywxYZF2bhbx7zVqeML ctx=default function usage { echo "Usage: `basename $0` [-h] [-c context] {init|token}" exit } function age { modified=`stat -c %X $1` now=`date +%s` expr $now - $modified } function refresh { refresh_token=`cat $CTX_DIR/$ctx.refresh_token` curl -si \ -d client_id=$CLIENT_ID \ -d client_secret=$CLIENT_SECRET \ -d refresh_token=$refresh_token \ -d grant_type=refresh_token \ https://accounts.google.com/o/oauth2/token > $CTX_DIR/$ctx.refresh grep access_token $CTX_DIR/$ctx.refresh | sed -e 's/.*: "//' -e 's/",//' > $CTX_DIR/$ctx.access_token } while getopts :hc: opt ; do case $opt in c) ctx=$OPTARG ;; h) usage ;; esac done shift $(($OPTIND - 1)) cmd=$1 ; shift mkdir -p $CTX_DIR case $cmd in init) url=`curl -gsi \ -d scope=https://www.googleapis.com/auth/youtube \ -d redirect_uri=urn:ietf:wg:oauth:2.0:oob \ -d response_type=code \ -d access_type=offline \ -d client_id=$CLIENT_ID \ https://accounts.google.com/o/oauth2/v2/auth | \ grep -i Location: | \ sed 's/[lL]ocation: //'` echo $url echo -n "Code? " read code curl -s \ -d client_id=$CLIENT_ID \ -d client_secret=$CLIENT_SECRET \ -d code=$code \ -d grant_type=authorization_code \ -d redirect_uri=urn:ietf:wg:oauth:2.0:oob \ https://www.googleapis.com/oauth2/v4/token > $CTX_DIR/$ctx.init grep access_token $CTX_DIR/$ctx.init | sed -e 's/.*: "//' -e 's/",//' > $CTX_DIR/$ctx.access_token grep refresh_token $CTX_DIR/$ctx.init | sed -e 's/.*: "//' -e 's/"//' > $CTX_DIR/$ctx.refresh_token echo "Done" ;; token) if [ ! -f $CTX_DIR/$ctx.access_token ] ; then echo "Unknown context: $ctx. Try initing first." exit fi age=`age $CTX_DIR/$ctx.access_token` if [ $age -gt 3600 ] ; then refresh fi cat $CTX_DIR/$ctx.access_token ;; *) usage esac
Surprisingly, I needed to use different API end points than I used for other curl based Google OAuth apps. I needed to generate the authentication code at https://accounts.google.com/o/oauth2/v2/auth and generate the auth token at https://www.googleapis.com/oauth2/v4/token.
Once I had an authentication token, life was good. I used the usual suspects to power this script. Mainly, curl to make the appropriate web requests and jq to format the resulting JSON in an intelligent way. You'll notice from the script below that if you pass -v to the script, you get the complete JSON output. Man those tools are awesome; if you don't know them well you're missing out.
Here's a sample run of my shiny new script:
$ youtube_tools -a subscriptions|grep -i megan ffVDX-wHSD6NaM3-kGgVug8jUOQIbwozBmWubSPnjtU:Megan Davies # Nothing personal Megan, but we're breaking up: $ youtube_tools -a subscription-delete \ -i `youtube_tools -a subscriptions |grep Megan | cut -d ':' -f 1`
Now that's how you manage YouTube subscriptions!
I'm not quite sure what else I'm going to do with this tool, but given how much I use YouTube for, I won't be surprised if I add to it.
Here's the code for the script, enjoy!
#!/bin/bash ## ## command line tools for working with YouTube. ## See: https://developers.google.com/youtube/v3/docs/ ## API_BASE=https://www.googleapis.com/youtube/v3 AUTH_TOKEN=`youtube_auth token` if [ -z "$AUTH_TOKEN" ] ; then echo "`basename $0`: authentication not setup. Run: 'youtube_auth init'" exit 1 fi function usage { echo "Usage: `basename $0` -a {subscriptions|subscription-delete} [-i ID] -v" exit } function filter { if [ -z "$VERBOSE" ] ; then jq "$@" else cat fi } while getopts ":a:i:v" opt ; do case $opt in a) ACTION=$OPTARG ;; v) VERBOSE=yes ;; i) ID=$OPTARG ;; \?) usage ;; esac done function invoke { curl -s -H "Authorization: Bearer $AUTH_TOKEN" "$@" } case $ACTION in subscriptions) invoke -G $API_BASE/subscriptions \ -d mine=true \ -d part=snippet \ -d maxResults=50 | filter -r ' .items[] | .id + ":" + .snippet.title' ;; subscription-delete) if [ -z "$ID" ] ; then echo "Deleting a subscription requires an ID (-i) value" usage fi invoke -X DELETE "$API_BASE/subscriptions?id=$ID" ;; *) usage ;; esac
No comments:
Post a Comment