Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/ticket email #313

Merged
merged 11 commits into from
Jan 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"this":false,
"bad_property":false
},
"search.usePCRE2": true
"search.usePCRE2": true,
"editor.formatOnSave": true
}
1 change: 1 addition & 0 deletions assets/email/Ticket.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div>{{firstName}}<img src="{{ticket}}"></img></div>
5 changes: 5 additions & 0 deletions constants/general.constant.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ const ANY_REGEX = /^.+$/;

const MAX_TEAM_SIZE = 4;

const WEEK_OF = 'Week Of';

const EMAIL_SUBJECTS = {};
EMAIL_SUBJECTS[HACKER_STATUS_NONE] = `Application for ${HACKATHON_NAME} incomplete`;
EMAIL_SUBJECTS[HACKER_STATUS_APPLIED] = `Thanks for applying to ${HACKATHON_NAME}`;
Expand All @@ -98,6 +100,8 @@ EMAIL_SUBJECTS[HACKER_STATUS_CONFIRMED] = `Thanks for confirming your attendance
EMAIL_SUBJECTS[HACKER_STATUS_CANCELLED] = "Sorry to see you go";
EMAIL_SUBJECTS[HACKER_STATUS_CHECKED_IN] = `Welcome to ${HACKATHON_NAME}`;

EMAIL_SUBJECTS[WEEK_OF] = `Welcome to ${HACKATHON_NAME}`;

const CONFIRM_ACC_EMAIL_SUBJECT = `Please complete your hacker application for ${HACKATHON_NAME}`;
const CREATE_ACC_EMAIL_SUBJECTS = {};
CREATE_ACC_EMAIL_SUBJECTS[HACKER] = `You've been invited to create a hacker account for ${HACKATHON_NAME}`;
Expand Down Expand Up @@ -145,5 +149,6 @@ module.exports = {
CACHE_TIMEOUT_STATS: CACHE_TIMEOUT_STATS,
CACHE_KEY_STATS: CACHE_KEY_STATS,
MAX_TEAM_SIZE: MAX_TEAM_SIZE,
WEEK_OF: WEEK_OF,
SAMPLE_DIET_RESTRICTIONS: SAMPLE_DIET_RESTRICTIONS,
};
8 changes: 8 additions & 0 deletions constants/routes.constant.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@ const hackerRoutes = {
requestType: Constants.REQUEST_TYPES.PATCH,
uri: "/api/hacker/confirmation/" + Constants.ROLE_CATEGORIES.SELF,
},
"postAnySendWeekOfEmail": {
requestType: Constants.REQUEST_TYPES.POST,
uri: "/api/hacker/email/weekOf/" + Constants.ROLE_CATEGORIES.ALL,
},
"postSelfSendWeekOfEmail": {
requestType: Constants.REQUEST_TYPES.POST,
uri: "/api/hacker/email/weekOf/" + Constants.ROLE_CATEGORIES.SELF,
},
};

