尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
A web app that aggregates events from 10+ sources for the Asheville, NC area, featuring AI-powered tagging, semantic search, and user authentication.檢視完整 README ↗A web app that aggregates events from 10+ sources for the Asheville, NC area, featuring AI-powered tagging, semantic search, and user authentication.
Want to get this running locally? Here's the fastest path:
On a Mac with Homebrew Postgres: npm install && npm run db:setup-local sets up a local database (installing pgvector if needed), writes DATABASE_URL to .env, fills in the public sign-in keys from avlgo.com so Google sign-in works locally, and offers to copy the live site's upcoming events in, scores included. Then npm run dev. The steps below are the hosted-Supabase route.
Head to supabase.com and create a new project. Once it's created, go to Settings > Database and copy the Connection Pooler URI (Transaction mode). It looks something like:
postgresql://postgres.[project-ref]:[password]@aws-0-us-east-1.pooler.supabase.com:6543/postgres
Copy the example env file and add your database URL:
cp .env.example .env
Then edit .env and paste your Supabase connection string:
DATABASE_URL=postgresql://your-connection-string-here
That's the only required variable. The others are optional (AI features, auth, etc.).
npm install
npx drizzle-kit push
The first command installs dependencies. The second creates the tables in your database.
npm run backfill
This scrapes ~30 pages of Eventbrite events and saves them to your database. Takes a couple minutes.
npm run dev
Open http://localhost:3000 and you should see events!
"tsx: command not found" - Run npm install -D tsx to add it locally.
No events showing - Make sure the backfill completed. Check with npm run db:count.
Database connection errors - Double-check your DATABASE_URL in .env. Make sure you're using the Connection Pooler URL from Supabase.
Create a .env file in the project root:
# Required
DATABASE_URL=postgresql://...
# Optional - Cron authentication
CRON_SECRET=your-random-secret-min-16-chars
# Optional - AI Features (Google Gemini)
GEMINI_API_KEY=your-gemini-api-key
# Optional - AI Features (Azure OpenAI)
AZURE_OPENAI_API_KEY=
AZURE_OPENAI_ENDPOINT=
# Optional - Supabase Auth
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
NEXT_PUBLIC_GOOGLE_CLIENT_ID=
See .env.example for the full list of optional variables.
npm install
npm run dev
Open http://localhost:3000 to view the app.
npx drizzle-kit push
npm run dev # Start development server
npm run build # Build for production
npm run start # Start production server
npm run lint # Run ESLint
npm run cron:schedule # View cron job schedules and next run times
npm run db:check # Check database connection
npm run db:count # Count events by source
npm run db:tags # Check tag statistics
npm run db:clear # Clear all events (use with caution)
npm run test:avl # Test AVL Today scraper
npm run test:eventbrite # Test Eventbrite scraper
npm run test:meetup # Test Meetup scraper
npm run test:harrahs # Test Harrah's scraper
npm run test:orangepeel # Test Orange Peel scraper
npm run test:greyeagle # Test Grey Eagle scraper
npm run backfill # Backfill events from Eventbrite
npm run test:tagging # Test AI tagging
npm run test:image-gen # Test AI image generation
npm run test:summary # Test AI summary generation
npm run test:embedding # Test embedding generation
npm run tag:events # Tag all untagged events
npm run backfill:embeddings # Backfill embeddings
| Endpoint | Method | Description |
|---|---|---|
/api/cron/scrape | GET | Trigger event scraping (requires auth) |
/api/cron/ai | GET | Trigger AI processing (requires auth) |
/api/cron/cleanup | GET | Cleanup dead/duplicate events (requires auth) |
/api/cron/dedup | GET | AI semantic deduplication (requires auth) |
/api/health | GET | Health check endpoint |
/api/chat | POST | AI conversational event discovery |
/api/preferences | GET/POST | User preferences sync |
/api/events/[id]/favorite | POST/DELETE | Favorite/unfavorite events |
/api/events/submit | POST | Submit new event |
/api/export/xml | GET | RSS XML export |
/api/export/markdown | GET | Markdown export |
The app scrapes events from 10+ sources:
| Source | Method |
|---|---|
| AVL Today | CitySpark API |
| Eventbrite | HTML scraping + API |
| Meetup | GraphQL API |
| Browser automation (local only) | |
| Harrah's Cherokee | Ticketmaster API |
| Orange Peel | Ticketmaster API + JSON-LD |
| Grey Eagle | JSON-LD |
| Live Music AVL | ICS feeds |
| Explore Asheville | Public API |
| Misfit Improv | Crowdwork API |
| NC Stage | ThunderTix |
| Story Parlor | Squarespace JSON-LD |
The cron jobs are configured in vercel.json:
curl -X GET https://your-domain.vercel.app/api/cron/scrape \
-H "Authorization: Bearer YOUR_CRON_SECRET"
asheville-event-feed/
├── app/ # Next.js App Router
│ ├── api/ # API routes (cron, chat, preferences, etc.)
│ ├── auth/ # Auth routes (callback, signout)
│ ├── events/[slug]/ # Individual event pages
│ ├── login/ # Login page
│ ├── profile/ # User profile page
│ ├── u/[slug]/ # Curator profile pages
│ └── page.tsx # Main page
├── components/ # React components
├── lib/
│ ├── ai/ # AI integrations (Gemini, Azure OpenAI)
│ ├── db/ # Database schema and queries
│ ├── scrapers/ # Event source scrapers
│ ├── supabase/ # Supabase client and utilities
│ └── utils/ # Utility functions
└── scripts/ # CLI utility scripts
MIT