Serverless handler stub created
This commit is contained in:
17
ma-api/lib/MarketAlert.js
Normal file
17
ma-api/lib/MarketAlert.js
Normal file
@@ -0,0 +1,17 @@
|
||||
const Sequelize = require("sequelize");
|
||||
const sequelize = require("./db.js");
|
||||
const MarketAlert = sequelize.define("market_alert", {
|
||||
id: {
|
||||
type: Sequelize.INTEGER,
|
||||
autoIncrement: true,
|
||||
primaryKey: true
|
||||
},
|
||||
olx_url: Sequelize.STRING,
|
||||
last_date: Sequelize.STRING,
|
||||
email: {
|
||||
type: Sequelize.STRING,
|
||||
allowNull: false
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = MarketAlert;
|
||||
8
ma-api/lib/arethereanynewitems.js
Normal file
8
ma-api/lib/arethereanynewitems.js
Normal file
@@ -0,0 +1,8 @@
|
||||
const convertToDate = require("./convertToDate");
|
||||
function areThereAnyNewItems(lastItemDate, controlDate) {
|
||||
if (!lastItemDate) {
|
||||
return true;
|
||||
}
|
||||
return new Date(controlDate) < convertToDate(lastItemDate);
|
||||
}
|
||||
module.exports = areThereAnyNewItems;
|
||||
13
ma-api/lib/convertToDate.js
Normal file
13
ma-api/lib/convertToDate.js
Normal file
@@ -0,0 +1,13 @@
|
||||
function convertToDate(date) {
|
||||
const [dan, mjesec, godina] = date
|
||||
.split(". u ")[0]
|
||||
.split(".")
|
||||
.map(el => Number(el));
|
||||
const [sati, minute] = date
|
||||
.split(". u ")[1]
|
||||
.split(":")
|
||||
.map(el => Number(el));
|
||||
return new Date(godina, mjesec, dan, sati, minute);
|
||||
}
|
||||
|
||||
module.exports = convertToDate;
|
||||
8
ma-api/lib/db.js
Normal file
8
ma-api/lib/db.js
Normal file
@@ -0,0 +1,8 @@
|
||||
const Sequelize = require("sequelize");
|
||||
const sequelize = new Sequelize("sql7276322", "sql7276322", "RS53ihYlg9", {
|
||||
host: "sql7.freemysqlhosting.net",
|
||||
dialect: "mysql",
|
||||
operatorsAliases: false
|
||||
});
|
||||
|
||||
module.exports = sequelize;
|
||||
96
ma-api/lib/index.js
Normal file
96
ma-api/lib/index.js
Normal file
@@ -0,0 +1,96 @@
|
||||
let express = require("express");
|
||||
const path = require("path");
|
||||
const bodyParser = require("body-parser");
|
||||
const MarketAlert = require("./MarketAlert");
|
||||
const sendNotification = require("./utils/sendnotification");
|
||||
const scrapTheItems = require("./utils/scraptheitems");
|
||||
const sequelize = require("./db.js");
|
||||
const Twocheckout = require("2checkout-node");
|
||||
|
||||
const app = express();
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
|
||||
const port = process.env.PORT || 5000;
|
||||
|
||||
app.get("/sendnotifications", async function(req, res) {
|
||||
let marketAlerts = await MarketAlert.findAll();
|
||||
|
||||
let lastDateUpdate = await Promise.all(
|
||||
marketAlerts
|
||||
.map(marketAlert => {
|
||||
const { id, email, olx_url, last_date } = marketAlert.dataValues;
|
||||
return { id, email, olx_url, last_date };
|
||||
})
|
||||
.map(sendNotification)
|
||||
);
|
||||
lastDateUpdate = lastDateUpdate.filter(Boolean(dateUpdate));
|
||||
lastDateUpdate.length &&
|
||||
lastDateUpdate.forEach(dateUpdate =>
|
||||
MarketAlert.update(
|
||||
{ last_date: dateUpdate.date },
|
||||
{ where: { id: dateUpdate.id } }
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
app.get("/items/:url", async (req, res) => {
|
||||
let url =
|
||||
"https://www.olx.ba/pretraga?" +
|
||||
req.params.url +
|
||||
"&sort_order=desc&sort_po=datum";
|
||||
let appts = await scrapTheItems(url);
|
||||
res.json({
|
||||
last_date: appts[0] && appts[0].date,
|
||||
items: appts
|
||||
});
|
||||
});
|
||||
|
||||
app.post("/marketalerts", function(req, res) {
|
||||
const { email, last_date, olx_url } = req.body;
|
||||
console.log(email, last_date, olx_url);
|
||||
res.json({ message: "Market Alert Created!" });
|
||||
// sequelize.sync().then(() =>
|
||||
// MarketAlert.create({
|
||||
// olx_url,
|
||||
// last_date,
|
||||
// email
|
||||
// })
|
||||
// );
|
||||
// res.json({ message: "Market Alert Created!" });
|
||||
});
|
||||
|
||||
app.post("/payforalert", function(request, response) {
|
||||
let tco = new Twocheckout({
|
||||
sellerId: "901402692",
|
||||
privateKey: "A28DCE5F-9292-405C-8161-F84D8BB83AFC",
|
||||
sandbox: true
|
||||
});
|
||||
|
||||
let params = {
|
||||
merchantOrderId: "123",
|
||||
token: request.body.token,
|
||||
currency: "USD",
|
||||
total: "2.00",
|
||||
billingAddr: {
|
||||
name: "Testing Tester",
|
||||
addrLine1: "123 Test St",
|
||||
city: "Sarajevo",
|
||||
state: "BiH",
|
||||
zipCode: "71000",
|
||||
country: "BiH",
|
||||
email: request.body.email,
|
||||
phoneNumber: "5555555555"
|
||||
}
|
||||
};
|
||||
|
||||
tco.checkout.authorize(params, function(error, data) {
|
||||
if (error) {
|
||||
response.send(error.message);
|
||||
} else {
|
||||
response.send(data.response.responseMsg);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
|
||||
42
ma-api/lib/scraptheitems.js
Normal file
42
ma-api/lib/scraptheitems.js
Normal file
@@ -0,0 +1,42 @@
|
||||
let fetch = require("node-fetch");
|
||||
let cheerio = require("cheerio");
|
||||
const areThereAnyNewItems = require("./arethereanynewitems");
|
||||
|
||||
async function scrapTheItems(url, controlDate, noNewItems = false) {
|
||||
let items = [];
|
||||
let response = await fetch(url);
|
||||
const body = await response.text();
|
||||
const $ = cheerio.load(body);
|
||||
$("#rezultatipretrage")
|
||||
.find(".listitem")
|
||||
.each(async (index, elem) => {
|
||||
if (noNewItems) return;
|
||||
const itemDate = $(elem)
|
||||
.find(".cijena > .datum > div")
|
||||
.first()
|
||||
.attr("data-cijelidatum");
|
||||
|
||||
if (controlDate && !areThereAnyNewItems(itemDate, controlDate)) {
|
||||
noNewItems = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const id = $(elem)
|
||||
.find("a")
|
||||
.first()
|
||||
.attr("href");
|
||||
const cijena = $(elem)
|
||||
.find(".cijena > .datum > span")
|
||||
.first()
|
||||
.text();
|
||||
const image = $(elem)
|
||||
.find("a > .slika > img")
|
||||
.first()
|
||||
.attr("src");
|
||||
|
||||
items.push({ url: id, price: cijena, image, date: itemDate });
|
||||
});
|
||||
return items;
|
||||
}
|
||||
|
||||
module.exports = scrapTheItems;
|
||||
33
ma-api/lib/sendnotification.js
Normal file
33
ma-api/lib/sendnotification.js
Normal file
@@ -0,0 +1,33 @@
|
||||
const scrapTheItems = require("./scraptheitems");
|
||||
const convertToDate = require("./convertToDate");
|
||||
const sgMail = require("@sendgrid/mail");
|
||||
// should be process.env.SENDGRID_API_KEY
|
||||
sgMail.setApiKey(
|
||||
"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"
|
||||
);
|
||||
|
||||
async function sendNotification(marketAlert) {
|
||||
const { id, email, olx_url, last_date } = marketAlert;
|
||||
let url =
|
||||
"https://www.olx.ba/pretraga?" + olx_url + "&sort_order=desc&sort_po=datum";
|
||||
let newItems = await scrapTheItems(url);
|
||||
let lastDate = newItems.length && newItems[0].date;
|
||||
let message =
|
||||
newItems.length &&
|
||||
newItems.reduce(
|
||||
(mes, item) => mes + `<strong>${item.url} i ${item.price}</strong>`,
|
||||
""
|
||||
);
|
||||
const msg = {
|
||||
to: email,
|
||||
from: "test@example.com",
|
||||
subject: "Market Alert",
|
||||
text: "New items on olx",
|
||||
html: message
|
||||
};
|
||||
if (message) {
|
||||
await sgMail.send(msg);
|
||||
return { id, date: String(convertToDate(lastDate)) };
|
||||
}
|
||||
}
|
||||
module.exports = sendNotification;
|
||||
Reference in New Issue
Block a user