Send and receive anonymous messages with optional AI‑generated prompts, secure email verification, and granular control over message acceptance. Built with Next.js 16 App Router, TypeScript, MongoDB (Mongoose), NextAuth (credentials), Zod validation, Tailwind CSS, and Resend for transactional email.
- Overview
- Features
- Tech Stack
- Architecture & Flow
- Directory Structure
- Data Model
- Validation Schemas
- Authentication & Session
- Message Lifecycle
- Email Verification Flow
- AI Prompt Generation
- API Reference
- Environment Variables
- Scripts
- Local Development Setup
- Production Build & Deployment
- Roadmap / Ideas
- Contributing
- Security Notes
- License
Anonymous Messenger allows users to create a verified account, share a public profile link, and receive anonymous messages. Users can toggle whether they accept new messages and manage their inbox (including deletion). The platform offers suggested open‑ended questions powered by Google's Gemini model to encourage engagement.
- Secure credential-based authentication with email verification (OTP code).
- Anonymous message sending with acceptance toggle.
- AI‑generated suggested questions (Gemini).
- Real-time friendly validation via Zod on both client & server.
- Robust aggregation pipeline for ordered message retrieval.
- Email templates built with
@react-email/components. - Server-side session handling using NextAuth JWT strategy.
- Modular API route handlers in App Router.
- Tailwind CSS + component abstractions (Radix UI + custom UI).
| Layer | Technologies |
|---|---|
| Framework | Next.js 16 (App Router) |
| Language | TypeScript |
| Styling | Tailwind CSS, Radix UI primitives, custom components |
| Auth | NextAuth (Credentials Provider, JWT strategy) |
| DB / ORM | MongoDB + Mongoose |
| Validation | Zod |
| Resend + React Email | |
| AI | Google Generative AI (Gemini) via @google/generative-ai |
| Misc | bcryptjs, axios, lucide-react icons |
High-level layers:
- Client: Next.js pages/components (App Router) render auth forms, dashboard, public user page, and message operations.
- API Routes: All business logic for signup, verification, message CRUD (limited to create/delete), AI suggestions, and status toggling lives under
app/api/*. - Auth: NextAuth Credentials provider checks username/email + password and enforces verification. JWT callback enriches token with user metadata.
- Persistence: Mongoose models +
dbConnectprovide a cached connection layer. - Email: Verification codes sent via Resend using a React Email template.
- AI: Suggestion endpoint prompts Gemini for 3 open-ended questions separated by
||.
Condensed view of notable paths:
app/
api/ # Route handlers (REST-like)
(app)/dashboard # Authenticated dashboard UI
(auth)/sign-in # Sign-in page
(auth)/sign-up # Registration page
(auth)/verify/[username] # Email verification page
u/[username] # Public profile page for receiving messages
components/ # Reusable UI components (cards, navbar, etc.)
emails/ # React email templates
lib/ # Utility functions (e.g., utils.ts)
src/lib/dbConnect.ts # Mongo connection helper
src/models/user.model.ts # Mongoose schemas/models
src/schemas/ # Zod validation schemas
src/context/AuthProvider.tsx # Session provider wrapper
src/helpers/sendVerificationEmail.ts # Email dispatch logic
public/ # Static assets
User document (simplified):
interface User {
username: string;
email: string;
password: string; // bcrypt hashed
verifyCode: string; // 6-digit OTP
verifyCodeExpiry: Date; // 1h validity
isVerified: boolean; // must be true for login
isAcceptingMessages: boolean; // toggle for new messages
message: { _id: ObjectId; content: string; createdAt: Date }[];
}Notes:
- Messages embedded within the user document (subdocument array).
- Retrieval uses aggregation to unwind and sort by
message.createdAtdescending.
signUpSchema: username (2–20 chars, regex restricted), email, password (>=6).signInSchema: identifier (email or username) + password.verifySchema: 6‑digit code exact length.messageSchema: content 10–300 chars.acceptMessageSchema: boolean toggle.
- Credentials login checks either email or username.
- Rejects unverified accounts.
- JWT callback attaches
_id,isVerified,isAcceptingMessages,usernameto token and session. - Session strategy: JWT (no DB session storage).
- Visitor accesses
/u/{username}. - Inputs anonymous content (validated 10–300 chars).
send-messageendpoint ensures user exists andisAcceptingMessages === true.- Message appended to embedded array; user saves.
- Authenticated owner queries
get-messageto retrieve sorted messages. - Owner can delete a message via
delete-message/{messageId}. - Owner toggles status via
accept-messagesPOST.
- User submits signup -> server checks uniqueness (verified usernames).
- Generates 6‑digit code, stores hashed password, sets expiry (+1h).
- Sends email via Resend with React Email template.
- User enters code on
/verify/{username}hittingverify-codeendpoint. - If code matches and not expired,
isVerifiedflips true, enabling login.
Endpoint suggest-messages uses Gemini model gemini-2.5-flash-lite to return a single string containing three questions separated by ||. Client splits into individual suggestions.
| Endpoint | Method | Auth | Description | Key Responses |
|---|---|---|---|---|
/api/sign-up |
POST | No | Register user & send verification email | 201 success / 400 conflicts |
/api/verify-code |
POST | No | Verify OTP for username | 200 verified / 400 invalid/expired |
/api/auth/[...nextauth] |
GET/POST | Yes | NextAuth handler | 200 session or 401 errors |
/api/is-username-unique?username= |
GET | No | Validate username availability | 200 unique / 400 taken |
/api/send-message |
POST | No | Send anonymous message to user | 200 stored / 401 not found / 403 disabled |
/api/get-message |
GET | Yes | Retrieve authenticated user messages | 200 list / 404 none / 401 unauth |
/api/delete-message/{messageId} |
DELETE | Yes | Remove a single message | 200 deleted / 401 not found/unauth |
/api/accept-messages |
POST | Yes | Toggle acceptance state | 200 updated / 401 unauth |
/api/accept-messages |
GET | Yes | Fetch acceptance state | 200 state / 401 unauth |
/api/suggest-messages |
GET | No | Get AI suggested prompts | 200 prompts |
General error envelope:
{ "success": false, "message": "<reason>" }Create .env.local with:
MONGODB_URI=<your_mongodb_connection_string>
NEXT_AUTH_SECRET=<strong_random_string>
GEMINI_API_KEY=<google_generative_ai_key>
RESEND_API_KEY=<resend_api_key>
Optional/custom:
- Email
fromaddress configured insendVerificationEmail.ts.
| Script | Purpose |
|---|---|
npm run dev |
Start Next.js dev server |
npm run build |
Production build |
npm run start |
Start production server |
npm run lint |
Run ESLint over project |
git clone https://github.com/PriteshThorat/AnonymousMessenger.git
cd AnonymousMessenger
pnpm install # or npm install / yarn
cp .env.example .env.local # if you create an example file
# Fill in required secrets
npm run devVisit http://localhost:3000.
npm run build
npm run startDeploy on Vercel (recommended):
- Add env vars in Vercel dashboard.
- Ensure MongoDB Atlas IP allowlist includes Vercel serverless IP ranges or uses SRV connection string.
- Rate limiting (IP, per-user).
- Spam / toxicity filtering (AI moderation).
- Pagination & message search.
- Export messages (CSV/JSON).
- Resend webhooks for delivery analytics.
- Optional replies (non-anonymous).
- Dark/light adaptive email templates.
- Fork & clone.
- Create feature branch:
git checkout -b feature/name. - Commit with conventional style messages.
- Lint before pushing.
- Open PR describing changes & testing steps.
- Store only hashed passwords (bcrypt).
- OTP codes expire after 1 hour; consider rate limits.
- JWT secret must be strong and rotated periodically.
- Avoid logging sensitive data (current logs acceptable but can be hardened).
- Consider adding CSRF and better error normalization in future.
This project is licensed under the MIT License.
- See the full text in
LICENSEat the repo root. - Copyright (c) 2025 Pritesh Thorat.
git clone https://github.com/PriteshThorat/AnonymousMessenger.git
cd AnonymousMessenger
npm install
echo "MONGODB_URI=..." >> .env.local
echo "NEXT_AUTH_SECRET=..." >> .env.local
echo "GEMINI_API_KEY=..." >> .env.local
echo "RESEND_API_KEY=..." >> .env.local
npm run devIssues & feature requests: open a GitHub Issue. For security concerns, please email the maintainer privately instead of opening a public issue.