Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • A COI-compatible client, i.e. your app. Also called just "COI client".
  • An IMAP service for retrieving the message historydata, currently we use IMAP for that, but COI is not tied to IMAP and could be made available through JMAP too, for example. The IMAP server may or may not be COI-compatible. Here we assume that the The IMAP service is MUST be compatible with IMAP v4rev1 as defined in RFC 3501, which is the case for almost any IMAP service in production.
  • An SMTP service for sending messages. Sending services are also called Mail Transfer Agents (MTAs).
  • Other clients, which may or may not be COI-compatible. Clients are also called Mail User Agents (MUAs).

...

  • Backwards Compatibility
    Always have something to show for existing email clients. Each message SHOULD contain 
    • a at least one text/plain part, or
    • additionally optionally a text/html part, or
    • a binary part like image/jpeg.
  • Open Standards
    Use open and existing standards when possible, e.g. 
    • VCard for contact information
    • Disposition Notification Reports for read receipts
    • application/json attachments for structured data
  • Secure Messaging
    Support users to message securely,
    • Allow any encryption mechanism

    • Recommend autocrypt.org support

    • Optional direct IMAP 2 IMAP communication

  • Modern User Experience.
    Provide support for allowing a user experience that most people expect, e.g. 
    • Easy cross device contact sync

    • Allow to block users

    • Edit & delete sent messages

    • Useful interactions like polls

    • Push (with COI enabled backend)

    • Typing notifications (when both parties use a COI-enabled servers)

Backwards Compatibility

COI messages are designed to be backwards compatible with existing email clients. While some COI functionalities will not work on such legacy clients, users of non-COI-compliant clients should still be informed about it. Therefore, each message MUST have at least one part that explains the content of this message. This SHOULD be MUST be a text/plain part plus one of the following mine types:

  • text/plain, ortext/html, or
  • a common binary format like for example image/jpeg.

...

  • A COI message MUST contain the "Chat-Version" header field with a value of "1.0". Note that further parameters MAY follow which will be separated by semicolons, e.g. "Chat-Version: 1.0;name=value".
  • A COI message MUST only contain one address in the "From" field.
  • A COI message MUST contain a "Date" header field with a value adhering to RFC 5322.
  • A COI message MUST contain a "Message-ID" header field in the following format: "coi|coi$" + domain-unique ID + "@" + mail domain, e.g. "coi|KJKJK2312321312KJ@mydomaincoi$KJKJK2312321312KJ@mydomain.org".  Note that the symbol behind "coi" is the pipe symbol |, not an uppercase i or a lowercase L.  
  • A COI message MUST contain "MIME-Version: 1.0" in the header.
  • A COI message SHOULD contain a "References" header field with the message-ID IDs of the initial message and the last message only. This is the "References" header value of the parent message, if this is not set, the message-ID of the parent message. Note that this recommendations is contrary to the RFC 5322 recommendation, which results in all message-ID are all parent messages being referenced. However, in a chat conversation there will be way more messages than in a typical email thread, so it would be impractical to reference all previous messages.
  • A COI message SHOULD contain a "In-Reply-To" header when answering to a previous message. This header field contains the message-ID in of the replied message.
  • The "To" header contains the recipient(s) of the message. 
  • The "From" header field of a COI message MUST only contain one sender.
  • A COI message SHOULD NOT have a SENDER header field.A COI message SHOULD contain a SUBJECT header field that starts with "Chat: " followed by either the message start, the sender's name or a random ID (the latter for privacy purposes). If the message is encrypted, a COI client SHOULD NOT repeat the message in plain text within the subject "Sender" header field.
  • A COI message MAY contain a "Disposition-Notification-To" header field. If it is present the field content MUST be the same as the FROM header field. This is for requesting read reports.
  • A binary COI message MUST contain the "Content-Transfer-Encoding" header field.
  • A binary COI message MUST contain the "Content-Disposition: inline" header. It SHOULD also contain the filename and size parameters, for example "Content-Disposition: inline;filename="earth.jpg";size=2048".
  • The "BCCChat-Content" header with the sender's address MAY be used to store a copy of the message on the user's IMAP service without needing to upload the message twice.The "Chat-Content" header is used in message parts to identify the used in message parts to identify the contents of a specific part.
  • Depending on the message contents or its encryption, additional headers MAY be set.
  • A COI client MAY set the "Subject" header field.  

COI Base Formats

