HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Node bot to send out reminder emails for forgotten employee weekly schedule submissions

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
employeenodeforgottenbotforemailsweeklysubmissionssendout

Problem

This 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 of Error. Just like you should always throw and instance of Error.



  • Don't nest .then() inside of a Promise constructor or other .then()s. Chain promises by returning. (i.e. new Promise(...).then() and not new Promise(... .then() ...)).



  • Be consistent with your naming convention. I sometimes see error and sometimes err.



  • Have a look into async functions and await.



  • If you only have one statement, an arrow function can be shortened from (param) => { return doSomethingWith(param); } to (param) => doSomethingWith(param); to param => 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 Foo can be shortened to export default class Foo {}.



  • {foo: foo, bar: bar} can be shortened to {foo, bar}.



  • Your storeToken() method has absolutely no guarantee of success. (writeFile is 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.