Skip to content

balamsoft/next-mail

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

next-mail (v0.0.1)

Next Mail

Motivation

To create a more secure, quickly evolving, open source alternative to traditional e-mail.

Messages format

Please refer to the JSON schema files at next-mail-core/src/main/resources for more details.

Every email will be sent in JSON format and UTF-16 encoding (without JSON comments). All properties must follow the kebab-case naming convention.

Some attributes are optional, in such case they can be omitted or provided with a null value. When an optional attribute is omitted then it should be assumed to be null. When a mandatory attribute is missing or null then the email should be considered invalid.

Emails payload format

{
  "version": "0.0.1",
  "type": "email",
  "from": "john-doe@example.com",
  "sender-fingerprint": "$2y$12$sgofxSYqPzFN78yFneHU6OMY3ydUMtXjG6fvSRkfCNJNudlkzOWQq",
  
  "to": ["sandra-doe@example.com", "sales@example.com"],
  "cc": [],
  "bcc": [],
  "sent-time": "2020-12-22T00:04:12Z",

  "subject": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.",

  "body":"
    [H1]Monthly Report January - 2021[/H1]
    
    Hi Sandra, I'm sending you the sales report for January.
    You will find the report in the [i]attachments section[/i].
  ",
  "signature": {
    "full-name": "John H. Doe",
    "company-name": "Example Dot Com SA",
    "address-line-1": "77 Massachusetts Ave",
    "address-line-2": null,
    "city": "Cambridge",
    "state": "MA",
    "zip-code": "02139",
    "company-url": "www.example.com",
    "phone-numbers": [
        {"number": "202-555-5555", "type": "OFFICE", "country-code": 1},
        {"number": "202-555-0719", "type": "MOBILE", "country-code": 1}
    ]
  }
  "attachments": [
    {
      "file-name": "Monthly report January 2021.pdf",
      "mime-type": "application/pdf",
      "data": "iVBORw0KGgoAAAANSUhEUgAAA4QAAAMdCAYAAADDJ7iwAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH5AoFFic1qLKyIwAAIABJREFUeNrsvduTJdd55ffbec8896rq6uoLGt0NgKSGkiySEw6GzAe9jEejGD067Aj/M3qcZ9sxM2GPHzQOeSwrwpJt2RpQ1IWSOOSQFCASFEEBTaKbfauu27nkyXvu3H7Is3dnNUFKIjAyCe4f4kRVnzp1TmZWNbpWre9bSyilFBaLxWL5mUMphRDiB+4bMvz4i48f/lkpZf784mO6rkMIgeM45nGO4wDQdR1KKVzXBUBKSVmW1HWN67o4jsNmsyEIAnzfp65rPM+jrmuUUiRJguM4ZFlG0zREUUQURQghzOPKskRKie/7BEFA13XUdY3v++b1hRC4rmte03EcPM8z9w+PVZ/H8Bq933V88T6LxW"
    }
  ]
}

Mandatory attributes are:

Attribute Description
version The version number of the email JSON object.
type In this case it should always be 'email'.
from The email address of the sender.
sender-fingerprint A hash string generated by the sender using the sender's secret code.
to An array of strings each one containing an email address. Cannot be empty.
sent-time A string representing a timestamp in ISO 8601 in UTC timezone (UTC always).
subject A string up to 100 characters long. Plain text only.
body A string up to 4MB in size (including text and inline images).

Optional attributes are:

Attribute Description
cc An array of strings each one containing an email address.
bcc An array of strings each one containing an email address.
signature The sender's contact card. All attributes are optional as well except for full-name which is mandatory if the signature attribute is defined.
attachments An array of elements each one representing a file (see the Attachments section).
appointment An email can include 0 or 1 appointment (see the Appointments section)
task An email can include 0 or 1 task (see the Tasks section)
tags An email can include string tags (see the Tags section)
acknowledge-required Sender requires recipients to acknowledged this email. To avoid endless 'Ok' replies.
acknowledge-required-label Allows changing the default label or the Acknowledge button.

