ScoutBot — Weekly Sunday Digest #11
This file contains hidden or 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
| name: ScoutBot — Weekly Sunday Digest | |
| # Every Sunday at 10:00 WAT (09:00 UTC): | |
| # 1. Sends the apology/update announcement (so latecomers who missed it get it) | |
| # 2. Sends the weekly opportunity digest (last 7 days only) | |
| # | |
| # The announcement email is idempotent in tone — receiving it twice is fine. | |
| # Can also be triggered manually from the GitHub Actions tab. | |
| on: | |
| schedule: | |
| - cron: '0 9 * * 0' # 10:00 WAT every Sunday | |
| workflow_dispatch: | |
| jobs: | |
| digest: | |
| runs-on: ubuntu-latest | |
| # 518 subscribers ÷ 30 per batch × 6-min pause × 2 emails = ~220 min | |
| timeout-minutes: 240 | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| cache: 'pip' | |
| - name: Install dependencies | |
| run: pip install -r requirements.txt | |
| - name: Restore Google service account JSON | |
| env: | |
| SA_JSON: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_JSON }} | |
| SA_JSON_B64: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_JSON_B64 }} | |
| run: | | |
| if [ -n "$SA_JSON_B64" ]; then | |
| echo "$SA_JSON_B64" | base64 -d > service_account.json | |
| echo "Restored from base64-encoded secret." | |
| elif [ -n "$SA_JSON" ]; then | |
| printf '%s' "$SA_JSON" > service_account.json | |
| echo "Restored from raw JSON secret." | |
| else | |
| echo "ERROR: Neither GOOGLE_SERVICE_ACCOUNT_JSON nor GOOGLE_SERVICE_ACCOUNT_JSON_B64 is set in repo secrets!" >&2 | |
| exit 1 | |
| fi | |
| python -c "import json; json.load(open('service_account.json')); print('service_account.json is valid.')" | |
| - name: Build .env file from secrets | |
| run: | | |
| cat > .env <<EOF | |
| SENDER_EMAIL=${{ secrets.SENDER_EMAIL }} | |
| GMAIL_APP_PASSWORD=${{ secrets.GMAIL_APP_PASSWORD }} | |
| SPREADSHEET_ID=${{ secrets.SPREADSHEET_ID }} | |
| FORM_SHEET_ID=1dFcnVvQjWkuYhN1rplICTY0j88KgvGqQ3FzYId2ru4s | |
| GOOGLE_SERVICE_ACCOUNT_JSON=service_account.json | |
| RECIPIENT_EMAILS=${{ secrets.RECIPIENT_EMAILS }} | |
| TELEGRAM_BOT_TOKEN=${{ secrets.TELEGRAM_BOT_TOKEN }} | |
| TELEGRAM_CHAT_ID=${{ secrets.TELEGRAM_CHAT_ID }} | |
| EOF | |
| - name: Send announcement / update email (catches any who missed it mid-week) | |
| run: python announce.py | |
| - name: Send weekly opportunity digest | |
| run: python run.py --notify | |
| - name: Send Telegram digest | |
| run: python telegram_notify.py | |
| - name: Upload logs | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: digest-logs | |
| path: scoutbot.log | |
| if-no-files-found: ignore | |
| retention-days: 14 |