= Lettersnail Clemens Fries :source-highlighter: pygments :toc: left :lettersnail-ini: lettersnail.ini :lettersnail-base: lettersnail :version: 0.0.1 lettersnail v{version} — a simple email notification helper. IMPORTANT: This program is in development and might have some rough edges. The documentation on `master` should still accurately reflect the current state of the program. == What is `lettersnail`? `lettersnail` is a “note to my future self” email notification tool. You write a simple text file, with some metadata, and it will, upon invocation, send a message when the time has come. .Example message ---- to: me@example.com subject: Watch Halley's Comet date: 2061-07-28 Greetings! Go outside at night, if the curfew of the – highly welcomed — alien overlords permits, and watch Halley's Comet. ---- === Motivation I needed a fairly simple tool to send some one-off reminders to myself, and possibly to others. Plus, I wanted the messages to live in my home directory, so I would not forget them if I move to another server. You could realize most of this with `atd`, but it is a bit clumsy if want to quickly write a message, plus I'd totally forget to copy `/var/spool/at`. `lettersnail` is not meant to be a daemon. It should be executed regularly by a cron job or other method. For the `date` parameter it also supports having a specific time, which acts as a “not before” constraint. If you run your cron job often enough (for example: every five minutes) the message will, of course, be sent very close to the given time. == Quick Start === Building In order to check out and build the project in its own directory in `/tmp`, write the following: [source,shell] ---- cd $(mktemp -d) git clone http://github.com/githubert/lettersnail go build ---- === Running Create `.config/{lettersnail-ini}`: [source,ini] ---- [default] server = smtp.example.com user = me password = aengeequ6xeiseoY from = me@example.com ---- Create a new message: ---- lettersnail create --to me@example.com ---- Add a cron job: ---- 0 6 * * * /path/to/lettersnail run ---- List messages due in the next days: ---- lettersnail next ---- Run manually: ---- lettersnail run ---- == Quick Start Walkthrough Create a file `.config/{lettersnail-ini}` and provide a server, credentials and a from address: [source,ini] ---- [default] server = smtp.example.com user = me password = aengeequ6xeiseoY from = me@example.com ---- NOTE: `port` defaults to `587`. If it doesn't work, try setting `port` to `25`. Now ready some message to yourself: ---- lettersnail create --to me@example.com ---- This will open a new file using the editor set in the `VISUAL` environment variable, or if no editor is set, it will default to `vi`. Fill in `date` in the format `YYYY-mm-dd` (for example `date: 2016-01-01`) and add a meaningful `subject`. Add a blank line between the configuration in the header and your message's body. Save and exit the editor. `lettersnail` will ask you what to do. Press `ENTER` to save the message to the `{lettersnail-base}/todo` folder. If you set `date` to today's date you can test if everything works. First check if everything is okay by running `lettersnail check`, if it reports no errors, you can see with `lettersnail next` if the message is scheduled for being sent out in the next seven days. Finally, if you type `lettersnail run`, it will deliver all messages that were due. As `lettersnail` is not a daemon, you should run it daily by adding it as a cron job. Type `crontab -e` and add a entry to run the command every day at 6 in the morning: ---- 0 6 * * * /path/to/lettersnail run ---- == Folder structure The default working directory is `lettersnail`, located in the user's home directory. There are several folders created beneath it, when the program is invoked. ---- lettersnail/ todo/ done/ errors/ drafts/ ---- `todo/` is the message queue. All `.msg` files in that folder are considered when running `lettersnail run`. `done/` contains all messages that were successfully delivered. For every message there is also a corresponding `.log` file. `errors/` contains all messages that could not be delivered. For every message there is also a corresponding `.log` file. `drafts/` contains messages that can be used with `lettersnail create --draft FILENAME`. Additionally, messages in this folder will also be checked with `lettersnail check`. == Global Settings File `.config/{lettersnail-ini}` Global settings can be put into the optional file `.config/{lettersnail-ini}`. All _global_ settings can also be overridden on the command line. `.config/{lettersnail-ini}` is a simple ini-style settings file with a `default` section, plus optional sections for every command, in order to overrule the settings in the `default` section. .Example file [source,ini] ---- [default] workdir = ~/lettersnail server = smtp.example.com port = 587 from = me@example.com [run] bcc = me@example.com ---- === Settings NOTE: Empty values are valid and mean that a setting has been un-set. ==== Global and Command Line workdir:: The working directory, defaults to `~/lettersnail`. server:: Address of the SMTP server. Defaults to `localhost`. port:: Port of the SMTP server. Defaults to the SMTP submission port `587`. not-before:: Do not sent messages before the specified time. (`00:00` until `not-before`) not-after:: Do not sent messages after the specified time. (`not-after` until `23:59`) TODO: not-after / not-before warrant some better explanation Priority of these is as follows `command line > global`. ==== Global, Command Line and as Configuration These parameters are valid everywhere and may also be included in the configuration part of a message. NOTE: `date` is not allowed anywhere except in the message configuration. from:: `from` as in <> to:: `to` as in <> cc:: `cc` as in <> bcc:: `bcc` as in <> subject:: `subject` as in <> reply-to:: `reply-to` as in <> Priority of these is as follows `configuration > command line > global`. == Message format Messages consist of two parts *separated by a single empty line*. The first part is the configuration and the second part is the actual message. .Example message ---- to: cryogenics-department@example.com from: me-bot@example.com cc: me@example.com subject: Unfreeze Clemens date: 2134-01-01 Dear Cryogenics Department, please unfreeze Clemens, as he wanted to watch this year's close pass of Halley's Comet. This one is going to have an apparent magnitude of -2.0 — it's gonna be fun, so feel free to join him! ---- [[Configuration]] === Configuration The following parameters are permitted, everything else is going to be ignored. ==== Required parameters NOTE: Except for `date`, other required parameters may be specified outside the message configuration, either on the command line or in the ini-file. date:: The "not before" date. This may either be a simple date in the format `YYYY-mm-dd`, which will be interpreted as `YYYY-mm-dd 00:00`, or a date with a time in the form of `YYYY-mm-dd HH:MM`. to:: A single address to where the message will be sent. It may either be a simple email address such as `foo@example.net` or an address including a name such as `Foo bar `. subject:: A short subject. from:: Same format as `to`. ==== Optional parameters cc:: Same format as `to`, but multiple comma-separated entries are allowed, works like `Cc` in email. bcc:: Same format as `to`, but multiple comma-separated entries are allowed, works like `Bcc` in email. reply-to:: Same format as `to`, works like `Reply-To` in email. === Message Body Simple, plain text. It is assumed to be in UTF-8, though. == Writing a New Message Either edit a file, directly in `{lettersnail-base}/todo`, or use the command line tool to initialize an empty message and start your favourite editor. The file name must end in `.msg`, otherwise it will be ignored. .Using the command line tool ---- $ lettersnail create --to "foo@example.com" ---- == Command Line Options Use `--help` after any command to get the full help message shown. ---- include::lettersnail.go[tag=main] ---- === `next` command ---- include::cmd/next.go[tag=next] ---- This will show which messages are going to be sent within the next 7 days. Use the `--days` parameter to change how many days in advance are processed. If you use the `--all` parameter, all pending messages will be listed. The format is simply `date subject (filename)`. ---- $ lettersnail next --all Showing all messages. 2061-07-28 00:00 Watch Halley's Comet (halley.msg) 2134-01-01 00:00 Unfreeze Clemens (unfreeze.msg) ---- === `run` command ---- include::cmd/run.go[tag=run] ---- This will send out all pending messages. There will be no output, unless there were errors. Any message that could not be sent will be moved to the `errors` folder, and a corresponding `.log`-file will be created with all available information; additionally, the program will start to complain at every invocation that there were messages with errors. Messages that were delivered successfully are moved to the `done` folder and a corresponding `.log`-file is created there, too. === `create` command ---- include::cmd/create.go[tag=create] ---- The `create` command will assist you in creating a new message. It will open a new file for you, filled in with any parameters you provided on the command line. If you provide a file name through the `--draft` parameter, it will create a new file based on the given file name in the `drafts` folder. ---- lettersnail create --to foo@example.com --subject "Something" ---- It will use the editor configured in `$VISUAL` or `$EDITOR` or `vi`, if the former are empty. `date` will be set to tomorrow's date. ---- 1 to: foo@example.com 2 subject: Something 3 date: 2016-01-01 4 5 Add message to the world of tomorrow here. ~ ~ ~ ~ INSERT >> [No Name][+] <<< -- INSERT -- ---- After editing it will ask you if you want to add the message to the `todo` folder. ---- Save message? ([(y)es], (r)enamed, (d)raft, (n)o): ---- Answering `n` or `no` will discard the message, answering `d` or `draft` will add it to the `drafts` folder. If you type `y`, `yes`, or simply hit `ENTER` it will be added to the `todo` folder. If you want to save the message under a different name, but still into the `todo` folder, you may anwer with `r` or `renamed` — the program will then prompt you for a new name, without the `.msg` extension. === `check` command ---- include::cmd/check.go[tag=check] ---- The `check` command will check all messages in the `todo` and `drafts` folder and report any messages that can't be processed. Optionally a file name can be provided to check only the given file. It will exit with a code of `0` if no errors were found, otherwise with a code of `1`. NOTE: `--silent` will not suppress output of errors, such as problems loading a file. ---- $ lettersnail check in drafts: foo.msg: missing the 'to' parameter missing the 'subject' parameter in todo: bar.msg: 'date' parameter is invalid ---- === `debug` command ---- include::cmd/debug.go[tag=debug] ---- The `debug` command will print out the effective configuration for a message, plus the email message. This shows all settings as they are seen at that point. Note that this also shows settings — such as `workdir` and `config` — that cannot be overridden by the message. Please note that for the email message there are several places, such as the `Message-Id`, that vary from invocation to invocation as they are randomly generated. ---- $ lettersnail debug lettersnail/todo/2061.msg Configuration ------------- config: /home/me/.config/config.ini date: 2061-07-28 days: 7 from: me@example.com not-after: 23:59 not-before: 00:00 port: 578 server: smtp.example.com subject: Watch Halley's Comet to: me@example.com workdir: /home/me/lettersnail Email message ------------- Content-Type: multipart/mixed; boundary=8bb4fce665d20481a3b832ef74a12123edadb7b1bc4d5b505c93e9fbd9e2 To: Subject: Watch Halley's Comet Message-Id: <1464969109987565122.18908.793296386389602001@smtp.example.com> From: me@example.com Date: Fri, 03 Jun 2016 17:51:49 +0200 Mime-Version: 1.0 --8bb4fce665d20481a3b832ef74a12123edadb7b1bc4d5b505c93e9fbd9e2 Content-Type: multipart/alternative; boundary=70b52bfb5fa8b90ebe2b3b9373f62436d412ae3e59bbfa20685dbc1bd6bc --70b52bfb5fa8b90ebe2b3b9373f62436d412ae3e59bbfa20685dbc1bd6bc Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Greetings! Go outside at night, if the curfew of the – highly welcomed — alien overlords permits, and watch Halley's Comet. --70b52bfb5fa8b90ebe2b3b9373f62436d412ae3e59bbfa20685dbc1bd6bc-- --8bb4fce665d20481a3b832ef74a12123edadb7b1bc4d5b505c93e9fbd9e2-- ----