A COI message will use one of these formats as specified in the "Content-Type" header field:

  • text/plain: for normal, user generated text messages without any additional data
  • multipart/alternative: for user generated messages in which the application/json part is some parts may be applicable for a COI client while the text/plain or text/html part is applicable for a both non-COI-compliant clientclients and COI clients.
  • multipart/mixed: for creating more complex messages, e.g. the first message to a group that also contains a text/vcard part of the sender as an attachment.

...

  • User generated text messages SHOULD be delivered in the TEXT/PLAIN mime format with a UTF-8 encoding when possible. This is defined with following header field: "Content-Type: text/plain; charset=UTF-8; format=flowed".
  • Note that incoming messages from existing email clients MAY be delivered in other formats but SHOULD still be shown. Any existing signatures and quote blocks SHOULD be either stripped away or folded out of view. A client MAY show an option to view the full message contents.

...

From: Me Myself <me@sample.com> 
To: You <you@recipientdomain.com>
BCC: Me Myself <me@sample.com>
Subject: Chat: Hello World...
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|S2571BC<coi$S2571BC.2878&8@sample.com>
Content-Type: text/plain; charset=UTF-8; format=flowed
Reference: <coi|434571BC<coi$434571BC.89A707D2@sample.com>
Chat-Version: 1.0
MIME-Version: 1.0
Disposition-Notification-To: Me Myself <me@sample.com>

Hello World
My dear friend, this is a message to you!


NOTES: User case scenario: contains bold/colored/text → use html only?

To allow clients to market themselves, user generated messages MAY be sent as multipart/alternative messages. In that case a COI client SHOULD prefer the text/plain part, whereas existing non-COI compliant clients will typically show the HTML content instead. NOT PART FOR THE SPEC? CREATE MULTIPART/MIXED with several parts

Example for Example for a multipart/alternative message:

From: Me Myself <me@sample.com> 
To: You <you@recipientdomain.com>
BCC: Me Myself <me@sample.com>
Subject: Chat: hello COI ...
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|22938<coi$22938.8238702@sample.com>
Content-Type: multipart/alternative;
boundary=unique-boundary-1
Reference: <coi|434571BC<coi$434571BC.89A707D2@sample.com>
Chat-Version: 1.0
Disposition-Notification-To: Me Myself <me@sample.com>
MIME-Version: 1.0
--unique-boundary-1
Content-Type: text/plain; Charset=UTF-8

hello COI world!

--unique-boundary-1
Content-Type: text/html; Charset=UTF-8

<html><body>
<p>hello COI world!</p>
--unique-boundary-1
Content-Type: text/html; charset=UTF-8
Chat-Content: ignore

<p><i>This message is a chat message - consider using <a href="https://myawesomecoiapp.com">my awesome COI app</a> for best experience!</i></p>
</body></html>

-unique-boundary-1--

An initial message SHOULD contain contact information about the sender, please compare the Contact Messages section below for details.

...

  • photos: image/webp, image/jpeg and image/png SHOULD be supported by a COI-compatible client. image/gif is RECOMMENDED to be supported. 
  • audio-recordings: audio/webm SHOULD be supported by a COI-compatible client. audio/mp4 and audio/mp4 is  RECOMMENDED aac is  RECOMMENDED to be supported.
  • videos: video/webm SHOULD be supported by a COI-compatible client. video/mp4 is RECOMMENDED to be supported.

...

A COI-compatible client SHOULD support messages with multiple files. In this case, the corresponding multipart/mixed and multipart/parallel messages need to be supported. If the COI client supports encryption, additionally multipart/encrypted messages MUST be supported.

...

From: Me Myself <me@sample.com> 
To: You <you@recipientdomain.com>
BCC: Me Myself <me@sample.com>
Subject: Chat: earth.jpg
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|434571BC<coi$434571BC.8070702@sample.com>
Content-Type: image/jpeg
Content-Transfer-Encoding: base64
Content-Disposition: inline;filename=earth.jpg;size=2048
Reference: <coi|434571BC<coi$434571BC.89A707D2@sample.com>
Chat-Version: 1.0
Disposition-Notification-To: Me Myself <me@sample.com>
MIME-Version: 1.0

TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=

...

From: Me Myself <me@sample.com> 
To: You <you@recipientdomain.com>
BCCSubject: Me Myself <me@sample.com>
Subject: Chat: files
Date:
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|123AB223<coi$123AB223.8238702@sample.com>
Content-Type: multipart/parallelmixed;
boundary=unique-boundary-1
Reference: <coi|434571BC<coi$434571BC.89A707D2@sample.com>
Chat-Version: 1.0
Disposition-Notification-To: Me Myself <me@sample.com>
MIME-Version: 1.0

