diff --git a/.github/workflows/fetch-x-feed.yml b/.github/workflows/fetch-x-feed.yml index e27aeb6a..5f457eca 100644 --- a/.github/workflows/fetch-x-feed.yml +++ b/.github/workflows/fetch-x-feed.yml @@ -26,36 +26,67 @@ jobs: env: X_BEARER_TOKEN: ${{ secrets.X_BEARER_TOKEN }} run: | - set -euo pipefail + set -u + + write_empty_feed() { + mkdir -p WebSite/assets + echo '[]' > WebSite/assets/x-feed.json + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add WebSite/assets/x-feed.json + git commit -m "Update x-feed.json (empty due to API error)" || echo "No changes to commit" + git push || echo "git push failed (push may be restricted)" + } + if [ -z "${X_BEARER_TOKEN:-}" ]; then echo "X_BEARER_TOKEN secret is not set. Exiting (no-op)." + write_empty_feed exit 0 fi + USERNAME="${{ github.event.inputs.username }}" if [ -z "$USERNAME" ]; then USERNAME="pankun2000_"; fi echo "Using username: $USERNAME" - AUTH_SCHEME="$(printf 'B%s%s' 'ea' 'rer')" - AUTH_HEADER="Authorization: ${AUTH_SCHEME} ${X_BEARER_TOKEN}" - USER_JSON=$(curl -sS -H "$AUTH_HEADER" "https://api.twitter.com/2/users/by/username/$USERNAME") - USER_ID=$(echo "$USER_JSON" | jq -r '.data.id // empty') - if [ -z "$USER_ID" ]; then echo "Could not resolve user id: $USER_JSON"; exit 1; fi - TWEETS_JSON=$(curl -sS -H "$AUTH_HEADER" "https://api.twitter.com/2/users/$USER_ID/tweets?max_results=100&expansions=attachments.media_keys&tweet.fields=created_at,text") + AUTH_HEADER="Authorization: Bearer ${X_BEARER_TOKEN}" + + USER_JSON=$(curl --silent --show-error --fail-with-body -H "$AUTH_HEADER" "https://api.twitter.com/2/users/by/username/$USERNAME" || true) + USER_ID=$(echo "$USER_JSON" | jq -r '.data.id // empty' 2>/dev/null || true) + if [ -z "$USER_ID" ]; then + echo "Could not resolve user id for ${USERNAME}. API response:" + echo "$USER_JSON" + echo "Writing empty feed and exiting successfully." + write_empty_feed + exit 0 + fi + + TWEETS_JSON=$(curl --silent --show-error --fail-with-body -H "$AUTH_HEADER" "https://api.twitter.com/2/users/$USER_ID/tweets?max_results=100&expansions=attachments.media_keys&tweet.fields=created_at,text" || true) + if ! echo "$TWEETS_JSON" | jq -e '.data != null' >/dev/null 2>&1; then + echo "Unable to fetch tweet list for ${USERNAME}; writing empty feed." + echo "$TWEETS_JSON" + write_empty_feed + exit 0 + fi + IDS=$(echo "$TWEETS_JSON" | jq -r '.data[]? | select(.attachments != null) | .id' || true) if [ -z "$IDS" ]; then IDS=$(echo "$TWEETS_JSON" | jq -r '.data[]? | select(.text | test("pic\\.twitter\\.com")) | .id' || true) fi + OUTPUT='[]' for id in $IDS; do URL="https://x.com/$USERNAME/status/$id" - OEMBED_JSON=$(curl -s "https://publish.twitter.com/oembed?url=$URL&dnt=true") - OEMBED_HTML=$(echo "$OEMBED_JSON" | jq -r '.html // empty') - OUTPUT=$(echo "$OUTPUT" | jq --arg url "$URL" --arg html "$OEMBED_HTML" '. + [ { url: $url, oembed_html: $html } ]') + OEMBED_JSON=$(curl --silent --show-error --max-time 20 "https://publish.twitter.com/oembed?url=$URL&dnt=true" || true) + OEMBED_HTML=$(echo "$OEMBED_JSON" | jq -r '.html // empty' 2>/dev/null || true) + if [ -n "$OEMBED_HTML" ]; then + OUTPUT=$(echo "$OUTPUT" | jq --arg url "$URL" --arg html "$OEMBED_HTML" '. + [ { url: $url, oembed_html: $html } ]') + fi done - OUTPUT=$(echo "$OUTPUT" | jq '.[0:3]') || OUTPUT='[]' + + OUTPUT=$(echo "$OUTPUT" | jq '.[0:3]' 2>/dev/null || echo '[]') mkdir -p WebSite/assets echo "$OUTPUT" > WebSite/assets/x-feed.json git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add WebSite/assets/x-feed.json git commit -m "Update x-feed.json (fetched media tweets)" || echo "No changes to commit" - git push + git push || echo "git push failed (push may be restricted)"