This document presents information relevant to people who want to contribute code. Please read first CONTRIBUTING document for general guidelines.
This project is made using Node JS. A Dockerfile is provided with the required environment. But a traditional environment installation can be used too.
-
https://prettier.io/ for automatic code formatting.
-
https://standardjs.com/ for code linting.
-
https://jestjs.io/ for testing.
-
https://github.com/developit/microbundle for bundling.
-
https://en.wikipedia.org/wiki/Makefile for centralized command runner.
-
https://asciidoc.org/ for docs.
-
https://git-scm.com/ for version control.
-
https://github.com/commitizen/cz-cli for standarized commit messages.
-
https://yarnpkg.com/ preferred package manager.
-
(optional) https://www.docker.com/ for node env.
You can use any editor that supports .editorconfig files.
Recommendations:
This codebase tries to follow Domain Driven Design practices and SOLID principles.
The main domains are:
-
parsers
: Parse email’s content with specific regex rules. -
actions
: Refers to some action to take after parsing emails (Ex: Save to Spreadsheet).
This directory contains the different actions
and parsers
. These are the important domains:
-
country
: Directory that holds different entities specific to a country. This is because the same entity (Ex: "Netflix") could have different email formats depending on the country of the customer. Country names should be in lowercase and in USA english. No spaces (use dash to separate words). -
any
: Directory refers toactions
andparsers
that could be applied to any country/entity.actions
will be applied on every email found. -
entity
: Directory that containsactions
andparsers
specific to the entity. An entity could be any organization. Example banks, subscription services and other money related emails.actions
will only be applied to emails related to this entity.
Example Structure
$ tree -L 6 plugins
plugins
├── any
│ ├── actions
│ │ ├── index.js
│ │ └── spreadsheet
│ │ ├── Constants.js
│ │ ├── SpreadSheetAction.js
│ │ └── index.js
│ ├── index.js
│ └── parsers
│ └── index.js
├── chile # country
│ ├── currencies
│ │ ├── CLP.js
│ │ └── index.js
│ ├── entities
│ │ ├── bancoestado # entity
│ │ │ ├── README.adoc
│ │ │ ├── actions
│ │ │ │ └── index.js
│ │ │ ├── index.js
│ │ │ ├── parsers
│ │ │ │ ├── BancoEstadoPurchaseNotificationParser.js
│ │ │ │ ├── BaseBancoEstadoParser.js
│ │ │ │ └── index.js
│ │ │ └── test
│ │ │ └── BancoEstadoPurchaseNotificationParser.test.js
│ │ └── index.js
│ └── index.js
└── index.js
This directory contains the core functionality and base classes. It should not be needed to modify this if you want to build a custom version. Only savvy developers should modify files here.
Example Structure
$ tree -L 4 lib
lib
├── Config.js
├── Constants.js
├── Email.js
├── actions
│ ├── BaseAction.js
│ ├── README.adoc
│ └── index.js
├── currencies
│ ├── BaseCurrency.js
│ └── index.js
├── parsers
│ ├── BaseParser.js
│ ├── Formatters.js
│ ├── README.adoc
│ ├── Types.js
│ ├── Validators.js
│ └── index.js
└── test
└── makeEmail.js
The Makefile is used for command standarization.
Contains all the available actions for emails. Actions can be run for each email found (any directory) or specifically for each entity (country/entity/actions directory). It’s recommended to select only the ones you will actually use. To have a more slim script. These actions will be executed in left to right order.
import SpreadSheetAction from "./SpreadSheetAction";
export default [SpreadSheetAction];
-
SpreadSheetAction.js: Save data to a specific Google Spreadsheet.
-
HttpAction: Call an http endpoint with the parsed data.
This directory contains all the available parsers for emails. It’s recommended to select only the ones you will actually use. To have a more slim script.
import BancoEstado from "./BancoEstado";
export default [BancoEstado];
Each parser will have a designated label that you must configure first in your Gmail account (using a filter) This is the way to determine which parser will be used to extract the data.
It’s recommended to use a parent label named biyete
to organize better your emails and labels related to biyete.
-
expense: money out.
-
deposit: money in.
-
alert: some payment or another money related action will be done in the future.
-
other: misc.
The parser should return an object with the following properties.
{
amount: 0, // The amount inside the email content.
context: '', // Normally the store, the person, or similar info to give context to the transaction.
account: '', // Associated card number, user account or any other info from wich the transaction took place.
date: {
formatter: {}, // DayJS object or similar date formatter
raw: '' // Raw date string
},
name: this.name, // Parser Name.
type: this.type, // Parser type expense, deposit, alert, other.
label: this.label, // Parser label.
entity: this.entity, // Which bank or entity processed the email.
currency: this.currency, // Currency associated with the ammount.
meta: {}, // Any other info not fit in the previous properties.
comment: '', // Additional comment.
createdAt: createdAt || new Date(), // When this was processed.
version: this.version,
parsed: false // tells if the parse was successful
}
The first thing you need is the base text of the email. Is recommended to obtain a text representation of the email. You could use "Show Original" option to open a text only representation. Using that you could create a regular expression to parse the data. Is recommended to use https://regex101.com/ for testing your regex.