Created
June 5, 2020 22:47
-
-
Save notwa/53b06f2d5dce23df4c0ec9fd41c3e3f1 to your computer and use it in GitHub Desktop.
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
#!/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