Refactor to a clean separation of concerns

I've made use of promises to simplify error handling and clean up
the code. Overall, there are more lines now, but this is mostly because
of my heavy commenting.

I brought in dotenv as well. I'm not sure how @x was managing environment variables, but this seemed to be a sane way to go about it.

It might be easier to understand the changes by looking at the actual code in the branch rather than the diff, since so much has changed.