...

--unique-boundary-1
Content-Type: image/jpeg
Content-Transfer-Encoding: base64
Content-Disposition: inline;
filename="venus.jpg";size=4096

... base64-encoded JPEG image data goes here ...
--unique-boundary-1--

Preview

...

Message Parts

For a large binary message such as a video or a high resolution photo, a COI-compatible client MAY send a preview message. This allows clients with unstable or rate-limited network connections to show the message without needing to download the full message contents first.

...

 Chat-Content: preview; 
reference=<coi|434571BC<coi$434571BC.8070702@sample.com>

A preview message typically contains one lower resolution image in a single binary message as described above. A preview message SHOULD NOT contain a read receipt request, i.e. no "Disposition-Notification-To" header.

...

An edit message MUST contain set the "Chat-Content" header field to "edit" with the message-ID of the large message set as a "reference" parameter in the same header field, for example:

 Chat-Content: editammend; 
reference=<coi|434571BC<coi$434571BC.8070702@sample.com>

If a message should be deleted, then the COI client MUST set the "Chat-Content" header field to "delete" and the reference parameter MUST be defined:

 Chat-Content: deletecollapse; 
reference=<coi|434571BC<coi$434571BC.8070702@sample.com>

A message can be edited and/or deleted several times and COI client SHOULD only show the latest version. An edit and delete message MAY contain a read receipt request, which SHOULD be processed normally. To not create a sense of false security, it is RECOMMENDED that clients show the history of edited and delete messages. A deleted message is RECOMMENDED to be shown as "this message has been deleted".

A COI client MUST ensure that the referenced message is coming from the same sender as the original message.

Multiple edits always reference the last edited message, not the original message.

If a the referenced message is not found, e.g. because it is deleted, then the only new message SHOULD be shown.

If a client decides not to support edit and delete message, it just shows all messages in their chronological order.

Example 1: A normal message is being sent with a typo:

From: Me Myself <me@sample.com> 
To: You <you@recipientdomain.com>
BCC: Me Myself <me@sample.com>
Subject: Chat: My dear friend...
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|S2571BC<coi$S2571BC.2878&8@sample.com>
Content-Type: text/plain; charset=UTF-8
Reference: <coi|434571BC<coi$434571BC.89A707D2@sample.com>
Chat-Version: 1.0
MIME-Version: 1.0
Disposition-Notification-To: Me Myself <me@sample.com>

My dear friend, this sdkalsk.

...

From: Me Myself <me@sample.com> 
To: You <you@recipientdomain.com>
BCC: Me Myself <me@sample.com>
Subject: Chat: My dear friend...
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|S232371BC<coi$S232371BC.2232&8@sample.com>
Content-Type: text/plain; charset=UTF-8
Reference: <coi|434571BC<coi$434571BC.89A707D2@sample.com>
Chat-Version: 1.0
Chat-Content: edit;
reference=<coi|S2571BC<coi$S2571BC.2878&8@sample.com
MIME-Version: 1.0

My dear friend, this is a message to you!

...

From: Me Myself <me@sample.com> 
To: You <you@recipientdomain.com>
BCC: Me Myself <me@sample.com>
Subject: Chat: My dear friend...
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|KJ23928L<coi$KJ23928L.298239&8@sample.com>
Content-Type: text/plain; charset=UTF-8
Reference: <coi|434571BC<coi$434571BC.89A707D2@sample.com>
Chat-Version: 1.0
Chat-Content: deletecollapsed;
reference=<coi|S2571BC<coi$S2571BC.2878&8@sample.com>
MIME-Version: 1.0

(original message marked as deleted)

...

From: Alice <you@recipientdomain.com>
To: Bob <me@sample.com>
Subject: Chat: Read receipt
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|122B223<coi$122B223.823202@sample.com>
Reference: <coi|434571BC<coi$434571BC.89A707D2@sample.com>
Chat-Version: 1.0
Content-Type: multipart/report; report-type=disposition-notification;
boundary="RAA14128.773615765/recipientdomain.com"
Content-Disposition: notification
MIME-Version: 1.0

...

Reporting-UA: joes-pc.cs.recipientdomain.com; Foomail 97.1
Original-Recipient: rfc822;you@recipientdomain.com
Final-Recipient: rfc822;you@recipientdomain.com
Original-Message-ID: <coi|199509192301<coi$199509192301.23456@sample.com>
Disposition: manual-action/MDN-sent-manually; displayed

