From c6c272423ff94bbdfcfe10c18a6ac69e0d38d5aa Mon Sep 17 00:00:00 2001
From: Julian Barker
Date: Wed, 28 Dec 2022 18:27:22 -0800
Subject: [PATCH 1/4] initial commit for lambdas repo
---
events/.env.sample | 9 +
events/index.js | 231 ++++++++++++++++++
events/package-lock.json | 500 ++++++++++++++++++++++++++++++++++++++
events/package.json | 20 ++
eventsNotification.js | 0
external-api copy.js | 348 ++++++++++++++++++++++++++
weather/.DS_Store | Bin 0 -> 6148 bytes
weather/.env.sample | 9 +
weather/Archive.zip | Bin 0 -> 5597435 bytes
weather/index.js | 230 ++++++++++++++++++
weather/package-lock.json | 500 ++++++++++++++++++++++++++++++++++++++
weather/package.json | 20 ++
weather/test.js | 6 +
13 files changed, 1873 insertions(+)
create mode 100644 events/.env.sample
create mode 100644 events/index.js
create mode 100644 events/package-lock.json
create mode 100644 events/package.json
create mode 100644 eventsNotification.js
create mode 100644 external-api copy.js
create mode 100644 weather/.DS_Store
create mode 100644 weather/.env.sample
create mode 100644 weather/Archive.zip
create mode 100644 weather/index.js
create mode 100644 weather/package-lock.json
create mode 100644 weather/package.json
create mode 100644 weather/test.js
diff --git a/events/.env.sample b/events/.env.sample
new file mode 100644
index 0000000..2d2c206
--- /dev/null
+++ b/events/.env.sample
@@ -0,0 +1,9 @@
+DATABASE_URL=postgres://localhost:5432/
+
+MAILGUN_KEY=
+
+MAILGUN_DOMAIN=
+
+WEATHER_KEY=
+
+MAPBOX_TOKEN=
diff --git a/events/index.js b/events/index.js
new file mode 100644
index 0000000..ef14bce
--- /dev/null
+++ b/events/index.js
@@ -0,0 +1,231 @@
+require('dotenv').config();
+
+const axios = require('axios');
+const Mailgun = require('mailgun.js');
+const formData = require('form-data');
+const { Sequelize, DataTypes } = require('sequelize');
+
+const DATABASE_URL = process.env.DATABASE_URL;
+const db = new Sequelize(DATABASE_URL);
+
+const subs = db.define('Subscriptions', {
+ username: {
+ type: DataTypes.STRING,
+ required: true,
+ },
+ type: {
+ type: DataTypes.ENUM(['weather', 'events']),
+ required: true,
+ },
+});
+
+const users = db.define('Users', {
+ username: {
+ type: DataTypes.STRING,
+ required: true,
+ primaryKey: true,
+ unique: true,
+ },
+ password: {
+ type: DataTypes.STRING,
+ required: true,
+ },
+ role: {
+ type: DataTypes.STRING,
+ required: true,
+ },
+ name: {
+ type: DataTypes.STRING,
+ required: false,
+ },
+ phone: {
+ type: DataTypes.STRING,
+ required: true,
+ },
+ email: {
+ type: DataTypes.STRING,
+ required: true,
+ },
+ zip: {
+ type: DataTypes.STRING,
+ required: true,
+ },
+});
+
+users.hasMany(subs, {
+ foreignKey: 'username',
+});
+subs.belongsTo(users, {
+ foreignKey: 'username',
+});
+
+const mailgun = new Mailgun(formData);
+const client = mailgun.client({
+ username: 'api',
+ key: process.env.MAILGUN_KEY,
+});
+
+const getEvents = socket => ( async () => {
+ try {
+
+ const currentDate = new Date();
+ const startDateTime = currentDate.toISOString().slice(0, -5) + 'Z';
+
+ const endDateTime = new Date(currentDate.getTime() + 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, -5) + 'Z';
+ console.log(startDateTime);
+ console.log(endDateTime);
+
+
+ let apikey = process.env.TICKET_API;
+ let city = 'seattle';
+ let stateCode = 'wa';
+ let radius = '20';
+ let unit = 'miles';
+
+
+ const response = await axios.get(
+ `https://app.ticketmaster.com/discovery/v2/events.json?size=5&apikey=${apikey}&startDateTime=${startDateTime}&endDateTime=${endDateTime}&city=${city}&radius=${radius}&unit=${unit}&stateCode=${stateCode}`);
+
+ const concerts = response.data;
+
+
+ const toStandardTime = function (time) {
+
+ const [hours, minutes, seconds] = time.split(':');
+ let hoursFix = parseInt(hours, 10);
+ let minutesFix = parseInt(minutes, 10);
+ let secondsFix = parseInt(seconds, 10);
+
+ if (hoursFix >= 12) {
+
+ hoursFix -= 12;
+
+
+ time = `${hoursFix.toString().padStart(2, '0')}:${minutesFix
+ .toString()
+ .padStart(2, '0')}:${secondsFix.toString().padStart(2, '0')} PM`;
+ } else {
+
+ time = `${hoursFix.toString().padStart(2, '0')}:${minutesFix
+ .toString()
+ .padStart(2, '0')}:${secondsFix.toString().padStart(2, '0')} AM`;
+ }
+
+ return time;
+ };
+ let eventList = '';
+
+ for (let i = 0; i < 5; i++) {
+ const venueData = concerts._embedded.events[i];
+ const venue = venueData._embedded.venues[0].name;
+ const eventName = concerts._embedded.events[i].name;
+ const eventUrl = concerts._embedded.events[i].url;
+ const eventDate = concerts._embedded.events[i].dates;
+ const eventStartTime = eventDate.start.localTime;
+ const eventStartDate = eventDate.start.localDate;
+ const newTime = toStandardTime(eventStartTime);
+
+ eventList += `${eventName} at ${venue} on ${eventStartDate} at ${newTime}, Link: ${eventUrl}`;
+ }
+
+ const msg = {
+ to: 'steveo732@gmail.com',
+ from: 'notifyme.us@gmail.com',
+ subject: 'Check Out These 5 events happening this week!',
+ text: `Five Upcoming Events in your Area: ${eventList}`,
+ html: `Five Upcoming Events in your Area:
+ `,
+ };
+
+ mailgun.messages().send(msg, (error, body) => {
+ if (error) {
+ console.error(error);
+ socket.emit('API_ERROR', 'An error has occured with your request');
+ } else {
+ console.log(msg.text);
+ socket.emit('API_RESULT', 'success'); // TODO - replace 'success' with actual api result
+ }
+ });
+ } catch (error) {
+ console.error(error);
+ socket.emit('API_ERROR', 'An error has occured with your request');
+ }
+});
+
+async function mailgunForecast(current, forecast, email) {
+ const { data, dates } = forecast;
+
+ const msg = {
+ to: email,
+ from: 'notifyme.us@gmail.com',
+ subject: 'Your Daily Weather Summary',
+ html: `
+
+ Here is your custom weather forecast for ${current.town} from NotifyMe-US:
+
+ -
+ The weather is currently ${current.weather}. The high temperature for today will be ${current.fahrenheitRoundedHigh} degrees Fahrenheit, and the low temperature will be ${current.fahrenheitRoundedLow} degrees Fahrenheit.
+
+ -
+ The humidity will be ${current.humidity}%, and the wind speed will be ${current.windMphFormatted} mph. There will be ${current.cloudCoverage}% cloud coverage.
+
+
+
+
+
+ The weather forecast for the next 5 days:
+
+ -
+ ${dates[0].toLocaleDateString()}: ${data[0].temp} °F with ${data[0].weather}
+
+ -
+ ${dates[1].toLocaleDateString()}: ${data[1].temp} °F with ${data[1].weather}
+
+ -
+ ${dates[2].toLocaleDateString()}: ${data[2].temp} °F with ${data[2].weather}
+
+ -
+ ${dates[3].toLocaleDateString()}: ${data[3].temp} °F with ${data[3].weather}
+
+ -
+ ${dates[4].toLocaleDateString()}: ${data[4].temp} °F with ${data[4].weather}
+
+
+
+
`,
+ };
+
+ await client.messages.create(process.env.MAILGUN_DOMAIN, msg);
+ console.log('completed mailgun send');
+}
+
+
+exports.handler = async () => {
+ const subsList = await subs.findAll({
+ where: {
+ type: 'weather',
+ },
+ include: [{
+ model: users,
+ required: true,
+ }],
+ });
+ console.log(subsList);
+
+ await Promise.allSettled(subsList.map(async sub => {
+ try {
+ console.log('THIS IS SUB -------------', sub.User.dataValues);
+ const { zip, email } = sub.User.dataValues;
+ const currentWeather = await getCurrentWeather(zip);
+ const forecast = await getForecast(zip);
+ await mailgunForecast(currentWeather, forecast, email);
+ console.log(`----- SUCCESS sending weather summary to ${email} -----`);
+ } catch(e) {
+ console.log(e.message);
+ }
+ }));
+ console.log(`----- SUCCESS -----`);
+
+};
diff --git a/events/package-lock.json b/events/package-lock.json
new file mode 100644
index 0000000..ba4d647
--- /dev/null
+++ b/events/package-lock.json
@@ -0,0 +1,500 @@
+{
+ "name": "events",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "events",
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "axios": "^1.2.1",
+ "dotenv": "^16.0.3",
+ "form-data": "^4.0.0",
+ "mailgun.js": "^8.0.6",
+ "pg": "^8.8.0",
+ "sequelize": "^6.28.0"
+ }
+ },
+ "node_modules/@types/debug": {
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz",
+ "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==",
+ "dependencies": {
+ "@types/ms": "*"
+ }
+ },
+ "node_modules/@types/ms": {
+ "version": "0.7.31",
+ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz",
+ "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
+ },
+ "node_modules/@types/node": {
+ "version": "18.11.18",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
+ "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA=="
+ },
+ "node_modules/@types/validator": {
+ "version": "13.7.10",
+ "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.10.tgz",
+ "integrity": "sha512-t1yxFAR2n0+VO6hd/FJ9F2uezAZVWHLmpmlJzm1eX03+H7+HsuTAp7L8QJs+2pQCfWkP1+EXsGK9Z9v7o/qPVQ=="
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ },
+ "node_modules/axios": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz",
+ "integrity": "sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==",
+ "dependencies": {
+ "follow-redirects": "^1.15.0",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/base-64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz",
+ "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg=="
+ },
+ "node_modules/buffer-writer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
+ "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "16.0.3",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
+ "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/dottie": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz",
+ "integrity": "sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg=="
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.2",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+ "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/inflection": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz",
+ "integrity": "sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==",
+ "engines": [
+ "node >= 0.4.0"
+ ]
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/mailgun.js": {
+ "version": "8.0.6",
+ "resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-8.0.6.tgz",
+ "integrity": "sha512-b+c7QO1T4oFsudEcRB2H7oZKth8ZDeYRW4xjW12QQVNYDSJCVxqSQfps6ofcH8fqcCMJdzc76HVNGdnUZgBPCw==",
+ "dependencies": {
+ "axios": "^0.27.2",
+ "base-64": "^1.0.0",
+ "url-join": "^4.0.1"
+ }
+ },
+ "node_modules/mailgun.js/node_modules/axios": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
+ "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
+ "dependencies": {
+ "follow-redirects": "^1.14.9",
+ "form-data": "^4.0.0"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/moment": {
+ "version": "2.29.4",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/moment-timezone": {
+ "version": "0.5.40",
+ "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.40.tgz",
+ "integrity": "sha512-tWfmNkRYmBkPJz5mr9GVDn9vRlVZOTe6yqY92rFxiOdWXbjaR0+9LwQnZGGuNR63X456NqmEkbskte8tWL5ePg==",
+ "dependencies": {
+ "moment": ">= 2.9.0"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "node_modules/packet-reader": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz",
+ "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ=="
+ },
+ "node_modules/pg": {
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/pg/-/pg-8.8.0.tgz",
+ "integrity": "sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==",
+ "dependencies": {
+ "buffer-writer": "2.0.0",
+ "packet-reader": "1.0.0",
+ "pg-connection-string": "^2.5.0",
+ "pg-pool": "^3.5.2",
+ "pg-protocol": "^1.5.0",
+ "pg-types": "^2.1.0",
+ "pgpass": "1.x"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ },
+ "peerDependencies": {
+ "pg-native": ">=3.0.1"
+ },
+ "peerDependenciesMeta": {
+ "pg-native": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/pg-connection-string": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz",
+ "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ=="
+ },
+ "node_modules/pg-int8": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
+ "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/pg-pool": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.2.tgz",
+ "integrity": "sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w==",
+ "peerDependencies": {
+ "pg": ">=8.0"
+ }
+ },
+ "node_modules/pg-protocol": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz",
+ "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ=="
+ },
+ "node_modules/pg-types": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
+ "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
+ "dependencies": {
+ "pg-int8": "1.0.1",
+ "postgres-array": "~2.0.0",
+ "postgres-bytea": "~1.0.0",
+ "postgres-date": "~1.0.4",
+ "postgres-interval": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pgpass": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
+ "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
+ "dependencies": {
+ "split2": "^4.1.0"
+ }
+ },
+ "node_modules/postgres-array": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
+ "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postgres-bytea": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
+ "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/postgres-date": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
+ "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/postgres-interval": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
+ "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
+ "dependencies": {
+ "xtend": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
+ "node_modules/retry-as-promised": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-7.0.3.tgz",
+ "integrity": "sha512-SEvMa4khHvpU/o6zgh7sK24qm6rxVgKnrSyzb5POeDvZx5N9Bf0s5sQsQ4Fl+HjRp0X+w2UzACGfUnXtx6cJ9Q=="
+ },
+ "node_modules/semver": {
+ "version": "7.3.8",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/sequelize": {
+ "version": "6.28.0",
+ "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.28.0.tgz",
+ "integrity": "sha512-+WHqvUQgTp19GLkt+gyQ+F6qg+FIEO2O5F9C0TOYV/PjZ2a/XwWvVkL1NCkS4VSIjVVvAUutiW6Wv9ofveGaVw==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/sequelize"
+ }
+ ],
+ "dependencies": {
+ "@types/debug": "^4.1.7",
+ "@types/validator": "^13.7.1",
+ "debug": "^4.3.3",
+ "dottie": "^2.0.2",
+ "inflection": "^1.13.2",
+ "lodash": "^4.17.21",
+ "moment": "^2.29.1",
+ "moment-timezone": "^0.5.34",
+ "pg-connection-string": "^2.5.0",
+ "retry-as-promised": "^7.0.3",
+ "semver": "^7.3.5",
+ "sequelize-pool": "^7.1.0",
+ "toposort-class": "^1.0.1",
+ "uuid": "^8.3.2",
+ "validator": "^13.7.0",
+ "wkx": "^0.5.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ibm_db": {
+ "optional": true
+ },
+ "mariadb": {
+ "optional": true
+ },
+ "mysql2": {
+ "optional": true
+ },
+ "oracledb": {
+ "optional": true
+ },
+ "pg": {
+ "optional": true
+ },
+ "pg-hstore": {
+ "optional": true
+ },
+ "snowflake-sdk": {
+ "optional": true
+ },
+ "sqlite3": {
+ "optional": true
+ },
+ "tedious": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/sequelize-pool": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz",
+ "integrity": "sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/split2": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz",
+ "integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==",
+ "engines": {
+ "node": ">= 10.x"
+ }
+ },
+ "node_modules/toposort-class": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz",
+ "integrity": "sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg=="
+ },
+ "node_modules/url-join": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
+ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA=="
+ },
+ "node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/validator": {
+ "version": "13.7.0",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz",
+ "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/wkx": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz",
+ "integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ }
+ }
+}
diff --git a/events/package.json b/events/package.json
new file mode 100644
index 0000000..d2988f7
--- /dev/null
+++ b/events/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "events",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "axios": "^1.2.1",
+ "dotenv": "^16.0.3",
+ "form-data": "^4.0.0",
+ "mailgun.js": "^8.0.6",
+ "pg": "^8.8.0",
+ "sequelize": "^6.28.0"
+ }
+}
diff --git a/eventsNotification.js b/eventsNotification.js
new file mode 100644
index 0000000..e69de29
diff --git a/external-api copy.js b/external-api copy.js
new file mode 100644
index 0000000..e9ecaaf
--- /dev/null
+++ b/external-api copy.js
@@ -0,0 +1,348 @@
+const router = require('express').Router();
+const axios = require('axios');
+const Mailgun = require('mailgun-js');
+
+require('dotenv').config();
+const mailgun = new Mailgun({
+ apiKey: process.env.MAILGUN_KEY,
+ domain: process.env.MAILGUN_DOMAIN,
+});
+
+const getForecast = socket => ( async () => {
+
+ let zip = '60513';
+
+ try {
+
+ const API_KEY = process.env.WEATHER_KEY;
+
+ let token = process.env.MAPBOX_TOKEN;
+
+
+ const latLon = await axios.get(`https://api.mapbox.com/geocoding/v5/mapbox.places/postcode/${zip}.json?access_token=${token}&country=us`);
+
+
+ let lat = latLon.data.features[0].center[1];
+ let lon = latLon.data.features[0].center[0];
+
+ const response = await axios.get(
+ `https://api.openweathermap.org/data/2.5/forecast?lat=${lat}&lon=${lon}&appid=${API_KEY}`,
+ );
+
+ const getForecastData = function (dayIndex) {
+ const forecast = response.data.list[dayIndex];
+ const weather = forecast.weather[0].description;
+ const temperature = forecast.main.temp;
+ const fahrenheit = (temperature - 273.15) * 9 / 5 + 32;
+ const fahrenheitRounded = Math.round(fahrenheit * 100) / 100;
+ const town = response.data.city.name;
+ return {
+ weather: weather,
+ temp: fahrenheitRounded,
+ city: town,
+ };
+ };
+
+ const forecastData1 = getForecastData(4);
+ const forecastData2 = getForecastData(12);
+ const forecastData3 = getForecastData(20);
+ const forecastData4 = getForecastData(28);
+ const forecastData5 = getForecastData(36);
+
+
+ const currentDate = new Date();
+ const forecastDates = [];
+
+ for (let i = 0; i < 5; i++) {
+ const forecastDate = new Date(currentDate);
+ forecastDate.setDate(currentDate.getDate() + i);
+ forecastDates.push(forecastDate);
+ }
+
+ console.log(response.data);
+
+
+
+ const msg = {
+ to: 'steveo732@gmail.com',
+ from: 'notifyme.us@gmail.com',
+ subject: 'Your 5 Day Weather Forecast',
+ text: `The weather forecast for the next 5 days in ${forecastData1.city} from NotifyMe-US:
+ ${forecastDates[0].toLocaleDateString()}: ${forecastData1.temp} °F with ${forecastData1.weather}
+ ${forecastDates[1].toLocaleDateString()}: ${forecastData2.temp} °F with ${forecastData2.weather}
+ ${forecastDates[2].toLocaleDateString()}: ${forecastData3.temp} °F with ${forecastData3.weather}
+ ${forecastDates[3].toLocaleDateString()}: ${forecastData4.temp} °F with ${forecastData4.weather}
+ ${forecastDates[4].toLocaleDateString()}: ${forecastData5.temp} °F with ${forecastData5.weather}
+ `,
+ html: `The weather forecast for the next 5 days in ${forecastData1.city} from NotifyMe-US:
+
+ -
+ ${forecastDates[0].toLocaleDateString()}: ${forecastData1.temp} °F with ${forecastData1.weather}
+ -
+ ${forecastDates[1].toLocaleDateString()}: ${forecastData2.temp} °F with ${forecastData2.weather}
+ -
+ ${forecastDates[2].toLocaleDateString()}: ${forecastData3.temp} °F with ${forecastData3.weather}
+ -
+ ${forecastDates[3].toLocaleDateString()}: ${forecastData4.temp} °F with ${forecastData4.weather}
+ -
+ ${forecastDates[4].toLocaleDateString()}: ${forecastData5.temp} °F with ${forecastData5.weather}
+
+
`,
+ };
+
+
+ mailgun.messages().send(msg, (error, body) => {
+ if (error) {
+ console.error(error);
+ socket.emit('API_ERROR', 'An error has occured with your request');
+ } else {
+ res.send({ message: 'Email sent successfully', msg });
+ console.log(msg.text);
+ }
+ });
+
+ } catch (error) {
+ console.error(error);
+ socket.emit('API_ERROR', 'An error has occured with your request');
+ }
+});
+
+
+const getWeather = socket => (async () => {
+
+ let zip = '60513';
+ try {
+
+ const API_KEY = process.env.WEATHER_KEY;
+ let token = process.env.MAPBOX_TOKEN;
+
+
+ const latLon = await axios.get(`https://api.mapbox.com/geocoding/v5/mapbox.places/postcode/${zip}.json?access_token=${token}&country=us`);
+
+
+ let lat = latLon.data.features[0].center[1];
+ let lon = latLon.data.features[0].center[0];
+
+ const response = await axios.get(
+ `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}`);
+
+
+ const forecast = response.data;
+ const weather = forecast.weather[0].description;
+ const temperatureHigh = forecast.main.temp_max;
+ const fahrenheitHigh = (temperatureHigh - 273.15) * 9 / 5 + 32;
+ const fahrenheitRoundedHigh = Math.round(fahrenheitHigh * 100) / 100;
+ const temperatureLow = forecast.main.temp_min;
+ const fahrenheitLow = (temperatureLow - 273.15) * 9 / 5 + 32;
+ const fahrenheitRoundedLow = Math.round(fahrenheitLow * 100) / 100;
+ const humidity = forecast.main.humidity;
+ const windspeed = forecast.wind.speed;
+ const windMph = windspeed * 2.236936;
+ const windMphFormatted = windMph.toFixed(2);
+ const cloudCoverage = forecast.clouds.all;
+ const town = forecast.name;
+
+ const msg = {
+ to: 'steveo732@gmail.com',
+ from: 'notifyme.us@gmail.com',
+ subject: 'Your Daily Weather Forecast',
+ text: `"Here is your custom weather forecast for today from NotifyMe-US:
+
+ The weather in ${town} is currently ${weather}. The high temperature for today will be ${fahrenheitRoundedHigh} degrees Fahrenheit, and the low temperature will be ${fahrenheitRoundedLow} degrees Fahrenheit. The humidity will be ${humidity}%, and the wind speed will be ${windMphFormatted} mph. There will be ${cloudCoverage}% cloud coverage."`,
+
+
+ html: `
+ Here is your custom weather forecast for today from NotifyMe-US::
+
+ -
+ The weather in ${town} is currently ${weather}. The high temperature for today will be ${fahrenheitRoundedHigh} degrees Fahrenheit, and the low temperature will be ${fahrenheitRoundedLow} degrees Fahrenheit.
+ -
+ The humidity will be ${humidity}%, and the wind speed will be ${windMphFormatted} mph. There will be ${cloudCoverage}% cloud coverage.
+
+
+ `,
+ };
+
+ mailgun.messages().send(msg, (error, body) => {
+ if (error) {
+ console.error(error);
+ socket.emit('API_ERROR', 'An error has occured with your request');
+ } else {
+ console.log(msg.text);
+
+ res.send({ message: 'Email sent successfully', msg });
+ }
+ });
+
+ } catch (error) {
+ console.error(error);
+ socket.emit('API_ERROR', 'An error has occured with your request');
+ }
+});
+
+
+const getDirections = socket => ( async () => {
+ let token = process.env.MAPBOX_TOKEN;
+
+ let addressOne = encodeURIComponent('4026 sunnyside ave 60513');
+ let addressTwo = encodeURIComponent('4255 N Knox Ave 60641');
+
+ try {
+
+ const latLonOne = await axios.get(`https://api.mapbox.com/geocoding/v5/mapbox.places/address/${addressOne}.json?types=address%2Cplace&access_token=${token}&country=us`);
+
+
+ const latLonTwo = await axios.get(`https://api.mapbox.com/geocoding/v5/mapbox.places/address/${addressTwo}.json?access_token=${token}&country=us`);
+
+
+ let addressOneCoor = latLonOne.data.features[0].center;
+ let addressTwoCoor = latLonTwo.data.features[0].center;
+
+ let coordinates = `${addressOneCoor[0]},${addressOneCoor[1]};${addressTwoCoor[0]},${addressTwoCoor[1]}`;
+
+
+ const response = await axios.get(`https://api.mapbox.com/directions/v5/mapbox/driving-traffic/${coordinates}?geometries=polyline&overview=simplified&steps=true&access_token=${token}`);
+
+ const directions = response.data;
+ const step = directions.routes[0].legs[0].steps;
+
+ const instructionsAndDistance = step.map(step => ({
+ instruction: step.maneuver.instruction,
+ distance: parseFloat((step.distance / 1609.344).toFixed(2)),
+ }));
+
+ const instructions = instructionsAndDistance.map(step => `${step.instruction} (${step.distance} miles)`).join('\n');
+ const distance = instructionsAndDistance.reduce((acc, step) => acc + step.distance, 0);
+ const roundedDistance = distance.toFixed(2);
+
+ const duration = Math.ceil(directions.routes[0].duration / 60);
+
+ const msg = {
+ to: 'steveo732@gmail.com',
+ from: 'notifyme.us@gmail.com',
+ subject: 'Your Daily Commute from NotifyMe-US',
+ text: `Your Daily Commute from NotifyMe-US for ${new Date().toLocaleDateString()}
+ Total distance: ${roundedDistance} miles
+ Total duration: ${duration} minutes,
+
+ Best Route:
+ ${instructions}`,
+
+ html: `Your Daily Commute from NotifyMe-US for ${new Date().toLocaleDateString()}
+ Total distance: ${roundedDistance} miles
+ Total duration: ${duration} minutes
+ Best Route:
+
+
+ ${instructionsAndDistance.map(step => `- ${step.instruction} (${step.distance} miles)
`).join('')}
+
+ `,
+
+ };
+
+
+
+ mailgun.messages().send(msg, (error, body) => {
+ if (error) {
+ console.error(error);
+ socket.emit('API_ERROR', 'An error has occured with your request');
+ } else {
+ console.log(msg.text);
+ res.send({ message: 'Email sent successfully', msg });
+
+ }
+ });
+ } catch (error) {
+ console.error(error);
+ socket.emit('API_ERROR', 'An error has occured with your request');
+ }
+});
+
+const getEvents = socket => ( async () => {
+ try {
+
+ const currentDate = new Date();
+ const startDateTime = currentDate.toISOString().slice(0, -5) + 'Z';
+
+ const endDateTime = new Date(currentDate.getTime() + 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, -5) + 'Z';
+ console.log(startDateTime);
+ console.log(endDateTime);
+
+
+ let apikey = process.env.TICKET_API;
+ let city = 'seattle';
+ let stateCode = 'wa';
+ let radius = '20';
+ let unit = 'miles';
+
+
+ const response = await axios.get(
+ `https://app.ticketmaster.com/discovery/v2/events.json?size=5&apikey=${apikey}&startDateTime=${startDateTime}&endDateTime=${endDateTime}&city=${city}&radius=${radius}&unit=${unit}&stateCode=${stateCode}`);
+
+ const concerts = response.data;
+
+
+ const toStandardTime = function (time) {
+
+ const [hours, minutes, seconds] = time.split(':');
+ let hoursFix = parseInt(hours, 10);
+ let minutesFix = parseInt(minutes, 10);
+ let secondsFix = parseInt(seconds, 10);
+
+ if (hoursFix >= 12) {
+
+ hoursFix -= 12;
+
+
+ time = `${hoursFix.toString().padStart(2, '0')}:${minutesFix
+ .toString()
+ .padStart(2, '0')}:${secondsFix.toString().padStart(2, '0')} PM`;
+ } else {
+
+ time = `${hoursFix.toString().padStart(2, '0')}:${minutesFix
+ .toString()
+ .padStart(2, '0')}:${secondsFix.toString().padStart(2, '0')} AM`;
+ }
+
+ return time;
+ };
+ let eventList = '';
+
+ for (let i = 0; i < 5; i++) {
+ const venueData = concerts._embedded.events[i];
+ const venue = venueData._embedded.venues[0].name;
+ const eventName = concerts._embedded.events[i].name;
+ const eventUrl = concerts._embedded.events[i].url;
+ const eventDate = concerts._embedded.events[i].dates;
+ const eventStartTime = eventDate.start.localTime;
+ const eventStartDate = eventDate.start.localDate;
+ const newTime = toStandardTime(eventStartTime);
+
+ eventList += `${eventName} at ${venue} on ${eventStartDate} at ${newTime}, Link: ${eventUrl}`;
+ }
+
+ const msg = {
+ to: 'steveo732@gmail.com',
+ from: 'notifyme.us@gmail.com',
+ subject: 'Check Out These 5 events happening this week!',
+ text: `Five Upcoming Events in your Area: ${eventList}`,
+ html: `Five Upcoming Events in your Area:
+ `,
+ };
+
+ mailgun.messages().send(msg, (error, body) => {
+ if (error) {
+ console.error(error);
+ socket.emit('API_ERROR', 'An error has occured with your request');
+ } else {
+ console.log(msg.text);
+ socket.emit('API_RESULT', 'success'); // TODO - replace 'success' with actual api result
+ }
+ });
+ } catch (error) {
+ console.error(error);
+ socket.emit('API_ERROR', 'An error has occured with your request');
+ }
+});
diff --git a/weather/.DS_Store b/weather/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..a3c6fd6c913e21efa8d2ed921b665baa78f5e746
GIT binary patch
literal 6148
zcmeHKJ5B>J5S@V(D?yQx(pSg@kcpNPMAV?L5fr;@q$s^RYA%8}1O->%B(%KwfU;s0
z2?~VJjAXyDJu{wt(%K#(;`z3j5lxAxLK9?BMntAZmk!)`0%VPGNgegn(3aYfK!0&c
zazCa!&3Z+<`LAfx-pm%)eYcjx`Sj^xpKaII^|I}ku&Ey2>eu_n=d=Cx&A05=w>!DK
z6od{527-ZLAQ%V+e#8LoY?127F#2F17zhSF8IbcKp$TTkVyH(4IxPW!@{Cr2F13XC
zB**Mn46y=Xa|N0!dx^p3j``$v*|8X!JFyoZ>^pxHFRZ&Geo}MdY#4no5DW|%IJDtZ
z?*DWAGNVQQ&?QE}Krryn7~o00sOR`7zgxe2p4_zw?Fvmq?20H5=z~W926B#^=%TGB
a(P5Vzi=jl3d36WILqG|ME*SU)2HpY1BRP@)
literal 0
HcmV?d00001
diff --git a/weather/.env.sample b/weather/.env.sample
new file mode 100644
index 0000000..2d2c206
--- /dev/null
+++ b/weather/.env.sample
@@ -0,0 +1,9 @@
+DATABASE_URL=postgres://localhost:5432/
+
+MAILGUN_KEY=
+
+MAILGUN_DOMAIN=
+
+WEATHER_KEY=
+
+MAPBOX_TOKEN=
diff --git a/weather/Archive.zip b/weather/Archive.zip
new file mode 100644
index 0000000000000000000000000000000000000000..916cb658dc900a98e35425eaa93603d93b1ddd6b
GIT binary patch
literal 5597435
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
z