Sending and receiving emails

Each email can have one or more destinataries, and each one could belong to a different domain. So, every time an email is sent two arguments must be sent to each one of this different domains:

  1. An exact copy of the email.
  2. A salted hash string that uniquely identifies the email being sent.

The hash string will become a globally unique identifier for the email across all organizations. This string will be used for two purposes:

  1. To verify if the email (json) received is complete.
  2. To uniquely identify the email when replies are sent across multiple domains.

So, when a domain receives an email the hash string must be stored as the message-id.

Attribute Description
message-id A string that identifies the email received across the world.

When an email is sent only one message is sent to each different domain instead of one message per receiver. The list of different domains can be obtained by looking at the receivers (from, to, cc, bcc) in the email.

For example:

{ "from": "steve@foo.com", "to": ["lisa@bar.com", "javier@baz.org"], "cc": ["sales-team@foo.com"], "bcc": ["steve@zmail.com"], ... }

In this case there are four different domains involved: foo.com, bar.com, baz.org and zmail.com. The domain foo.com will save the email in the local database. This means that only 3 copies of this email will be sent over the net. After each domain receives its respective copy then each one of those servers will internally route a copy to each individual receiver.

Following the previous example, foo.com will internally send a copy to steve@foo.com (sent folder) and one to each member of the sale-team group. Other domains should do the same: save the email in the database and rout it to each individual receiver that belongs to that domain in particular.

[email]
   |
   +---> foo.com --> DB --+---> notify: steve@foo.com 
   |                      |
   |                      +--> sales-team@foo.com ---> notify: susan@foo.com, mark@foo.com, lauren@foo.com, ...
   |
   +---> bar.com --> DB --> notify: lisa@bar.com
   |
   +---> baz.org --> DB --> notify: javier@baz.org
   |
   +---> zmail.com --> DB --> notify: steve@zmail.com

Replies payload format

Unlike traditional emails replies do not include the original message (or conversation), instead, they just reference the original email:

{
  "version": "0.0.1",
  "type": "reply",
  "from": "sandra-doe@example.com",
  "sender-fingerprint": "$2y$12$sgofxSYqPzFN78yFneHU6OMY3ydUMtXjG6fvSRkfCNJNudlkzOWQq",
  
  "original-message-id": "2e87284d245c2aae1c74fa4c50a74c77c17b6e9b160cda0cf583e89ec7b7fc22",
  "sent-time": "2020-12-22T00:04:23Z",

  "body":"Thanks John, I'll check it.",
  
  "signature": {
    "full-name": "Sandra Doe",
    "company-name": "Example Dot Com SA",
    "address-line-1": "77 Massachusetts Ave",
    "address-line-2": null,
    "city": "Cambridge",
    "state": "MA",
    "zip-code": "02139",
    "company-url": "www.example.com",
    "phone-numbers": [
        {"number": "202-555-5556", "type": "OFFICE", "country-code": 1}
    ]
  }
  "attachments": []
}

Mandatory attributes are:

Attribute Description
version The version number of the email JSON object.
type In this case it should always be 'reply'.
original-message-id The message-id of the original email received.
reply-id A unique string that identifies the reply. The reply-id should be unique domain-wide.
from The email address of the sender.
sender-fingerprint A hash string generated by the sender using the sender's secret code.
to An array of strings each one containing an email address. Cannot be empty.
sent-time A string representing a timestamp in ISO 8601 in UTC timezone (UTC always).
subject A string up to 100 characters long. Plain text only.
body A string up to 4MB in size (including text and inline images).

Optional attributes are:

Attribute Description
cc An array of strings each one containing an email address.
bcc An array of strings each one containing an email address.
signature The sender's contact card. All attributes are optional as well except for full-name which is mandatory if the signature attribute is defined.
attachments An array of elements each one representing a file (see the Attachments section).
appointment An email can include 0 or 1 appointment (see the Appointments section)
task An email can include 0 or 1 task (see the Tasks section)
tags An email can include string tags (see the Tags section)

