DeepSeek Harness Remote
DeepSeek Harness Remote 可將手機或另一台電腦與你運行 DeepSeek Harness 的電腦安全連接,隨時隨地繼續你的工作,方便隨時查看進度並繼續工作。
AI 翻譯
尚未收集儲存庫資訊。
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
AI opportunity tracker for Gmail: finds opportunities and deadlines with an explainable match % (Next.js, Django, Gemini)
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗An AI agent that reads your Gmail (read-only), finds internships, jobs, hackathons, scholarships and events, tracks their deadlines and ranks them against your profile, so nothing important gets buried in your inbox.
Live site: https://oppora-app.vercel.app
Try it without Gmail: on the live site, click Try the demo. It opens a shared, read-only sample account ("Alex") filled with made-up emails, so no sign-in or Gmail is needed and nothing you do there is saved. The first load may take about a minute while the free server wakes up.
Gmail sign-in is invite-only for now (Google's testing phase), so the demo is the way in for visitors.
▶ Watch on YouTube: a one-minute explainer of how Oppora finds opportunities in Gmail, ranks them and tracks their deadlines.
| Landing page: Sign in with Google or Try the demo | Opportunities found in the inbox, with match % |
| Details: AI summary and why it matches | Deadlines, coloured by urgency |
| AI insights and application progress | Assistant that answers from your own data |
On a phone:
All screenshots are from the public demo account, which contains only made-up sample emails.
| Part | Built with | Hosted on (free plans) |
|---|---|---|
| Website | Next.js 16 (App Router), React, TypeScript, Tailwind CSS v4, Radix, Lucide | Vercel |
| API | Python 3.14, Django 5.2, Django REST Framework, gunicorn | Render |
| Database | PostgreSQL 16 | Neon |
| Rate limits | Redis 7 | Upstash |
| AI | Google Gemini (free tier) behind one provider interface | Google AI Studio |
Gmail API (gmail.readonly) with Google sign-in (OAuth + PKCE) | Google Cloud | |
| Background work | Celery + Redis locally; on the free plan, short resumable batches and an hourly GitHub Actions scheduler | GitHub |
flowchart LR
B[Browser] --> V["Vercel<br/>Next.js website"]
V -- "/api/* (same-origin proxy)" --> R["Render<br/>Django + DRF API"]
R --> N[("Neon<br/>PostgreSQL")]
R --> U[("Upstash<br/>Redis rate limits")]
R <--> GM["Gmail API<br/>read-only"]
R --> GE["Google Gemini<br/>AI extraction"]
GH["GitHub Actions<br/>hourly scheduler"] -- "secret-protected POST" --> R
The browser only ever talks to the website. Next.js forwards /api/* to Django, so the session cookie is
first-party and httpOnly, no CORS is needed, and no key ever reaches the browser.
gmail.readonly scope is requested. Google sign-in uses PKCE, OAuth
tokens are encrypted at rest (Fernet, with key rotation) and never sent to the browser, and disconnecting revokes
access at Google.null and shows
as Not mentioned in email.More detail on each of these: CLAUDE.md (decisions and stage notes) and backend/README.md (API and backend layout).
.env locally, the hosting dashboards online). The browser bundle contains no
keys.TOKEN_ENCRYPTION_KEY=<new>,<old>, run
backend\.venv\Scripts\python backend\manage.py rotate_token_key, then remove the old key.I built Oppora with Claude Code as my AI pair-programmer, in 12 stages: I wrote the product brief and design direction, set the rules (read-only Gmail, never invent facts, free services only, tests for every stage), made the decisions at each step, and reviewed and tested the results, including with my own real Gmail before going live.
Free hosting guide (Vercel, Render, Neon, Upstash, GitHub Actions): docs/deploy.md. Google sign-in, Gmail and Gemini setup: docs/google-cloud-setup.md. A click-by-click 2-minute demo script: docs/demo-script.md.
In PowerShell, from the project folder:
powershell -ExecutionPolicy Bypass -File .\start-oppora.ps1
The script:
.env on the first run and generates any missing secret keysnpm install (first run, or when package-lock.json changes)docker compose up -d --wait)It's safe to run again: anything already running is left alone, except that the backend restarts when .env changed, and the worker and beat restart when .env or backend code changed. -ExecutionPolicy Bypass applies only to this run.
| Option | What it does |
|---|---|
-RefreshDemo | Reloads the demo account's data for today (dates are relative to the load day). Your real account isn't touched. |
-Restart | Restarts Oppora's own servers (never other programs on ports 8000/3000). |
-NoBrowser | Doesn't open the browser. |
Stop: close the four Oppora … windows. To stop the database too, run docker compose stop.
.env, and save. The backend restarts by itself, and Google sign-in then replaces the demo sign-in.cp .env.example .env # then fill in DJANGO_SECRET_KEY and TOKEN_ENCRYPTION_KEY (see the comments)
docker compose up -d --wait # Postgres + Redis
cd backend
python3.14 -m venv .venv && . .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt -r requirements-dev.txt
python manage.py migrate
python manage.py seed_demo # demo account; needs Node and `npm install` in ../frontend
# four terminals:
python manage.py runserver 127.0.0.1:8000
python -m celery -A config worker --pool=solo --loglevel=info
python -m celery -A config beat --loglevel=info --schedule .celery/beat-schedule
cd ../frontend && npm install && npm run dev # http://localhost:3000
Without Redis or a worker you can set JOBS_BACKEND=thread. Syncs then run inside the web process, but nothing is scheduled.
Every variable is listed and explained in .env.example. The ones you'll touch:
| Variable | Purpose |
|---|---|
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_REDIRECT_URI | Google sign-in and Gmail (read-only). Keep the Google Cloud app in Testing mode with your Gmail as a test user. |
GEMINI_API_KEY, GEMINI_MODEL, GEMINI_FALLBACK_MODEL | The AI. Use a Google AI Studio project without billing so it stays free. |
AI_REQUESTS_PER_MINUTE, AI_REQUESTS_PER_DAY | Keep at or below your free-tier limits. Over the limit, emails wait in a queue and resume by themselves. |
GMAIL_INITIAL_SYNC_DAYS | How far back the first scan looks (default 60 days). |
DEFAULT_USER_TIMEZONE | Used for "today" until the browser reports your zone. |
TOKEN_ENCRYPTION_KEY, DJANGO_SECRET_KEY | Generated by the start script. Never commit them. |
AI_PROVIDER=openai switches to OpenAI, which is paid. It's never enabled by default.
cd frontend; npm run check # ESLint + TypeScript + Vitest
npm run build # production build
cd ..\backend; .venv\Scripts\python -m pytest # API, pipeline, security, journey, performance
.venv\Scripts\ruff check .; .venv\Scripts\ruff format --check .
.venv\Scripts\python manage.py makemigrations --check --dry-run
backend/tests/test_journey.py runs the complete journey with Google, Gmail and the AI faked: sign-in → sync → AI analysis → details → save → apply → reminder → assistant.
| Symptom | Fix |
|---|---|
| Sign in with Google opens the demo account | Google keys aren't in .env yet, or the backend wasn't restarted. Saving .env restarts it; -Restart forces it. |
| Settings shows Gmail: Needs reconnect | In Testing mode Google expires refresh tokens after 7 days. Click Reconnect. |
| The sync card says N emails queued | The AI's daily free limit is used up. They resume by themselves after the reset (midnight Pacific time) while the worker and beat are running. |
| Port 8000 or 3000 is in use | Another program uses it. The script tells you which. Close it, or change the port. |
| Demo dates look old | Run start-oppora.ps1 -RefreshDemo. |
DJANGO_DEBUG=false, strong secrets (the server refuses to start with weak or missing keys) and its own database
password on Neon.