Skip to content

Commit

Permalink
Add shell utility scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
joelpurra committed May 10, 2018
1 parent 774e2a8 commit 82589ac
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 0 deletions.
27 changes: 27 additions & 0 deletions utilities/shell/README.md
@@ -0,0 +1,27 @@
# Twitch shell utilities

- Simple shell utilities, needed one time or another during testing and development.
- Not all steps are automated — some require very manual copy-paste.
- See the main readme file for setting up Twitch application environment variables.
- See individual files for documentation, but don't expect too much.
- A part of [botten-nappet](https://joelpurra.com/projects/botten-nappet/).


```shell
tree ./utilities/shell/
```

```text
./utilities/shell/
├── README.md
├── download-all-channel-feed-posts.sh
└── manual-authentication-steps.sh
0 directories, 3 files
```



---

[botten-nappet](https://joelpurra.com/projects/botten-nappet/) Copyright © 2018 [Joel Purra](https://joelpurra.com/). Released under [GNU Affero General Public License version 3.0 (AGPL-3.0)](https://www.gnu.org/licenses/agpl.html). [Your donations are appreciated!](https://joelpurra.com/donate/)
85 changes: 85 additions & 0 deletions utilities/shell/download-all-channel-feed-posts.sh
@@ -0,0 +1,85 @@
#!/usr/bin/env bash

set -e
set -u
set -o pipefail

# ---
#
# Download all Twitch channel feed posts.
#
# Used as a backup tool for when Twitch kills off the channel feed.
# This script might not be useful after that, circa June 2018.
# https://help.twitch.tv/customer/portal/articles/2936769-removing-channel-feed-and-pulse
#
# Outputs a json file with all posts and post details in an array.
#
# NOTE: does not get each post's comments.
#
# NOTE: requires Twitch authorization environment variables to have been set up.
#
# ---

function die() {
echo -E "FATAL" "$@" >&2
exit 1
}

function fetchCurrentPage() {
curl \
--silent \
--header 'Accept: application/vnd.twitchtv.v5+json' \
--header "Client-ID: ${TWITCH_APP_CLIENT_ID}" \
--header "Authorization: OAuth ${TWITCH_APP_ACCESS_TOKEN}" \
"https://api.twitch.tv/kraken/feed/${TWITCH_USER_ID}/posts?limit=100&cursor=${TWITCH_CHANNEL_FEED_POSTS_CURSOR}"
}

function downloadCurrentPage() {
# TODO: use local variables.
declare TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT="${TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT_PREFIX}${TWITCH_CHANNEL_FEED_POSTS_OFFSET}${TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT_SUFFIX}"
fetchCurrentPage > "$TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT"

# TODO: use local variables.
TWITCH_CHANNEL_FEED_POSTS_CURSOR="$(cat "$TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT" | jq --raw-output '._cursor')"
TWITCH_CHANNEL_FEED_POSTS_COUNT="$(cat "$TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT" | jq --raw-output '.posts | length')"
TWITCH_CHANNEL_FEED_POSTS_OFFSET="$(( "$TWITCH_CHANNEL_FEED_POSTS_OFFSET" + "$TWITCH_CHANNEL_FEED_POSTS_COUNT" ))"

# echo "TWITCH_CHANNEL_FEED_POSTS_CURSOR" "$TWITCH_CHANNEL_FEED_POSTS_CURSOR"
# echo "TWITCH_CHANNEL_FEED_POSTS_COUNT" "$TWITCH_CHANNEL_FEED_POSTS_COUNT"
# echo "TWITCH_CHANNEL_FEED_POSTS_OFFSET" "$TWITCH_CHANNEL_FEED_POSTS_OFFSET"
}

function main() {
# Step 0: check input.
[[ -z "$TWITCH_USER_ID" ]] && die "Environment variable not set" "TWITCH_USER_ID"
[[ -z "$TWITCH_APP_CLIENT_ID" ]] && die "Environment variable not set" "TWITCH_APP_CLIENT_ID"
[[ -z "$TWITCH_APP_ACCESS_TOKEN" ]] && die "Environment variable not set" "TWITCH_APP_ACCESS_TOKEN"

# Step 1: setup.
# TODO: use local variables.
declare TWITCH_CHANNEL_FEED_POSTS_TIMESTAMP="$(date -u +%FT%TZ | tr -d ':')"
declare TWITCH_CHANNEL_FEED_POSTS_COUNT="0"
declare TWITCH_CHANNEL_FEED_POSTS_OFFSET="0"
declare TWITCH_CHANNEL_FEED_POSTS_CURSOR=""
declare TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT_PREFIX="twitch.channel-feed.posts.${TWITCH_USER_ID}.${TWITCH_CHANNEL_FEED_POSTS_TIMESTAMP}."
declare TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT_SUFFIX=".json"
declare TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT_LIST="${TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT_PREFIX}*${TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT_SUFFIX}"
declare TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT_ALL="${TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT_PREFIX}all${TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT_SUFFIX}"

# Step 2: run once.
downloadCurrentPage

# Step 3: loop.
while [[ ! -z "$TWITCH_CHANNEL_FEED_POSTS_CURSOR" ]];
do
downloadCurrentPage
done

# Step 3: concatenate.
cat $TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT_LIST | jq --slurp 'map(.posts) | add | sort_by(.created_at)' > "$TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT_ALL"

# Done!
cat "$TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT_ALL" | jq --arg path "$TWITCH_CHANNEL_FEED_POSTS_PAGE_OUTPUT_ALL" '{ path: $path, count: length, first: .[0].created_at, last: .[-1].created_at }'
}

main
74 changes: 74 additions & 0 deletions utilities/shell/manual-authentication-steps.sh
@@ -0,0 +1,74 @@
echo "Do not execute this file directly; instead copy-paste examples as needed." >&2
exit 1

# NOTE: requires Twitch application environment variables to be set.
# See "Prepare variables" in the main readme file.


# ---


# Get an application access token.
# Required: TWITCH_APP_CLIENT_ID
# Required: TWITCH_APP_CLIENT_SECRET
export TWITCH_APP_ACCESS_TOKEN="$(curl --data "client_id=${TWITCH_APP_CLIENT_ID}&client_secret=${TWITCH_APP_CLIENT_SECRET}&grant_type=client_credentials&scope=channel_feed_read" 'https://api.twitch.tv/kraken/oauth2/token' | jq --raw-output '.access_token')"

# Optional: Revoke an application access token.
# Required: TWITCH_APP_CLIENT_ID
# Required: TWITCH_APP_ACCESS_TOKEN
curl --data "client_id=${TWITCH_APP_CLIENT_ID}&token=${TWITCH_APP_ACCESS_TOKEN}" 'https://api.twitch.tv/kraken/oauth2/revoke'


# ---


# Sample application access token usage for different Twitch APIs.
# Required:
curl --header "Authorization: Bearer ${TWITCH_APP_ACCESS_TOKEN}" 'https://api.twitch.tv/helix/'

curl --header "Authorization: OAuth ${TWITCH_APP_ACCESS_TOKEN}" 'https://api.twitch.tv/kraken/'

curl --header "Authorization: Bearer ${TWITCH_APP_ACCESS_TOKEN}" 'https://api.twitch.tv/helix/webhooks/hub'


# ---


# Get the user id from user name.
# Required: TWITCH_APP_ACCESS_TOKEN
# Required: TWITCH_USER_NAME
export TWITCH_USER_ID="$(curl --header "Authorization: Bearer ${TWITCH_APP_ACCESS_TOKEN}" "https://api.twitch.tv/helix/users?login=${TWITCH_USER_NAME}" | jq --raw-output '.data[0].id')";


# ---


# Authorize a user in your application.
# Required: TWITCH_APP_CLIENT_ID
# Required: TWITCH_APP_CLIENT_SECRET
# Required: TWITCH_APP_OAUTH_REDIRECT_URL
# Required:
# Step 1: setup.
export CSRF_STATE="$(echo "unguessable $(date) even more unguessable" | shasum --algorithm 512 | cut -d ' ' -f 1)"
function urlencode() { python -c "import sys, urllib as ul; print ul.quote_plus(sys.argv[1]);"; }
export TWITCH_APP_OAUTH_REDIRECT_URL_URLENCODED="$(urlencode "$TWITCH_APP_OAUTH_REDIRECT_URL")"

# Step 2: open up the browser for application authorization.
open "https://api.twitch.tv/kraken/oauth2/authorize?client_id=${TWITCH_APP_CLIENT_ID}&redirect_uri=${TWITCH_APP_OAUTH_REDIRECT_URL_URLENCODED}&response_type=code&scope=channel_feed_read%20channel_subscriptions%20chat_login&force_verify=true&state=${CSRF_STATE}"

# Step 3: copy the url after the user has been redirected, then execute this line.
export TWITCH_USER_AUTHORIZATION_CODE="$(pbpaste | sed -E -e 's/.*\bcode=([a-zA-Z0-9]*)\b.*/\1/')"

# Step 4: retrieve the actual user access token.
# NOTE: This can be stored and reused long-term.
export TWITCH_USER_ACCESS_TOKEN="$(curl --data "client_id=${TWITCH_APP_CLIENT_ID}&client_secret=${TWITCH_APP_CLIENT_SECRET}&code=${TWITCH_USER_AUTHORIZATION_CODE}&grant_type=authorization_code&redirect_uri=${TWITCH_APP_OAUTH_REDIRECT_URL_URLENCODED}" 'https://api.twitch.tv/kraken/oauth2/token' | jq --raw-output '.access_token')"

# Optional: test the access by requesting used details.
# Required: user_read scope.
curl --header "Authorization: OAuth ${TWITCH_USER_ACCESS_TOKEN}" 'https://api.twitch.tv/kraken/user'

# Optional: revoke the user access token.
curl --data "client_id=${TWITCH_APP_CLIENT_ID}&token=${TWITCH_USER_ACCESS_TOKEN}" 'https://api.twitch.tv/kraken/oauth2/revoke'


# ---

0 comments on commit 82589ac

Please sign in to comment.