How replies work

When a user replies to an email, potentially involving destinataries at multiple domains, then an exact copy of the reply will be sent to each domain (including the domain of the user sending the reply).

For this reason the reply should contain the salted hash code that identifies the original email.

When a reply is sent only one message is sent to each different domain instead of one message per destinatary. The list of different domains can be obtained by looking at the receivers (from, to, cc, bcc) in the original email.

For example, if the original email was sent to these persons:

{
    "from": "steve@foo.com",
    "to": ["lisa@bar.com", "javier@baz.org"],
    "cc": ["sales-team@foo.com"],
    "bcc": ["steve@zmail.com"],
    ...
}

When any of the receivers replies to the email (i.e. lisa@bar.com) then bar.com saves the reply in the local database and sends a copy of the reply to the other 3 domains: foo.com, baz.org and zmail.com.

After each domain receives a copy and saves it, then all receivers should be sent a push notification containing the reply. In order to know who the original receivers were, the original message should be found in the database using the original-message-id. Each domain should only care about notifying the users that belong to the current organization.

[reply to original-message-id=2e87284d245... from lisa@bar.com]
    | 
    +---> foo.com --> DB -+--> notify: steve@foo.com 
    |                     |
    |                     +--> sales-team@foo.com ---> notify: susan@foo.com, mark@foo.com, lauren@foo.com, ...
    |
    +---> baz.org --> DB ---> notify: javier@baz.org
    |
    +---> zmail.com --> DB ---> notify: steve@zmail.com

In the example above the reply doesn't need to be sent to bar.com since it already has been saved and notified locally.

Asymmetric Encryption and Decryption

Next-mail emails travel over TCP and should be encrypted using SSL/TLS to protect their users. However, this means that emails are being decrypted once they reach the target server. TLS isn't end-to-end encryption. They could still be captured or stolen by someone with access to the internal network infrastructure.

To add another layer of protection next-mail messages can be encrypted end-to-end using asymmetric encryption. One to one emails be encrypted to secure key parts of it during transit so only the sender and the receiver can see their contents.

Encrypted email sections

