Focus Feed is a full-stack web application that curates news content for users, allows them to configure news preferences, and sends out newsletters on a regular schedule. It uses React on the frontend, Firebase for user authentication, Firestore for data storage, a Node/Express server for back-end tasks, and an ML microservice for specialized endpoints. The project also leverages Resend to deliver email newsletters, with scheduled tasks managed by node-cron. Email server is currently hosted on Railway.
- Features
- Tech Stack
- Installation & Setup
- Environment Variables
- Running Locally
- Scripts
- Testing
- Cron & Newsletter
- ML Server
- Deployment
- License
- User Authentication & Onboarding: Users can sign up, sign in, and be guided through an onboarding process (built on Firebase).
- Preferences: Users can customize their preferred news sources, topics, etc.
- React Frontend: A responsive UI built with React (and optionally Tailwind).
- Newsletter Service: Regularly sends curated news articles to each user’s email using Resend.
- Cron Scheduling: Uses node-cron to automatically dispatch newsletters at set intervals (e.g., weekly or daily).
- ML Microservice: A separate Node/Express service (in
ml/sev) handling specialized routes (e.g., for training or production ML endpoints). - Automated Testing: Jest-based tests for server routes (and additional tests for the ML microservice).
- Frontend: React, React Router, Tailwind CSS (optional), etc.
- Backend: Node.js, Express, Firebase Admin SDK, Firestore, Resend, node-cron
- ML Microservice: Node.js/Express-based, with additional endpoints for training, filtering, and production states
- Database: Firestore (Firebase)
- Email: Resend for transactional emails
- Hosting: Example hosting on Railway.app or other Node-friendly platforms
- Web Scraping API: Backend for article scraping and summarization API
-
Clone the repository:
git clone https://github.com/<your-username>/<your-repo>.git cd <your-repo>
-
Install dependencies:
npm install
This installs both React dependencies and back-end dependencies (all in one
package.json). -
Generate a Firebase Admin Service Account (or use existing). Place it in
serviceAccountKey.json(or store in environment variables). -
Set up
.env:RESEND_API_KEY=your_resend_api_key GOOGLE_APPLICATION_CREDENTIALS=./serviceAccountKey.json # or optionally, SERVICE_ACCOUNT_KEY_JSON=<the JSON string if storing directly>- If using direct JSON for the service account, you can parse it in
firebaseAdmin.js. - Otherwise, keep a local
serviceAccountKey.json(make sure it’s in .gitignore).
- If using direct JSON for the service account, you can parse it in
Typical variables:
RESEND_API_KEY: Your Resend API key to send emails.GOOGLE_APPLICATION_CREDENTIALSorSERVICE_ACCOUNT_KEY_JSON: For Firebase Admin SDK.NODE_ENV: Usuallydevelopmentorproduction.PORT: If you want to run the server on a specific port.
-
Start the React dev server:
npm run dev
This will run Vite-based development mode, typically on http://localhost:5173.
-
(Optional) Start the ML server:
cd ml/sev npm install npm run dd1_TESTS # to test node index.js
By default, it runs on
https://localhost:7050. -
Start the main Node server (including cron job):
npm run start
- This runs
server.js, which initializes a node-cron job for the newsletter. - By default, it might not serve your React app. The React dev server is separate in dev mode.
- This runs
| Script | Description |
|---|---|
npm run dev |
Starts the Vite development server for the React frontend. |
npm run build |
Builds the React app for production into the dist/ folder. |
npm run preview |
Previews the built React app locally. |
npm run start |
Runs server.js, launching the Node process with cron tasks. |
npm run dd1_TESTS |
Runs Jest tests (including the ML server tests). |
npm run cron |
(Optional) Runs node newsletter/cron.js directly. |
- Frontend: Uses React Testing Library for UI tests.
- Backend: Jest-based tests in
ml/sev/testfor the ML server endpoints. - Running Tests:
npm run dd1_TESTS
-
node-cron is used to schedule newsletter sends, located in
src/lib/newsletter/cron.js. -
Manual Sending: You can send a newsletter to a specific user for testing by running:
node src/lib/newsletter/sendNewsletter.js
- By default, that file might reference a
testUIDinside the code. Adjust as needed for your own test user.
- By default, that file might reference a
-
Adjusting the Cron Schedule:
- In
cron.js, you’ll see something like:cron.schedule("30 21 * * 4", async () => { // ... });
- The string
"30 21 * * 4"is a standard cron expression (minute hour day-of-month month day-of-week). - For example,
"0 9 */3 * *"would run at 9:00 AM every 3 days. - For more info, see node-cron docs or a cron expression guide.
- In
-
Resend is used to dispatch the actual email, with logic in
sendNewsletter.js.- The code fetches user sources from Firestore, obtains articles, and composes an HTML email via
FocusFeedNewsletter.js.
- The code fetches user sources from Firestore, obtains articles, and composes an HTML email via
- Located in
ml/sev/. - Exposes routes like
/preProcess,/train,/prod, etc., for machine learning tasks. ml/sev/index.js: Main Express server with HTTPS.- Testing:
npm run dd1_TESTS(or runjestfromml/sev).
- Railway (or any Node-friendly host) can run the
startscript:- Set environment variables (RESEND_API_KEY, etc.) in Railway’s dashboard.
- Deploy. The
server.jsprocess will run automatically. - The React app can be built via
npm run build, then served with your chosen method (or a separate static host).
- ML Server can also be deployed on a separate instance if needed, or combined in a monorepo approach.
This project is licensed under the MIT License. You’re free to modify, distribute, and use it for personal or commercial purposes.
Enjoy building & customizing your own Focus Feed! If you have questions or suggestions, feel free to open an issue or contribute.