...

To synchronize contacts across devices, a COI-compatible client SHOULD MAY store contacts as individual messages into the COI/CONTACTS folder. Note that on a COI-compatible IMAP server this folder is generated automatically, compare the COI server specification for details. 

To keep the user in control, a COI client SHOULD ask the user for permission, before storing contacts on the IMAP server.

As there are varying needs between client implementations, only some headers are specified in this specification, these headers cannot be used to calculate the contact. Message contents can contain contact data. Client MAY choose to encrypt these messages to protect the contact data further.

The meta data of a contact is stored in a JSON-format, this MUST include COI management information about a contact. The contact data itself is RECOMMENDED SHOULD to be stored VCARD data of the contact as defined in RFC 6350

A contact message MUST SHOULD be a multipart/mixed message with the following contents:

  • One text/plain part explaining the contents, e.g. "this message contains contact information". This part SHOULD have a "Content-Disposition: inline" field.
  • One application/json part that contains contact meta data. This part SHOULD is RECOMMENDED to have a "Content-Disposition: attachment" field with the "filename" parameter, e,g. Content-Disposition: attachment; filename="contact.json". Additionally, this part MUST have the is RECOMMENDED to set the "Chat-Content set " header to "contact".
  • The message MAY contain a text/vcard part containing the actual contact data. This part SHOULD part  is RECOMMENDED to have a "Content-Disposition: attachment" field with a "filename" parameter, which is RECOMMENDED to be "contact.vcf".

...

  • "coi-version" that is set to 1.

  • "content" that is set to"contact".

  • "tokens" which contains an array of token. Each token elements contains 

    • "contact_mail_hash" that contains the SHA3-256 hash of the contact.

    • "my_mail_hash" that contains the SHA3-256 hash of the current user's email address, which may be an alias.

    • "token" is a string value being added automatically by a COI-compliant IMAP service. This can be used for enabling direct IMAP to IMAP connections.

The JSON data MAY also contain the following keys:

  • "is_me" is set to true for the user's own profile. is_me is false by default
  • "is_visible" which can be set to false and is true by default. This can be useful to hide contacts that have been blocked by a user. In this case the is_blocked state is still requiredclient can still show which contacts are blocked, but the contact itself might is otherwise not be interesting to the user anymore."is_favorite" is set to true when a contact is deemed as important by the user.
  • "status" which contains the current user-generated status of the contact.
  • "groups" with an array of any contact-groups a contact is associated with. Predefined groups are "friends" partner", "family", "friend", "favorite", and "familywork".
  • "notification" object which contains the following keys:
    • "is_enabled": true or false - defaults to true. Defines if notifications are enabled for this users.
    • "types" which is an array of strings that can contain "sound", "banner" or other client specific keywords that define the notification type that should be shown.
    • "sound" which defines the notification sound that should be used in a client specific way. RECOMMENDED values include "workare "partner", "family", "partnerfriend", "kidsfavorite", "friendwork" and "other",
    • "filters" criteria when a notification should be shown. When missing and is_enabled is true, it is RECOMMENDED that a notification is shown for any new user generated message. Possible values are
      • "message" for any user generated message excluding read receipts, contact updates, etc, 
      • "mention" for messages that contain a mention of this user, or
      • a client specific value.

...

To efficiently process contact messages on the server side, some data must be stored in the headers, specifically the "COI-Token" and "COI-Blocked" header fields that are described below.

  • From: Contact's primary address and name. Optional, and in case contacts are encrypted it should only be a fixed string.
  • To: Logged in user's primary address for this contact. Optional, and in case contacts are encrypted it should only be a fixed string.
  • Subject: "Chat: Contact" or some other informative text.
  • Date: Timestamp when the contact was last intentionally modified (which can be different from received-time, which is when it was uploaded to server)
  • COI-Token: See below
  • COI-Blocked: yes - COI server should block all messages coming from this contact. This header MUST NOT exist if the contact is not blocked.

...

  • Version ID = '1'. This can be increase to completely change the format or e.g. to switch to a different hash algorithm.
  • Token string, which can contain any characters valid in the header, except '-'
  • Base64 encoded SHA256(from + ':' + to) of the normalized From and To addresses. Normalization means lowercasing the address, and in case of EAI addresses also converting it into UTF-8. (FIXME: Not sure of this exactly? And in theory the localpart could be case-sensitive, although practically it never is.)
  • Token creation UNIX timestamp in hex
  • Token validity time in seconds in hex
  • Optional future extension fields, which can be ignored if they aren't understood

