Skip to content

Commit

Permalink
✨ Enable responses endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
birdcar committed May 10, 2019
1 parent 2e299a3 commit 6713cc2
Show file tree
Hide file tree
Showing 6 changed files with 269 additions and 42 deletions.
68 changes: 50 additions & 18 deletions controllers/responses.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,21 @@
//Dependencies
const router = require("express").Router();

// Mail parsing
const simpleParser = require("mailparser").simpleParser;
const multer = require("multer");
const upload = multer();
const moment = require("moment");

//Models
const Responses = require("../models/db/responses");
const Notifications = require("../models/db/notifications");

//data validation
const { responseSchema } = require("../models/schemas");
const validation = require("../middleware/dataValidation");

router.route("/").post(validation(responseSchema), async (req, res) => {
// we have a ref to the notification thread being sent with the post request, but not a notification_id
const { thread, ...rest } = req.body;

// use that thread to find the notification and grab its id
const { id } = await Notifications.find({ "n.thread": thread }).first();
// Authentication & validation
const { authentication } = require("../middleware/authentication");

//create a response body and pass in everything from req.body EXCEPT the thread (invalid property for response)
//and make the found id the notification_id
const responseBody = { ...rest, notification_id: id };
const newResponse = await Responses.add(responseBody);
return res.status(201).json({ newResponse });
});

router
.route("/:id")
router.route(authentication, "/:id")
.get(async (req, res) => {
const { id } = req.params;
const response = await Responses.find({ "r.id": id }).first();
Expand All @@ -44,4 +35,45 @@ router
: res.status(404).json({ message: "The resource could not be found." });
});

router.route("/email")
.post(upload.none(), async (req, res) => {
// Parse the raw email from req.body using multer and simpleParser
const { email } = req.body;
const { text, headerLines } = await simpleParser(email);

// Get the unique thread identifier (the To email address)
const thread = headerLines
.filter(h => h.key === "to")[0]
.line.replace("<", "")
.replace(">", "")
.replace("To: Training Bot ", "");

// use that thread identifier to find the notification and grab its id
const { id } = await Notifications.find({ "n.thread": thread }).first();

// Pull the date off the header to split the new body text from
// the rest of the thread. Format it with moment to match email
// formatting
const dateString = headerLines
.filter(h => h.key === "date")[0]
.line.replace("Date: ", "");
const formatDate = moment(dateString).format("ddd, MMMM D, YYYY");

// get the body text by spliting on the common RE footer and
// then grabbing the first item in that new array
const body = text.split(`On ${formatDate}\n\n`)[0];

// build a response object with the thread and the body
const resObject = {
body,
notification_id: id
};

// Add the newResponse object to the responses table
const newResponse = await Responses.add(resObject);

// Return 204 and no content (since I'm responding to a webhook)
return res.status(204).end();
});

module.exports = router;
15 changes: 7 additions & 8 deletions jobs/notifications/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const CronJob = require("cron").CronJob;
const notify = require('./lib/notify');
const wipeFailed = require('./lib/wipeFailed')
const notify = require("./lib/notify");
const wipeFailed = require("./lib/wipeFailed");

// node-cron start function for notification system
const notificationSystem = function() {
Expand All @@ -20,21 +20,20 @@ const notificationSystem = function() {
},
async function(time) {
try {
await wipeFailed(time)
}
catch (error) {
await wipeFailed(time);
} catch (error) {
console.error(
"There was an error removing outdated notifications",
"There was an error removing outdated notifications",
error
)
);
}
},
true,
"UTC"
);
console.log("Notification System Instantiation");
console.log(new Date());
},
}
};
};

Expand Down
2 changes: 1 addition & 1 deletion jobs/notifications/lib/senders/email.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module.exports = n => {
})
.then(_ => ({
id: n.id,
thread: n.thread,
thread,
num_attempts: n.num_attempts + 1,
is_sent: true
}));
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@
"jwks-rsa": "^1.4.0",
"jwt-decode": "^2.2.0",
"knex": "^0.16.5",
"mailparser": "^2.7.1",
"moment": "^2.24.0",
"multer": "^1.4.1",
"pg": "^7.10.0",
"pm2": "^3.5.0",
"sqlite3": "^4.0.6",
Expand Down
15 changes: 5 additions & 10 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//Dependencies
const express = require("express"),
helmet = require("helmet"),
cors = require("cors");
const express = require("express");
const helmet = require("helmet");
const cors = require("cors");

//Server to point to
const server = express();
Expand All @@ -10,11 +10,6 @@ const server = express();
server.use(
helmet(),
express.json(),
express.urlencoded({
extended: true,
type: "multipart/form-data",
limit: "10mb"
}),
cors()
);

Expand Down Expand Up @@ -45,7 +40,7 @@ server.use("/api/messages", authentication, messageRouter);
server.use("/api/stripe", stripeRouter);
server.use("/api/slack", slackRouter);
server.use("/api/notifications", authentication, notificationsRouter);
server.use("/api/responses", authentication, responsesRouter);
server.use("/api/responses", responsesRouter);

//Default Endpoints
server.get("/", (req, res) => {
Expand All @@ -55,6 +50,6 @@ server.get("/", (req, res) => {
//async error handling middleware MUST come after routes or else will just throw Type error
server.use(errorHandler);

notificationSystem.start();
// notificationSystem.start();

module.exports = server;
Loading

0 comments on commit 6713cc2

Please sign in to comment.