Not all parts of an email can be encrypted, some information must still be readable by the mail router to be able to dispatch the encrypted messages. The following sections will be encrypted in both emails and replies that belong to a private conversation:

  • The subject
  • The email body
  • The values of each one of the properties in each attachment (including the file's data)
  • The values of each one of the properties in the sender's signature
  • The values of each one of the properties in appointments and tasks
  • The tags

Sending an encrypted email

A private one-to-one conversation starts with a request sent from the mail server of person A to the mail server of person B.

{
  "version": "0.0.1",
  "type": "public-key-request",
  "from": "john-doe@example.com",
  "to": ["lisa-miller@acme.com"]
}

This request will be sent when the user A chooses to send an encrypted email to person B. If the next-mail server of person B agrees to provide a public key (this feature could be disabled in the server configuration) then the public key will be returned as a response:

{
  "version": "0.0.1",
  "type": "public-key-response",
  "from": "john-doe@example.com",
  "owner": "lisa-miller@acme.com",
  "public-key": "MIIBCgKCAQEA+xGZ/wcz9ugFpP07Nspo6U17l0YhFiFpxxU4pTk3Lifz9R3zsIsuERwta7+fWIfxOo208ett/jhskiVodSEt3QBGh4XBipyWopKwZ93HHaDVZAALi/2A+xTBtWdEo7XGUujKDvC2/aZKukfjpOiUI8AhLAfjmlcD/UZ1QPh0mHsglRNCmpCwmwSXA9VNmhz+PiB+Dml4WWnKW/VHo2ujTXxq7+efMU4H2fny3Se3KYOsFPFGZ1TNQSYlFuShWrHPtiLmUdPoP6CV2mML1tk+l7DIIqXrQhLUKDACeM5roMx0kLhUWB8P+0uj1CNlNN4JRZlC7xFfqiMbFRU9Z4N6YwIDAQAB"
}

Once the sender has the receiver's public key the email can be encrypted. Now, all the replies will automatically be encrypted as well. For this purpose the email must include the sender's public key, so it must be included in the email.

{
  "version": "0.0.1",
  "type": "email",
  "encrypted": true,
  "from": "john-doe@example.com",
  "sender-fingerprint": "$2y$12$sgofxSYqPzFN78yFneHU6OMY3ydUMtXjG6fvSRkfCNJNudlkzOWQq",
  "sender-public-key": "AAAAB3NzaC1yc2EAAAABJQAAAQB/nAmOjTmezNUDKYvEeIRf2YnwM9/uUG1d0BYsc8/tRtx+RGi7N2lUbp728MXGwdnL9od4cItzky/zVdLZE2cycOa18xBK9cOWmcKS0A8FYBxEQWJ/q9YVUgZbFKfYGaGQxsER+A0w/fX8ALuk78ktP31K69LcQgxIsl7rNzxsoOQKJ/CIxOGMMxczYTiEoLvQhapFQMs3FL96didKr/QbrfB1WT6s3838SEaXfgZvLef1YB2xmfhbT9OXFE3FXvh2UPBfN+ffE7iiayQf/2XR+8j4N4bW30DiPtOQLGUrH1y5X/rpNZNlWW2+jGIxqZtgWg7lTy3mXy5x836Sj/6L"
  
  "to": ["lisa-miller@acme.com"],
  "cc": [],
  "bcc": [],
  "sent-time": "2021-01-14T21:04:12Z",

  "subject": "*encrypted subject using Lisa's public key*",

  "body":"*encrypted email body*",
  ...
}

When (B) replies to the email sent by (A) the reply will automatically be encrypted.

{
  "version": "0.0.1",
  "type": "reply",
  "encrypted": true,
  "from": "lisa-miller@acme.com",
  "sender-fingerprint": "$2y$12$hulfxSYqPzFN78yFneHU6OMY3ydUMtErG6fvSRkfCNJNudlkzOWQq",
  
  "original-message-id": "2a76384d245c2aae1c74fa4c50a74c77c17b6e9b160cda0cf583e89ec7b7fc22",
  "sent-time": "2021-01-15T08:12:54Z",

  "body":"*encrypted mail body using John's public key*",
  ...
}

Non encrypted replies should be actively denied by the next-mail servers as part of a private thread.

Precautions

When one of the actors receives an encrypted mail or reply that cannot be decrypted using his/her private key the receiver should be notified. The message may have not been encrypted properly, or the public/private keys of the receiver could have changed since that message was sent.

In the event that a user loses his/her private keys all the emails encrypted with them will become unreadable and unrecoverable. In order to minimize data loss the users may opt to keep an unencrypted copy of those messages in a device or in a cloud storage service of his/her choice (although there are inherent risks in doing so).

Sender identification

Verification request

An HTTP request is sent to the original domain including the original sender's address and the sender-fingerprint and the emails' hash value as follows:

{
  "from": "john-doe@example.com",
  "sender-fingerprint": "$2y$12$sgofxSYqPzFN78yFneHU6OMY3ydUMtXjG6fvSRkfCNJNudlkzOWQq",
  "message-id": "2e87284d245c2aae1c74fa4c50a74c77c17b6e9b160cda0cf583e89ec7b7fc22"
}

Following the example above, the request will be sent to nmail.example.com/verify which will do the following:

  1. An account exists for the sender.
  2. The hash code is valid against the sender's secret code, which is a randomized unique string generated for that user when the account was created.
  3. The account did send a message that matches the given message-id, and the generated sender-fingerprint hash code in that event matches as well.

Next-mail servers should allow user's to renew their secret code, if and only if, any previous valid secret code are kept. If previous valid secret codes are deleted then any previous emails sent from that email account will be rendered as "unverified sender" by mail clients.

Next-mail clients should keep indexes for values: from, sender-fingerprint and message-id. Mail clients should actively refuse any emails received with a duplicate sender-fingerprint or message-id values since those values are meant to be unique at all times. Re-sending or forwarding emails should provide new values for those two fields at the moment the message is sent.

Verification endpoint

The next-mail verification URL will be constructed from the domain in the sender's mail address. The company should publish a subdomain called nmail which in turn should provide an endpoint called verify.

Custom verification URLs should not be allowed since that could bypass this verification mechanism really easily. For example, an attacker could impersonate a CEO of a company by using his/her email address in the from field and then providing a verification URL to a server like 2y6yy9Hglsjza2EBqAADgNq24naGAZo4EepM0Nli.biz/verify that simply replies successfully to all requests it receives.

Verification response

The verification response should include all the fields received in the request plus two more fields called verified and verification-date. Example:

{
  "from": "john-doe@example.com",
  "sender-fingerprint": "$2y$12$sgofxSYqPzFN78yFneHU6OMY3ydUMtXjG6fvSRkfCNJNudlkzOWQq",
  "message-id": "2e87284d245c2aae1c74fa4c50a74c77c17b6e9b160cda0cf583e89ec7b7fc22",
  "verified": true,
  "verification-date": "2020-12-22T00:04:22Z"
}

Dates format

ISO 8601 - Limited to UTC only, clients should convert the dates to the local date and time according to the user's timezone.

"sent-time": "2020-12-22T00:04:12Z"

Acknowledgement

Sometimes the person who sends an email may require acknowledgement from its receivers. To avoid simple replies like 'Ok', that are often sent as a reply to all, emails will show the receivers an 'Acknowledge' button. Once pressed the sender, an only the sender, will be notified. Applies to everyone except people listed in the BCC field.

By default, the label of this button will be 'Acknowledge' but can be customized.

{
    ...
    "to": ["logisticts@example.com"],
    "cc": ["hr@sales.com"],
    "bcc": ["cso@example.com"],
    "acknowledge-required": true,
    "acknowledge-required-label": "Understood",
    "subject": "New security guidelines for 2022, please acknowledge.",
    ...
}

Every time a user hits the acknowledge button a message will be sent to the domain of the sender, for example:

{
  "version": "0.0.1",
  "type": "acknowledge",
  "from": "james-hr@example.com",
  "original-message-id": "3f97284d245c2aae1c74fa4c50a74c77c17b6e9b160cda0cf583e89ec7b7fc45",
  "sent-time": "2021-11-29T16:13:56Z"
}

Rich text markup

For security reasons we should prevent the inclusion of HTML and Javascript code in messages. A custom markup language is proposed.

This markup language is not meant to be extensive; it is only meant to support a subset of HTML-equivalent tags sufficient for creating good-looking emails. Tags like iframe,script,form,input,select,embedand canvas, among others, won't and shouldn't be allowed in the future. Even elements like images and hyperlinks will have restrictions.

Basic text formatting

[h1]Lorem ipsum[/h1]
[h2]Lorem ipsum[/h2]
[h3]Lorem ipsum[/h3]
[h4]Lorem ipsum[/h4]
[h5]Lorem ipsum[/h5]
[h6]Lorem ipsum[/h6]
[b]Bold text[/b]
[i]Italics[/i]
[u]Underline[/u]
[s]Striked text[/s]
[super]super index[/super]
[sub]subindex[/sub]
[left]left aligned[/left]
[center]centered text[/center]
[right]right aligned[/right]
[justify]justified text[/justify]
[div]...[/div]
[span]...[/span]
[code]...[/code]
[cite]...[/cite]
[blockquote]...[/blockquote]
[p]...[/p]
[pre]...[/pre]
[ul]
    [li]Milk[/li]
    [li]Coffee[/li]
[/ul]

Images

External images: For security reasons external images are not supported. (TODO: consider allowing external images, then fetching the image files in the back end and translating them into Base64 strings before being sent to the front end)

Inline images:

[img]image/png;iVBORw0KGgoAAAANSUhEUgAAAA4AAAAQCAYAAAAmlE46AAAAAXNSR0IArs4c6QAAAIRlWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABgAAAAAQAAAGAAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAAA6gAwAEAAAAAQAAABAAAAAAfkeR3QAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KTMInWQAAAB5JREFUKBVj/A8EDGQAJjL0gLWMasQTcqOBM8IDBwBlLAQctY7BrAAAAABJRU5ErkJggg==[/img]

Hyperlinks

[mailto:{Hyperlink text}]{Email Address}[/mailto]
[url:{Hyperlink text}]{URL}[/url]

Examples:

[mailto:John Doe, Finance]john-doe@example.com[/mailto]
[url:Security Awareness Meeting]http://www.example.com/events/2021/March/security-awareness-meeting[/url]

Next-mail servers and clients should implement a mechanism that verifies URLs and renders them unclickable to all users when blacklisted. Before visiting the link the next-mail client will create a shortened version of it, the short URL will be opened instead of the original one.

Hyperlinks executing javascript code will simply not be allowed.

Tables

[table;class:balance-sheet]
  [thead]
    [row;class:banner-row]
      [col;span:3]
        [img]image/png; ... [/img]
      [/col]
    [/row]
  [/thead]
  [tbody]
    [row;class:header-row]
      [col]Number[col]
      [col]Description[col]
      [col]Amount ($USD)[col]
    [/row]
    [row]
      [col]1[/col]
      [col]Net income[/col]
      [col]$14.564M[/col]
    [row]
    ...
  [/tbody]
[/table]

CSS Formatting

As you could see in the tables section you can use class names. The CSS code for a next-mail email is defined in the css attribute at the root node.

{
  ...
  "body": "[div;class=mail-title]Some text[/div]",
  "css": ".mail-title {
    text-align: center;
    font-size: 14px;
    font-weight: bold;
    color: #EE0022;
  }"
  ...
}

