From 7108a479b5e7815baa61f6ed76dc4a24b5af15d1 Mon Sep 17 00:00:00 2001
From: Animesh Das <100115113+Animesh-Das245@users.noreply.github.com>
Date: Mon, 30 Oct 2023 18:25:16 +0530
Subject: [PATCH 1/5] Create NotificationPreferenceForm.js
---
frontend/src/NotificationPreferenceForm.js | 53 ++++++++++++++++++++++
1 file changed, 53 insertions(+)
create mode 100644 frontend/src/NotificationPreferenceForm.js
diff --git a/frontend/src/NotificationPreferenceForm.js b/frontend/src/NotificationPreferenceForm.js
new file mode 100644
index 0000000..6a6f116
--- /dev/null
+++ b/frontend/src/NotificationPreferenceForm.js
@@ -0,0 +1,53 @@
+// src/NotificationPreferenceForm.js
+
+import React, { useState } from "react";
+
+function NotificationPreferenceForm() {
+ const [email, setEmail] = useState('');
+ const [productId, setProductId] = useState('');
+ const [originalPrice, setOriginalPrice] = useState('');
+
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+ const data = {
+ email,
+ product_id: productId,
+ original_price: originalPrice,
+ };
+
+ const response = await fetch('http://localhost:5000/set-notification-preference', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(data)
+ });
+
+ if (response.ok) {
+ const result = await response.json();
+ alert(result.message);
+ } else {
+ alert('Failed to set notification preference. Please try again.');
+ }
+ };
+
+ return (
+
+ );
+}
+
+export default NotificationPreferenceForm;
From 9863be0f15a181421e8f63abe9fac5df7b198dd0 Mon Sep 17 00:00:00 2001
From: Animesh Das <100115113+Animesh-Das245@users.noreply.github.com>
Date: Mon, 30 Oct 2023 18:29:19 +0530
Subject: [PATCH 2/5] Update App.js
---
frontend/src/App.js | 2 ++
1 file changed, 2 insertions(+)
diff --git a/frontend/src/App.js b/frontend/src/App.js
index 2b50294..b8558e2 100644
--- a/frontend/src/App.js
+++ b/frontend/src/App.js
@@ -3,6 +3,7 @@ import SearchTextList from "./components/SearchTextList";
import PriceHistoryTable from "./components/PriceHistoryTable";
import axios from "axios";
import TrackedProductList from "./components/TrackedProductList";
+import NotificationPreferenceForm from "./NotificationPreferenceForm";
const URL = "http://localhost:5000";
@@ -83,6 +84,7 @@ function App() {
onSearchTextClick={handleSearchTextClick}
/>
+
{showPriceHistory && (
Date: Mon, 30 Oct 2023 18:38:17 +0530
Subject: [PATCH 3/5] Update app.py
---
Backend/app.py | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/Backend/app.py b/Backend/app.py
index 49c9f57..660a810 100644
--- a/Backend/app.py
+++ b/Backend/app.py
@@ -39,6 +39,15 @@ class TrackedProducts(db.Model):
def __init__(self, name, tracked=True):
self.name = name
self.tracked = tracked
+
+class NotificationPreference(db.Model):
+ id = db.Column(db.Integer, primary_key=True)
+ email = db.Column(db.String(255), nullable=False)
+ product_id = db.Column(db.Integer, db.ForeignKey('tracked_products.id'), nullable=False)
+ original_price = db.Column(db.Float, nullable=False)
+ product = db.relationship('TrackedProducts', back_populates='notification_preferences')
+
+TrackedProducts.notification_preferences = db.relationship('NotificationPreference', back_populates='product')
@app.route('/results', methods=['POST'])
@@ -192,6 +201,26 @@ def update_tracked_products():
"products": product_names}
return jsonify(response), 200
+@app.route('/set-notification-preference', methods=['POST'])
+def set_notification_preference():
+ email = request.json.get('email')
+ product_id = request.json.get('product_id')
+ original_price = request.json.get('original_price')
+
+ new_preference = NotificationPreference(email=email, product_id=product_id, original_price=original_price)
+ db.session.add(new_preference)
+ db.session.commit()
+
+ return jsonify({'message': 'Notification preference set successfully'}), 200
+
+
+from apscheduler.schedulers.background import BackgroundScheduler
+from notifications import check_notifications
+
+scheduler = BackgroundScheduler()
+scheduler.add_job(func=check_notifications, trigger="interval", minutes=60)
+scheduler.start()
+
if __name__ == '__main__':
with app.app_context():
From a47f8996faac54d639b5dec6f5d6ff2630300951 Mon Sep 17 00:00:00 2001
From: Animesh Das <100115113+Animesh-Das245@users.noreply.github.com>
Date: Mon, 30 Oct 2023 18:39:08 +0530
Subject: [PATCH 4/5] Create notifications.py
---
Backend/notifications.py | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
create mode 100644 Backend/notifications.py
diff --git a/Backend/notifications.py b/Backend/notifications.py
new file mode 100644
index 0000000..a37489d
--- /dev/null
+++ b/Backend/notifications.py
@@ -0,0 +1,35 @@
+import smtplib
+from email.mime.text import MIMEText
+from app import db, NotificationPreference, TrackedProducts
+
+def check_notifications():
+ notification_preferences = NotificationPreference.query.all()
+
+ for preference in notification_preferences:
+ latest_price = TrackedProducts.query.filter_by(id=preference.product_id).first().price
+ percent_drop = ((preference.original_price - latest_price) / preference.original_price) * 100
+
+ if percent_drop >= 30:
+ send_notification(preference.email, preference.product, latest_price, percent_drop)
+
+def send_notification(email, product, price, percent_drop):
+ smtp_server = 'smtp.example.com'
+ smtp_port = 587
+ smtp_username = 'your_username'
+ smtp_password = 'your_password'
+
+ subject = f'Price Drop Alert for {product.name}'
+ body = f'The price for {product.name} has dropped by {percent_drop}% to {price}!'
+ msg = MIMEText(body)
+ msg['Subject'] = subject
+ msg['From'] = 'notifications@example.com'
+ msg['To'] = email
+
+ try:
+ with smtplib.SMTP(smtp_server, smtp_port) as server:
+ server.starttls()
+ server.login(smtp_username, smtp_password)
+ server.send_message(msg)
+ print(f'Notification sent to {email}')
+ except Exception as e:
+ print(f'Failed to send notification: {e}')
From e965a2a6a990959ac141b3751ceb55d1eb9fb99e Mon Sep 17 00:00:00 2001
From: Animesh Das <100115113+Animesh-Das245@users.noreply.github.com>
Date: Mon, 30 Oct 2023 18:57:46 +0530
Subject: [PATCH 5/5] Update README.md
---
README.md | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/README.md b/README.md
index f77ff69..b68b53e 100644
--- a/README.md
+++ b/README.md
@@ -36,6 +36,33 @@ Fill in your [Bright Data Scraping Browser](https://brightdata.com/products/scra
To automate the collection of prices from this software simply run the `scheduler/main.py` file at your desired increment while the python flask backend is running.
+## New Feature: Price Drop Notifications
+
+We have introduced a new feature to notify users when the price of a tracked product drops by 30% or more. Users can easily set their notification preferences by providing their email address and selecting the product they are interested in.
+
+### Setup
+
+1. **SMTP Relay Service**:
+ - We've implemented an email notification system using an SMTP relay service.
+ - You will need to create an account with an SMTP relay service of your choice (e.g., SendGrid, Mailgun, etc.).
+ - Update the `SMTP_SERVER`, `SMTP_PORT`, `SMTP_USER`, and `SMTP_PASSWORD` environment variables in your backend configuration with the credentials provided by your SMTP relay service.
+
+2. **Backend Configuration**:
+ - In the `app.py` file in the backend folder, ensure that the `/set-notification-preference` and `/check-price-drop` routes are correctly set up.
+
+3. **Frontend Integration**:
+ - Include the `NotificationPreferenceForm` component in your frontend application where users can enter their email address and set their notification preference for specific products.
+
+### Usage
+
+- Users can navigate to the Notification Preference section on the UI.
+- Enter their email address, select a product, and specify the original price.
+- Once the preference is set, the system will monitor the price of the specified product.
+- When a price drop of 30% or more is detected, an email notification will be sent to the user informing them of the price drop.
+
+This feature enhances the user experience by providing timely notifications on price drops for products they are interested in.
+
+
### Windows
I have created a simple `.bat` script called `run.bat` that you can schedule to execute using the Windows Task Scheduler that will automatically run the backend api and send the appropriate request to it.