Blocking Contacts

To mark a contact as blocked a COI client MUST set the "COI-Blocked" header field of the corresponding contact storage message. The actual content of this header field is ignored but is RECOMMENDED to be set to "yes". When a contact is blocked, a COI client SHOULD move any incoming messages to the "Blocked" folder, unless the IMAP server supports the COI capability, in which case the server does that. 

Contact Encryption

Clients MAY encrypt the actual contact data, in this case they MUST use a client-specific key that contains the domain of the client in reversed underscore format. Take for example a client that is called myawesomecoiclient and is available on example.com:

"com_example_myawesomecoiclient_contact": "<encrypted data goes here>" 

Before blocking a contact, the client SHOULD check the last received message of that contact for a DKIM header. In case there is no DKIM header, the client SHOULD warn the user about the possibility, that the sender address might be spoofed.

Contact Storage Message Example

...

From: Simon Tester <simon@coi-dev.org>
To: alice@example.com
COI-Token: 1-tbudgBSg+bHWHiHnlteNzN8TUvI80ygS9IULh4rklEw=-Js0c9gM0xZ1TMWGBQhPwiATiXOiPKRy4Ow1SmZnZu2k=-5c4f90a2-1e13380
Subject: Chat: Contact
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|232888<coi$232888.2323@sample.com>
Chat-Version: 1.0
Content-Type: multipart/mixed;
boundary="RAA14128.773615765/recipientdomain.com"
MIME-Version: 1.0

...

This message contains a contact, do not delete.

--RAA14128.773615765/recipientdomain.com
Content-Type: application/json; charset=UTF-8
Content-Disposition: attachment;
filename="contact.json"
Chat-Content: contact

{
"coi-version": 1,

"content": "contact",

"is_me": false,

"is_visible": true,
  "is_favorite": true,  "status": "idling around...",

"groups": ["friends", "favorite"],

"last_time_contact_sent": "Sun, 3 Dec 2019 20:53:37 +0100",
  "notification": {
"enabled": true,
"types": ["banner", "sound"],
"sound": "friend"
}
}

--RAA14128.773615765/recipientdomain.com
Content-Type: text/vcard; charset=UTF-8
Content-Disposition: attachment;
filename="contact.vcf"

BEGIN:VCARD
VERSION:4.0
EMAIL;TYPE=work:stester@coi-dev.org
EMAIL;PREF=1:simon@coi.me
FN:Simon Tester
N:Tester;Simon;;;ing. jr,M.Sc.
BDAY:--0203
ANNIVERSARY:20090808T1430-0500
GENDER:M
LANG;PREF=1:fr
PHOTO:data:image/jpeg;base64,MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhv
AQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bm
ljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0
<...remainder of base64-encoded data...>
END:VCARD

--RAA14128.773615765/recipientdomain.com--

...

The initial contact information message MUST set the "Content-Type" to "multipart/mixed" and MUST contain at least one text/plain or multipart/alternative, one application/json and one text/vcard part. For the text/json part of the message the "Chat-Content" header MUST be set to "contactinfo". It is RECOMMENDED to send contact information messages in an end-to-end encrypted form. When sending a contact configuration message to several recipients, the message recipients MUST SHOULD NOT be specified in the "BCCTo" header field unless the message is sent to a group conversation. The JSON part only contains the "status" data field in this current specification, along with "coi-version" and "content" fields.

...

From: Alice <me@sample.com> 
To: you@recipientdomain.com
BCC: Alice <me@sample.com>
Subject: Chat: Hello my ...
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|238788<coi$238788.AB29702@sample.com>
Content-Type: multipart/mixed;
boundary="SDKJK2233.23278827/sample.com"
Chat-Version: 1.0
MIME-Version: 1.0
--SDKJK2233.23278827/sample.com
Content-Type: text/plain; charset=UTF-8
Content-Disposition: inline

...

Note that a contact update might also only contain a status update, in this example sent to several active contacts at once by using the BCC headerupdate:

TODO consider contact update message, so that COI clients discard the text/plain part

From: Me Myself <me@sample.com> 
BCC: <you@recipientdomain.com>,Carrol <carrol@otherdomain.com>,Dareen <dareen@somewhere.com>
Subject: Chat: Contact
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|34343<coi$34343.ASDS9702@sample.com>
Content-Type: multipart/mixed;
boundary="23982989.SKDJKJK@sample.com>
Chat-Version: 1.0
MIME-Version: 1.0

