name: Sync NPM Keyword Search on: schedule: # Run every 15 minutes - cron: '*/15 * * * *' workflow_dispatch: jobs: sync-keyword: runs-on: ubuntu-latest steps: - name: Trigger keyword search sync id: sync run: | # Call the sync API and capture response response=$(curl -X POST "${{ secrets.VERCEL_PRODUCTION_URL }}/api/sync/keyword" \ -H "Authorization: Bearer ${{ secrets.CRON_SECRET }}" \ -H "Content-Type: application/json" \ -f -s -S) echo "Response: $response" # Extract data using jq processed=$(echo "$response" | jq -r '.data.processed') skipped=$(echo "$response" | jq -r '.data.skipped') errors=$(echo "$response" | jq -r '.data.errors') packagesFound=$(echo "$response" | jq -r '.data.packagesFound') durationMs=$(echo "$response" | jq -r '.data.durationMs') # Extract and display error messages errorMessages=$(echo "$response" | jq -r '.data.errorMessages[]?' 2>/dev/null || echo "") if [ -n "$errorMessages" ]; then echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "⚠️ SYNC ERRORS ($errors total):" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "$response" | jq -r '.data.errorMessages[]?' | while IFS= read -r error; do echo " • $error" done echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" fi # Set outputs for Discord notification echo "processed=$processed" >> $GITHUB_OUTPUT echo "skipped=$skipped" >> $GITHUB_OUTPUT echo "errors=$errors" >> $GITHUB_OUTPUT echo "packagesFound=$packagesFound" >> $GITHUB_OUTPUT echo "durationMs=$durationMs" >> $GITHUB_OUTPUT # Store error messages for Discord (first 3, truncated) if [ "$errors" -gt 0 ]; then errorSummary=$(echo "$response" | jq -r '.data.errorMessages[0:3]? | join("\n• ")' 2>/dev/null || echo "") if [ -n "$errorSummary" ]; then # Save to file to preserve newlines echo "• $errorSummary" > /tmp/error_summary.txt fi fi # Store skipped packages for Discord if [ "$skipped" -gt 0 ]; then skippedList=$(echo "$response" | jq -r '.data.skippedPackages[]? | "\(.name) (by \(.author)) - \(.reason)"' 2>/dev/null | paste -sd "\n" - || echo "") if [ -n "$skippedList" ]; then echo "$skippedList" > /tmp/skipped_packages.txt fi fi # Determine status emoji if [ "$errors" -gt 0 ]; then echo "status_emoji=⚠️" >> $GITHUB_OUTPUT echo "status_color=16776960" >> $GITHUB_OUTPUT # Yellow else echo "status_emoji=✅" >> $GITHUB_OUTPUT echo "status_color=5763719" >> $GITHUB_OUTPUT # Green fi - name: Send Discord notification if: always() run: | # Format duration duration_sec=$(echo "scale=2; ${{ steps.sync.outputs.durationMs }} / 1000" | bc) # Build Discord payload using jq for proper JSON escaping # Read optional data error_text="" skipped_text="" if [ -f /tmp/error_summary.txt ] && [ ${{ steps.sync.outputs.errors }} -gt 0 ]; then error_text=$(cat /tmp/error_summary.txt | head -c 800) fi if [ -f /tmp/skipped_packages.txt ] && [ ${{ steps.sync.outputs.skipped }} -gt 0 ]; then skipped_text=$(cat /tmp/skipped_packages.txt) fi # Build fields array dynamically base_fields='[ { "name": "📦 Packages Found", "value": "${{ steps.sync.outputs.packagesFound }}", "inline": true }, { "name": "✨ Processed", "value": "${{ steps.sync.outputs.processed }}", "inline": true }, { "name": "⏭️ Skipped", "value": "${{ steps.sync.outputs.skipped }}", "inline": true }, { "name": "❌ Errors", "value": "${{ steps.sync.outputs.errors }}", "inline": true }, { "name": "⏱️ Duration", "value": "'"${duration_sec}s"'", "inline": true }, { "name": "🔗 Run", "value": "[View Logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})", "inline": true } ]' # Create payload with dynamic fields payload=$(jq -n \ --arg title "${{ steps.sync.outputs.status_emoji }} NPM Keyword Search Sync" \ --argjson color ${{ steps.sync.outputs.status_color }} \ --argjson baseFields "$base_fields" \ --arg error_text "$error_text" \ --arg skipped_text "$skipped_text" \ --arg timestamp "$(date -u +%Y-%m-%dT%H:%M:%S.000Z)" \ ' { embeds: [{ title: $title, color: $color, fields: ( $baseFields + (if $skipped_text != "" then [{ name: "📋 Skipped Packages", value: $skipped_text, inline: false }] else [] end) + (if $error_text != "" then [{ name: "🔍 Error Details", value: ("```\n" + $error_text + "\n```"), inline: false }] else [] end) ), timestamp: $timestamp }] }') # Send to Discord curl -X POST "${{ secrets.DISCORD_WEBHOOK }}" \ -H "Content-Type: application/json" \ -d "$payload"