You can also define classes in other tags seen before. Use a semicolon (;) to separate the class definition from the rest of the tag as follows:

[div;class:main-section]...[/div]
[code;class:code-block-java]...[/code]
[mailto:John Doe, Finance;class:mailto-link]john-doe@example.com[/mailto]
[ul;class:numbered-list]...[/ul]

Also you can add styles to all tags of the same type just like in HTML:

{
    ...
    "body": "
        [div]This is a div[/div]
        [div]This is another div[/div]
        [span]This is a span[/span]
    ",
    "css": "
      div {
        display: block;
        font-size: 14pt;
        color: black;
      }
      span {
        display: inline-block;
        font-size: 12pt;
        background-color: black;
        color: white;
      }
    "
}

The signature card can also be formatted using class name .contact-card. Each element in the card will be a div with a CSS class named as the attribute it represents, for example:

.contact-card {
    width: 450px;
    font-size: 12px;
}
.contact-card.full-name {
    // css
}
.contact-card.company-name {
    // css
}
.contact-card.address-line-1 {
    // css
}
.contact-card.address-line-2 {
    // css
}
.contact-card.phone-numbers:first-child {
    // css for the first phone number displayed
}
.contact-card.phone-numbers:nth-child(2) {
    // css for the second phone number displayed
}