--SDKJK2233.23278827/sample.com
Content-Type: text/plain; charset=UTF-8
Content-Disposition: inline

here's my new status!

--SDKJK2233.23278827/sample.com
Content-Type: application/json
Content-Disposition: attachment; charset=UTF-8
filename="contact.json"
Chat-Content: contactinfo

{
"coi-version": 1,
"content": "contact",
"status": "here's my new status!"
}

--SDKJK2233.23278827/sample.com--

...

When a COI client has lost information about a contact and cannot restore the information neither from the COI/CONTACTS IMAP folder nor from the message history, it MAY request the contact information by setting the Chat-Content header field to "contactrequestedcontactrequest". The receiving COI client SHOULD send the contact information to the requesting party. It is RECOMMENDED to ask the recipient for approval before sending the contact information.

...

From: Me Myself <me@sample.com> 
To: You <you@recipientdomain.com>
BCC: Me Myself <me@sample.com>
Subject: Chat: Hello World...
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|S2571BC<coi$S2571BC.2878&8@sample.com>
Content-Type: text/plain; charset=UTF-8
Reference: <coi|434571BC<coi$434571BC.89A707D2@sample.com>
Chat-Version: 1.0
Chat-Content: contactrequestedcontactrequest
MIME-Version: 1.0
Disposition-Notification-To: Me Myself <me@sample.com>

(please send contact information)

...

To identify groups in replies from non-COI-compliant clients, the group ID is embedded into the message ID in the format "coi|groupcoi$group.<groupd ID>.<domain unique value>@<domain>", e.g.

Message-ID: <coi|group<coi$group.4321dcba1234.ABSKDJK23223.293892839@example.com>

...

A COI client sends a message to a group by adding several contacts to the "To" header field. If a group-name exists, a COI client SHOULD specify the group name at the beginning of the with the "ToSubject" header field and separated with a colon from the addresses of the group participants in the "To" header field. To not accidentally spread user-specific nicknames for contacts, COI clients SHOULD either use names authorized by the participants  or use the email addresses without names in the "To" header field.

...


From: Me Myself <me@sample.com>
To: My Crew:c@a.test,joe@where.test,jdoe@one.test;
BCC: Me Myself <me@sample.com> alice@example.com; bob@example.com
Subject: Chat: Hi gang...My Crew
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|group<coi$group.4321dcba1234.S2571BC.2878&8@sample.com>
Content-Type: text/plain; charset=UTF-8
Reference: <coi|group<coi$group.4321dcba1234.434571BC.89A707D2@sample.com>
Chat-Version: 1.0
MIME-Version: 1.0
Disposition-Notification-To: Me Myself <me@sample.com>

Hi gang, hope you're doing fine!

...

From: Alice <alice@example.com> 
To: My Crew: bob@example.com,carrol@example.com,dean@example.com;
Subject: Chat: Group creation
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|group<coi$group.1234abcd4321.238788.AB29702@example.com>
Content-Type: multipart/mixed;
boundary="A22090S.123213/example.com"
Chat-Version: 1.0
MIME-Version: 1.0

--A22090S.123213/example.com
Content-Type: text/plain; charset=UTF-8
Content-Disposition: inline

Hello folks, let's chat!

--A22090S.123213/example.com
Content-Type: application/json; charset=UTF-8
Content-Disposition: attachment;
filename="groupinfo.json"
Chat-Content: groupinfo
Chat-GroupInfoSignature: jkh213k2189821hjksadhjdnbasbndjashks
9283928k23mjk2jj8sdj2b3jda6sj2b

