patternjavascriptMinor
Node bot to send out reminder emails for forgotten employee weekly schedule submissions
Viewed 0 times
employeenodeforgottenbotforemailsweeklysubmissionssendout
Problem
This
I'm interested in feedback, what I could simplify, where are the code smells, etc.
index.js
```
import CalendarService from './calendarService';
import MailService from './mailService';
import TeamService from './teamService';
const mailService = new MailService();
const calendarService = new CalendarService();
const teamService = new TeamService();
console.log('Loading calendar credentials…');
calendarService.loadCredentials()
.then((credentials) => {
console.log('✓ Credentials loaded');
console.log('------------------------------------------');
console.log('Authorizing with Google API…');
return calendarService.authorize(credentials);
})
.then(() => {
console.log('✓ Google API authorized');
console.log('------------------------------------------');
console.log('Fetching calendar events for current week…');
return calendarService.listEventsForUpcomingWeek();
})
.then((events) => {
console.log('✓ Events fetched');
console.log('------------------------------------------');
console.log('Identifying missing dates…');
const missingDatesPerTeamMember = [];
teamService.getTeam().forEach((teamMember) => {
const teamMemberEvents = events.filter((event) => event.creator.email === teamMember.email);
const missingDates = calendarService.identifyMissingDates(teamMemberEvents);
if (missingDates.length) {
missingDatesPerTeamMember.push({ teamMember: teamMember, missingDates: missingDates });
}
});
return missingDatesPerTeamMember;
})
.then((missingDates) => {
console.log('✓ Missing dates identified');
console.log('------------------------------------------');
console.log('Sending out emails to team members with missing dates…');
return mailService.sendEmailsToTeamMembersWithMissingDates(missingDates);
})
CalendarService is part of a little node-bot I wrote today which sends out reminder-emails if a team member forgets to submit his weekly schedule in time. Calendar backend is using Google Calendar.I'm interested in feedback, what I could simplify, where are the code smells, etc.
index.js
```
import CalendarService from './calendarService';
import MailService from './mailService';
import TeamService from './teamService';
const mailService = new MailService();
const calendarService = new CalendarService();
const teamService = new TeamService();
console.log('Loading calendar credentials…');
calendarService.loadCredentials()
.then((credentials) => {
console.log('✓ Credentials loaded');
console.log('------------------------------------------');
console.log('Authorizing with Google API…');
return calendarService.authorize(credentials);
})
.then(() => {
console.log('✓ Google API authorized');
console.log('------------------------------------------');
console.log('Fetching calendar events for current week…');
return calendarService.listEventsForUpcomingWeek();
})
.then((events) => {
console.log('✓ Events fetched');
console.log('------------------------------------------');
console.log('Identifying missing dates…');
const missingDatesPerTeamMember = [];
teamService.getTeam().forEach((teamMember) => {
const teamMemberEvents = events.filter((event) => event.creator.email === teamMember.email);
const missingDates = calendarService.identifyMissingDates(teamMemberEvents);
if (missingDates.length) {
missingDatesPerTeamMember.push({ teamMember: teamMember, missingDates: missingDates });
}
});
return missingDatesPerTeamMember;
})
.then((missingDates) => {
console.log('✓ Missing dates identified');
console.log('------------------------------------------');
console.log('Sending out emails to team members with missing dates…');
return mailService.sendEmailsToTeamMembersWithMissingDates(missingDates);
})
Solution
A few things I can spot, in no particular order:
- As Dan Pantry suggested, it's probably better if you precompile your files using babel (i.e. add a build step) and run it normally with node. Normally there wouldn't be an issue, but if run in a cron multiple times, the penalty can stack up.
- DRY:
const cl = console.log.bind(console)
- In some of the cases, you're using the normal version (
readFile()and in some, you're using the sync version (readFileSync()), in a CLI, there's nothing wrong with using sync operations. But pick one and stay consistent.
- Always
reject()with an instance ofError. Just like you should alwaysthrowand instance ofError.
- Don't nest
.then()inside of a Promise constructor or other.then()s. Chain promises by returning. (i.e.new Promise(...).then()and notnew Promise(... .then() ...)).
- Be consistent with your naming convention. I sometimes see
errorand sometimeserr.
- Have a look into
asyncfunctions andawait.
- If you only have one statement, an arrow function can be shortened from
(param) => { return doSomethingWith(param); }to(param) => doSomethingWith(param);toparam => doSomethingWith(param);.
- Promise constructors should generally be used at the lowest possible level. Promisify all of the callback-based functions, and construct functions on top of those Promise-returning functions.
class Foo {} export default Foocan be shortened toexport default class Foo {}.
{foo: foo, bar: bar}can be shortened to{foo, bar}.
- Your
storeToken()method has absolutely no guarantee of success. (writeFileis async, and you're returning before it's done, you don't know if it failed or not).
- Stay consistent with your object key naming and quoting.
Context
StackExchange Code Review Q#111789, answer score: 2
Revisions (0)
No revisions yet.