2026-02-16 23:01:00 -05:00

109 lines
3.2 KiB
Bash
Executable File

#!/bin/bash
# Upwork Auto-Apply Pipeline
# Called by Clawdbot wake event when new Upwork email arrives
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ACCOUNT="jake@localbosses.org"
PROCESSED_FILE="$SCRIPT_DIR/processed.json"
MIN_HOURLY=50
MIN_FIXED=1000
# Initialize processed file if missing
[ -f "$PROCESSED_FILE" ] || echo '[]' > "$PROCESSED_FILE"
echo "[pipeline] Checking for new Upwork job emails..."
# Search for unread Upwork job notification emails
EMAILS=$(gog gmail search "from:donotreply@upwork.com subject:\"New job\" is:unread" \
--max 10 --account "$ACCOUNT" --json 2>&1)
if [ $? -ne 0 ]; then
echo "[pipeline] ERROR: Gmail search failed: $EMAILS"
exit 1
fi
# Parse email IDs
EMAIL_IDS=$(echo "$EMAILS" | jq -r '.[].messages[0].id // empty' 2>/dev/null)
if [ -z "$EMAIL_IDS" ]; then
echo "[pipeline] No new Upwork job emails found."
exit 0
fi
PROCESSED_COUNT=0
SKIPPED_COUNT=0
for MSG_ID in $EMAIL_IDS; do
# Skip already processed
if jq -e "index(\"$MSG_ID\")" "$PROCESSED_FILE" > /dev/null 2>&1; then
echo "[pipeline] Already processed: $MSG_ID"
SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
continue
fi
echo "[pipeline] Processing email: $MSG_ID"
# Get full email
EMAIL_BODY=$(gog gmail get "$MSG_ID" --account "$ACCOUNT" --json 2>&1)
if [ $? -ne 0 ]; then
echo "[pipeline] ERROR reading email $MSG_ID: $EMAIL_BODY"
continue
fi
# Extract job URL
JOB_URL=$(echo "$EMAIL_BODY" | jq -r '.body // .snippet // ""' | \
grep -oP 'https://www\.upwork\.com/jobs/~\d+' | head -1)
if [ -z "$JOB_URL" ]; then
# Try plain text extraction
JOB_URL=$(gog gmail get "$MSG_ID" --account "$ACCOUNT" 2>&1 | \
grep -oP 'https://www\.upwork\.com/jobs/~\d+' | head -1)
fi
if [ -z "$JOB_URL" ]; then
echo "[pipeline] No job URL found in email $MSG_ID, skipping"
continue
fi
# Extract subject for logging
SUBJECT=$(echo "$EMAIL_BODY" | jq -r '.subject // "unknown"' 2>/dev/null || echo "unknown")
echo "[pipeline] Job URL: $JOB_URL"
echo "[pipeline] Subject: $SUBJECT"
# Extract rate info from email body
RATE_INFO=$(gog gmail get "$MSG_ID" --account "$ACCOUNT" 2>&1 | \
grep -E '^\s*(Hourly|Fixed)' | head -1 || echo "")
echo "[pipeline] Rate: $RATE_INFO"
# Quick pre-filter based on email rate info
if echo "$RATE_INFO" | grep -qi "hourly"; then
MAX_RATE=$(echo "$RATE_INFO" | grep -oP '\$\d+' | tail -1 | tr -d '$')
if [ -n "$MAX_RATE" ] && [ "$MAX_RATE" -lt "$MIN_HOURLY" ]; then
echo "[pipeline] SKIP: Max hourly rate \$$MAX_RATE < \$$MIN_HOURLY minimum"
# Mark as processed so we don't revisit
jq ". + [\"$MSG_ID\"]" "$PROCESSED_FILE" > "$PROCESSED_FILE.tmp" && mv "$PROCESSED_FILE.tmp" "$PROCESSED_FILE"
SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
continue
fi
fi
# Output job info for Clawdbot to process
echo "---JOB_DATA---"
echo "MSG_ID=$MSG_ID"
echo "JOB_URL=$JOB_URL"
echo "SUBJECT=$SUBJECT"
echo "RATE_INFO=$RATE_INFO"
echo "---END_JOB_DATA---"
# Mark as processed
jq ". + [\"$MSG_ID\"]" "$PROCESSED_FILE" > "$PROCESSED_FILE.tmp" && mv "$PROCESSED_FILE.tmp" "$PROCESSED_FILE"
PROCESSED_COUNT=$((PROCESSED_COUNT + 1))
done
echo "[pipeline] Done. Processed: $PROCESSED_COUNT, Skipped: $SKIPPED_COUNT"