A custom CSS signature formatting can be defined company-wide and will be applied by default to all users in it.

Tags like url and mailto will become HTML anchors (<a href="..."/>).

Escape codes

Next-mail escape sequences:

Sequence Description
\[ to escape left square brackets
\] to escape right square brackets
\" to escape double quotes
\\ to escape backslash

Attachments

Emails and replies can contain file attachments (optional). The attachments' data value is also a Base64 encoded string.

  ...
  "attachments": [
    {
      "file-name": "Monthly report January 2021.pdf",
      "mime-type": "application/pdf",
      "data": "iVBORw0KGgoAAAANSUhEUgAAA4QAAAMdCAYAAADDJ7iwAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH5AoFFic1qLKyIwAAIABJREFUeNrsvduTJdd55ffbec8896rq6uoLGt0NgKSGkiySEw6GzAe9jEejGD067Aj/M3qcZ9sxM2GPHzQOeSwrwpJt2RpQ1IWSOOSQFCASFEEBTaKbfauu27nkyXvu3H7Is3dnNUFKIjAyCe4f4kRVnzp1TmZWNbpWre9bSyilFBaLxWL5mUMphRDiB+4bMvz4i48f/lkpZf784mO6rkMIgeM45nGO4wDQdR1KKVzXBUBKSVmW1HWN67o4jsNmsyEIAnzfp65rPM+jrmuUUiRJguM4ZFlG0zREUUQURQghzOPKskRKie/7BEFA13XUdY3v++b1hRC4rmte03EcPM8z9w+PVZ/H8Bq933V88T6LxW"
    }
    ...

Appointments

Emails can include one appointment (optional).

{
  ...
  "appointment": {
    "title": "Sales montly meeting",
    "type": "Event",
    "date": "2020-12-23T17:00:00Z"
    "duration": {
      "minutes": 30
    },
    "all-day": false,
    "timezone": "GMT+5",
    "reminders": [
      {"minutes": -15},
      {"days": -1}
    ],
    "guests": [
      "john-doe@example.com", "sandra-doe@example.com", "sales-team@example.com"
    ],
    "phone-numbers": {
      [
        {"number": "+16172532871", "guest-access-code": "123456"},
        {"number": "+16172532872", "guest-access-code": "123456"}
      ]
    },
    "meeting-url": "meet.google.com/bco-vrja-abc",
    "location": {
      "address-line-1": "77 Massachusetts Ave",
      "address-line-2": null,
      "city": "Cambridge",
      "state": "MA",
      "zip-code": "02139",
      "company-url": "www.example.com",
      "phone-numbers": [
        {"number": "202-555-5645", "type": "OFFICE", "country-code": 1}
      ]
      "meeting-room": "Room 14",
      "gps-coordinates": {
        "latitude": "42.3631788",
        "longitude": "-71.0933875"
      }
    }
  }
}

Tasks

Sometimes you may send an email asking someone to perform a task and want to know the progress. The current state of the task will be visible to all persons who received that email. The state should be handled and updated by next-mail clients.

Only one task per email allowed (optional).

{
  ...
  "task": {
    "individual": false,
    "workflow": [
      "TODO",
      "IN-PROGRESS",
      "DONE",
      "WONT-FIX"
    ],
    "end-states": ["DONE", "WONT-FIX"],
    "checklist": [
      "Create the sales report",
      "Peer review it",
      "Send report to Sandra"
    ],
    "deadline": "2021-02-01T12:15:00Z",
    "timezone": -5
  }
}

A description may not be necessary in the task itself, it must be written in the email's body. Checklist and deadline are optional but worflow and end-states are mandatory. There could be cases in which more that one state could be considered as a final state. Workflows may be created in the next-mail client and they are copied to the email instead of being written every time per email.

Tasks only apply to receivers in the to field and only within the same domain as the sender. Tasks can be individual (one state per receiver) or not (one state for everyone).

Polls

Anyone receiving the email will be able to vote in the poll. When hide-results is true only the sender will be able to see them, otherwise anyone will be able to see the results as soon as they submit their vote.

  {
    ...
    "poll": {
      "hide-results": false,
      "selections-allowed": 1,
      "title": "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium?"
      "options":[
        "Nam libero tempore",
        "Quod maxime placeat",
        "Temporibus autem quibusdam",
        "Non recusandae"
      ],
      "expires": "2021-01-14T10:00:00Z"
    }
  }

Tags

Emails may optionally include tags to help sort them or trigger actions setup using third party plugins.

{
  ...
  "tags": [
    "sales-department", "reminders", "work"
  ]
}
{
  ...
  "tags": [
    "echo", "lights", "turn-on", "living room"
  ]
}

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published