{
"coi-version": 1,
"content": "group",
"group": {
"name": "My Crew",
"description": "",
"avatar": {
"type": "image/jpeg",
"data": "<base64 encoded image data>"
},
"id": "1234abcd4321",
"participants": [
                { "email": "alice@example.com",  "email_hash": "<SHA3-256 hash of the email address>, "public_key": "<base64 encoded key data>", "is_admin": true },
                { "email": "bob@example.com",    "email_hash": "djk232u8uKJHKJK@#2k32kjk2",           "public_key": "23kjkjKK...23kj23KJKH" },
                { "email": "carrol@example.com", "email_hash": "sdhj923kjkjKSKDHJiuiUIKJ<J2223",      "public_key": "jnhjhjJj23989KJKJk" },
                { "email": "dean@example.com",   "email_hash": "ssdlkwsl2023k9823kjkjKSKDHJ23230903", "public_key": "sad2320oslkdl" },
]
}
}

--A22090S.123213/example.com
Content-Type: application/json; charset=UTF-8;
name="contact.json"
Content-Disposition: attachment
Chat-Content: contactinfo

{
"coi-version": 1,
"content": "contact",
"status": "this is my status :-)"
}

--A22090S.123213/example.com
Content-Type: text/vcard; charset=UTF-8;
name="contact.vcf"
Content-Disposition: attachment;
filename="contact.vcf"

BEGIN:VCARD
VERSION:4.0
EMAIL;PREF=1:alice@example.com
FN:Alice Angel
N:Angel;Alice;;;
BDAY:--1209
GENDER:F
LANG;PREF=1:en
END:VCARD

--A22090S.123213/example.com--

...

From: Bob Barr <bob@example.com> 
To: My Crew: alice@example.com, carrol@example.com, dean@example.com;
Subject: Chat: Group left
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|group<coi$group.1234abcd4321.Asd23212.A2328@example.com>
Reference: <coi|group<coi$group.1234abcd4321.238788.AB29702@example.com>
Content-Type: text/plain; charset=UTF-8
Chat-Version: 1.0
Chat-Content: groupleft
MIME-Version: 1.0

left group "My Crew": Bob Barr

...

From: Alice <alice@example.com> 
To: My Crew: bob@example.com,carrol@example.com,dean@example.com;
Subject: Chat: Group creation
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|group<coi$group.1234abcd4321.238788.AB29702@example.com>
Content-Type: multipart/mixed;
boundary="A22090S.123213/example.com"
Chat-Version: 1.0
MIME-Version: 1.0

--A22090S.123213/example.com
Content-Type: text/plain; charset=UTF-8
Content-Disposition: inline

Updated group: Bob is now admin, too.

--A22090S.123213/example.com
Content-Type: application/json; charset=UTF-8
Content-Disposition: attachment;
filename="groupinfo.json"
Chat-Content: groupinfo
Chat-GroupInfoSignature: 2j1312kSDSD3k2DFDFFsadhjdnbasbndjashks
92232KJKJK28k23mjk2jjDFDFF2b2378JHJ2837JHJHJL2398KBNBvb23JHJjj

{
"coi-version": 1,
"content": "group",
"group": {
"name": "My Crew",
"description": "",
"avatar": {
"type": "image/jpeg",
"data": "<base64 encoded image data>"
},
"id": "1234abcd4321",
"participants": [
{ "email": "alice@example.com", "email_hash": "<SHA3-256 hash of the email address>, "public_key": "<base64 encoded key data>", "is_admin": true },
{ "email": "bob@example.com", "email_hash": "djk232u8uKJHKJK@#2k32kjk2", "public_key": "23kjkjKK...23kj23KJKH", "is_admin": true },
{ "email": "carrol@example.com", "email_hash": "sdhj923kjkjKSKDHJiuiUIKJ<J2223", "public_key": "jnhjhjJj23989KJKJk" },
{ "email": "dean@example.com", "email_hash": "ssdlkwsl2023k9823kjkjKSKDHJ23230903", "public_key": "sad2320oslkdl" },
]
}
}

--A22090S.123213/example.com--

...

From: Alice <alice@example.com> 
To: My Crew: bob@example.com, carrol@example.com, dean@example.com;
Subject: Chat: request group info
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|S2571BC<coi$S2571BC.2878&8@sample.com>
Content-Type: text/plain; charset=UTF-8
Reference: <coi|434571BC<coi$434571BC.89A707D2@sample.com>
Chat-Version: 1.0
Chat-Content: grouprequested
MIME-Version: 1.0
Disposition-Notification-To: Alice <alice@example.com>

(please send group information)

...

From: Me Myself <me@sample.com> 
To: You <you@recipientdomain.com>
BCC: Me Myself <me@sample.com>
Subject: Chat: Hello COI...
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|S2571BC<coi$S2571BC.2878&8@sample.com>
Content-Type: text/plain; charset=UTF-8
Content-Disposition: pinned;
timeout=Tue, 5 Dec 2019 0:00:00 +0100
Reference: <coi|434571BC<coi$434571BC.89A707D2@sample.com>
Chat-Version: 1.0
MIME-Version: 1.0
Disposition-Notification-To: Me Myself <me@sample.com>

Hello COI world, this message is pinned!

...

From: Me Myself <me@sample.com> 
To: My Crew: you@recipientdomain.com, carrol@otherdomain.com, dareen@somewhere.com;
BCC: Me Myself <me@sample.com>
Subject: Chat: poll - Which movie?
Date: Mon, 4 Dec 2019 15:51:37 +0100
Message-ID: <coi|group<coi$group.23298982923929.238788.AB29702@sample.com>
Content-Type: multipart/alternative;
boundary="unique-boundary-1"
Reference: <coi|434571BC<coi$434571BC.89A707D2@sample.com>
Chat-Version: 1.0
Disposition-Notification-To: Me Myself <me@sample.com>
Content-Disposition: pinned;
timeout=Tue, 5 Dec 2019 0:00:00 +0100
MIME-Version: 1.0

--unique-boundary-1
Content-Type: text/html; charset=UTF-8

<html><body>
<p>Which movie: &quot;Avengers&quot;, &quot;Matrix&quot;, &quot;Aliens&quot;?</p>
<p><i>This message is a chat message - consider using <a href="https://myawesomecoiapp.com">my awesome COI app</a> for best experience!</i></p>
</body></html>

--unique-boundary-1
Content-Type: application/json; charset=UTF-8
Content-Disposition: attachment;
filename="poll.json"
Chat-Content: poll

{
"coi-version": 1,
"content": "poll",
"poll": {
"title": "Which movie?",
"options": [ { "description": "Avengers" }, { "description": "Matrix" }, { "description": "Aliens" } ],
"show-intermediate-results": false,
"data-type": "image/webp",
"data": "SKJ098788787K878J878...rest of base64 encoded WebP image"
}
}

--unique-boundary-1--

...

From: Me Myself <me@sample.com> 
To: My Crew: you@recipientdomain.com, carrol@otherdomain.com, dareen@somewhere.com;
BCC: Me Myself <me@sample.com>
Subject: Chat: vote - Which movie?
Date: Mon, 4 Dec 2019 16:51:37 +0100
Message-ID: <coi|group<coi$group.23298982923929.21382788.2932UJH@sample.com>
Content-Type: multipart/alternative;
boundary="unique-boundary-1"
Reference: <coi|434571BC<coi$434571BC.89A707D2@sample.com>
Chat-Version: 1.0
MIME-Version: 1.0

--unique-boundary-1
Content-Type: text/html; charset=UTF-8

<html><body>
<p>Which movie: voted for &quot;Matrix&quot; and &quot;Aliens&quot;.</p>
<p><i>This message is a chat message - consider using <a href="https://myawesomecoiapp.com">my awesome COI app</a> for best experience!</i></p>
</body></html>

--unique-boundary-1
Content-Type: application/json; charset=UTF-8
Content-Disposition: attachment;
filename="poll.json"
Chat-Content: poll;
reference=<coi|group<coi$group.23298982923929.238788.AB29702@sample.com>

{
"coi-version": 1,
"content": "pollvote",
"votes": [1,2]

...

From: Me Myself <me@sample.com> 
To: My Crew: you@recipientdomain.com, carrol@otherdomain.com, dareen@somewhere.com;
BCC: Me Myself <me@sample.com>
Subject: Chat: vote - Which movie?
Date: Mon, 4 Dec 2019 16:51:37 +0100
Message-ID: <coi|group<coi$group.23298982923929.21382788.2932UJH@sample.com>
Content-Type: multipart/alternative;
boundary="unique-boundary-1"
Reference: <coi|434571BC<coi$434571BC.89A707D2@sample.com>
Chat-Version: 1.0
MIME-Version: 1.0

--unique-boundary-1
Content-Type: text/html; charset=UTF-8

<html><body>
<p>Which movie: voted for &quot;Matrix&quot; and &quot;Aliens&quot;.</p>
<p><i>This message is a chat message - consider using <a href="https://myawesomecoiapp.com">my awesome COI app</a> for best experience!</i></p>
</body></html>

--unique-boundary-1
Content-Type: application/json; charset=UTF-8
Content-Disposition: attachment;
filename="poll.json"
Chat-Content: pollclose;
reference=<coi|group<coi$group.23298982923929.238788.AB29702@sample.com>

{
"coi-version": 1,
"content": "pollclose",
"result": {
"index": 2,
"pinned": true
}
}

--unique-boundary-1--

...

  • Having a reference that starts with a message ID starting with "<coi|<coi$", or
  • Having an "in-reply-to" header field with a message-ID that starts with "<coi|<coi$

For moving the message to COI/CHATS a COI client has the following options:

...