const sponsorRoutes = {
Expand Down
3 changes: 3 additions & 0 deletions constants/success.constant.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const HACKER_GET_BY_ID = "Hacker found by id.";
const HACKER_READ = "Hacker retrieval successful.";
const HACKER_CREATE = "Hacker creation successful.";
const HACKER_UPDATE = "Hacker update successful.";
const HACKER_SENT_WEEK_OF = "Hacker week-of email sent."

const RESUME_UPLOAD = "Resume upload successful.";
const RESUME_DOWNLOAD = "Resume download successful.";
Expand Down Expand Up @@ -67,6 +68,8 @@ module.exports = {
HACKER_CREATE: HACKER_CREATE,
HACKER_UPDATE: HACKER_UPDATE,

HACKER_SENT_WEEK_OF: HACKER_SENT_WEEK_OF,

RESUME_UPLOAD: RESUME_UPLOAD,
RESUME_DOWNLOAD: RESUME_DOWNLOAD,

Expand Down
8 changes: 8 additions & 0 deletions controllers/hacker.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,19 @@ function gotStats(req, res) {

}

function sentWeekOfEmail(req, res) {
return res.status(200).json({
message: Constants.Success.HACKER_SENT_WEEK_OF,
data: {}
});
}

module.exports = {
updatedHacker: updatedHacker,
createdHacker: createdHacker,
uploadedResume: uploadedResume,
downloadedResume: downloadedResume,
showHacker: showHacker,
gotStats: gotStats,
sentWeekOfEmail: sentWeekOfEmail,
};
52 changes: 52 additions & 0 deletions docs/api/api_data.js
Original file line number Diff line number Diff line change
Expand Up @@ -1869,6 +1869,58 @@ define({
"url": "https://api.mchacks.ca/api/hacker/resume/:id"
}]
},
{
"type": "post",
"url": "/hacker/email/weekOf/:id",
"title": "",
"description": "<p>Sends a hacker the week-of email, along with the HackPass QR code to view their hacker profile (for checkin purposes). Hackers must be eitherconfirmed, or checked in.</p>",
"name": "postHackerSendWeekOfEmail",
"group": "Hacker",
"version": "0.0.9",
"parameter": {
"fields": {
"param": [{
"group": "param",
"type": "string",
"optional": true,
"field": "status",
"description": "<p>The hacker ID</p>"
}]
}
},
"success": {
"fields": {
"Success 200": [{
"group": "Success 200",
"type": "string",
"optional": false,
"field": "message",
"description": "<p>Success message</p>"
},
{
"group": "Success 200",
"type": "object",
"optional": false,
"field": "data",
"description": "<p>empty</p>"
}
]
},
"examples": [{
"title": "Success-Response: ",
"content": "{\n \"message\": \"Hacker week-of email sent.\", \n \"data\": {}\n}",
"type": "object"
}]
},
"permission": [{
"name": "Administrator"
}],
"filename": "routes/api/hacker.js",
"groupTitle": "Hacker",
"sampleRequest": [{
"url": "https://api.mchacks.ca/api/hacker/email/weekOf/:id"
}]
},
{
"type": "get",
"url": "/sponsor/self",
Expand Down
52 changes: 52 additions & 0 deletions docs/api/api_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -1868,6 +1868,58 @@
"url": "https://api.mchacks.ca/api/hacker/resume/:id"
}]
},
{
"type": "post",
"url": "/hacker/email/weekOf/:id",
"title": "",
"description": "<p>Sends a hacker the week-of email, along with the HackPass QR code to view their hacker profile (for checkin purposes). Hackers must be eitherconfirmed, or checked in.</p>",
"name": "postHackerSendWeekOfEmail",
"group": "Hacker",
"version": "0.0.9",
"parameter": {
"fields": {
"param": [{
"group": "param",
"type": "string",
"optional": true,
"field": "status",
"description": "<p>The hacker ID</p>"
}]
}
},
"success": {
"fields": {
"Success 200": [{
"group": "Success 200",
"type": "string",
"optional": false,
"field": "message",
"description": "<p>Success message</p>"
},
{
"group": "Success 200",
"type": "object",
"optional": false,
"field": "data",
"description": "<p>empty</p>"
}
]
},
"examples": [{
"title": "Success-Response: ",
"content": "{\n \"message\": \"Hacker week-of email sent.\", \n \"data\": {}\n}",
"type": "object"
}]
},
"permission": [{
"name": "Administrator"
}],
"filename": "routes/api/hacker.js",
"groupTitle": "Hacker",
"sampleRequest": [{
"url": "https://api.mchacks.ca/api/hacker/email/weekOf/:id"
}]
},
{
"type": "get",
"url": "/sponsor/self",
Expand Down
2 changes: 1 addition & 1 deletion docs/api/api_project.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ define({
"apidoc": "0.3.0",
"generator": {
"name": "apidoc",
"time": "2019-01-21T04:13:36.482Z",
"time": "2019-01-23T23:37:14.991Z",
"url": "http://apidocjs.com",
"version": "0.17.7"
}
Expand Down
2 changes: 1 addition & 1 deletion docs/api/api_project.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"apidoc": "0.3.0",
"generator": {
"name": "apidoc",
"time": "2019-01-21T04:13:36.482Z",
"time": "2019-01-23T23:37:14.991Z",
"url": "http://apidocjs.com",
"version": "0.17.7"
}
Expand Down
25 changes: 25 additions & 0 deletions middlewares/hacker.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const Services = {
Storage: require("../services/storage.service"),
Email: require("../services/email.service"),
Account: require("../services/account.service"),
Env: require("../services/env.service"),
};
const Middleware = {
Util: require("./util.middleware")
Expand Down Expand Up @@ -308,6 +309,29 @@ async function sendAppliedStatusEmail(req, res, next) {
Services.Email.sendStatusUpdate(account.firstName, account.email, Constants.General.HACKER_STATUS_APPLIED, next);
}

/**
* Sends an email telling the user that they have applied. This is used exclusively when we POST a hacker.
* @param {{body: {hacker: {accountId: string}}}} req
* @param {*} res
* @param {(err?:*)=>void} next
*/
async function sendTicketEmail(req, res, next) {
const hacker = req.body.hacker;
const address = Services.Env.isProduction() ? process.env.FRONTEND_ADDRESS_DEPLOY : process.env.FRONTEND_ADDRESS_DEV;
const httpOrHttps = (address.includes("localhost")) ? "http" : "https";
const singleHackerViewLink = Services.Hacker.generateHackerViewLink(httpOrHttps, address, hacker._id.toString());
const ticketSVG = await Services.Hacker.generateQRCode(singleHackerViewLink);
const account = await Services.Account.findById(hacker.accountId);
if (!account || !ticketSVG) {
return next({
status: 500,
message: Constants.Error.GENERIC_500_MESSAGE,
error: {}
});
}
Services.Email.sendTicketEmail(account.firstName, account.email, ticketSVG, next);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was there a reason to use callbacks here instead of await/async? It would be nice for our services to be consistent.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The email library we use doesn’t support async / await, so back when I first created the service, I followed the library’s standards. I can try promisifying it and see what happens then.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see - unfortunate

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah :’(

}

/**
* If the current hacker's status is Constants.HACKER_STATUS_NONE, and the hacker's application is completed,
* then it will change the status of the hacker to Constants.General.HACKER_STATUS_APPLIED, and then email the hacker to
Expand Down Expand Up @@ -520,6 +544,7 @@ module.exports = {
ensureAccountLinkedToHacker: ensureAccountLinkedToHacker,
uploadResume: Middleware.Util.asyncMiddleware(uploadResume),
downloadResume: Middleware.Util.asyncMiddleware(downloadResume),
sendTicketEmail: Middleware.Util.asyncMiddleware(sendTicketEmail),
sendStatusUpdateEmail: Middleware.Util.asyncMiddleware(sendStatusUpdateEmail),
sendAppliedStatusEmail: Middleware.Util.asyncMiddleware(sendAppliedStatusEmail),
updateHacker: Middleware.Util.asyncMiddleware(updateHacker),
Expand Down
Loading