Skip to content

Instantly share code, notes, and snippets.

@notwa
Created June 5, 2020 22:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save notwa/53b06f2d5dce23df4c0ec9fd41c3e3f1 to your computer and use it in GitHub Desktop.
Save notwa/53b06f2d5dce23df4c0ec9fd41c3e3f1 to your computer and use it in GitHub Desktop.
#!/usr/bin/env zsh
set -e
# private user stuff:
read -r oauth < ~/.twitch_oauth
# public api stuff:
api='https://gql.twitch.tv/gql'
ChannelFollowsHash='fd9d5312a69d3c50cd2a8d6a1caadc824df410c249b78d330d7f469d22151933'
ClipsCardsUserHash='b73ad2bfaecfd30a9e6c28fada15bd97032c83ec77a0440766a56fe0bd632777'
# doing the dirty work:
json2() {
python3 ~/src/json2/json2 "$@"
}
# a simple interface:
mode=${1:?no timeframe specified}
shift
if [ "$mode" = "day" ]; then
period="LAST_DAY"
clip_limit=3
ntop=12
elif [ "$mode" = "week" ]; then
period="LAST_WEEK"
clip_limit=3
ntop=18
elif [ "$mode" = "month" ]; then
period="LAST_MONTH"
clip_limit=5
ntop=90
else
echo "invalid timeframe specified" >&2
exit 1
fi
who_i_follow_raw() {
limit=100
if [ "${1:-}" != "" ]; then
cursor="$1"
variables='{"cursor":"'"$cursor"'","limit":'"$limit"',"order":"DESC"}'
else
variables='{"limit":'"$limit"',"order":"DESC"}'
fi
curl -sS 'https://gql.twitch.tv/gql' \
-H "Authorization: OAuth $oauth" \
--data-binary '[{"operationName":"ChannelFollows","variables":'"$variables"',"extensions":{"persistedQuery":{"version":1,"sha256Hash":"'"$ChannelFollowsHash"'"}}}]'
}
process_follows() {
# formely used displayName but now uses login to support non-ascii names.
json2 \
| tr '\r' '\n' \
| sort -u \
| grep -P '^/0/data/user/follows/edges/\d+/(node/login|cursor)=.*$' \
| cut -d'=' -f 2 \
| paste -d" " - -
}
who_i_follow() {
local last_cursor= current_cursor=
for i in {1..100}; do
current_cursor="$last_cursor"
last_cursor=
who_i_follow_raw "$current_cursor" \
| process_follows \
| while read -r cursor name; do
echo "$name"
last_cursor="$cursor"
done
[ -n "$last_cursor" ] || break
last_cursor="${last_cursor:1}" # strip the leading double-quote
done
}
user_clips_raw() {
user="${1:?please specify a username}"
limit="$clip_limit"
# filter can be one of: LAST_DAY LAST_WEEK LAST_MONTH ALL_TIME
curl -sS 'https://gql.twitch.tv/gql' \
-H "Authorization: OAuth $oauth" \
--data-binary '[{"operationName":"ClipsCards__User","variables":{"login":"'"$user"'","limit":'"$limit"',"criteria":{"filter":"'"$period"'"}},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"'"$ClipsCardsUserHash"'"}}}]'
}
process_clips() {
json2 \
| awk -F'=' '
$1~/\/slug$/{name=$2}
$1~/\/viewCount$/{printf "%s\thttps://clips.twitch.tv/%s\n",$2,name}
'
}
user_clips() {
user="${1:?please specify a username}"
user_clips_raw "$user" \
| process_clips
}
(
who_i_follow \
| while read -r user; do
user_clips "$user"
done
) \
| sort -n
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment