Warning
The project is still under development and testing!
Mailio Server implementation based on Mailio MIRs specifications.
version: 1.0
scheme: http # http or https
port: 8080
title: Mailio Server
description: Mailio Server implementation based on mirs.mail.io specification
swagger: true
mode: release # "debug": or "release"
mailio:
diskSpace: 524288000 # initial maximum disk size in bytes (500 MB)
authenticationPath: /api/v1/didauth # don't change unless you know what you're doing
messagingPath: /api/v1/mtp/message # don't change unless you know what you're doing
serverKeysPath: test_server_keys.json
readVsReceived: 30 # 30% read makes a message go to goodreads, less to other
serverDomain: mio.example.com # where this server is located on the internet
serverSubdomainQueryList: # standard subdomains for the mail server. e.g. mio.example.com, mailio.example.com, ...
- prefix: mio
- prefix: mailio
- prefix: didcomm
serverHandshake:
id: "mail_io_server_handshake" # guessable id
type: 3 # 3 - server specific, 1 = personal, 2 = signup
minimumLevel: 1 # reCaptchaV3
subtypes:
- subtype: 1
frequencyMinutes: 0 # 0 - no limit
- subtype: 2 # product updates
frequencyMinutes: 43800 # 30 days
- subtype: 3 # security updates
frequencyMinutes: 0
- subtype: 4 # promotional updates
frequencyMinutes: 43800 # 30 days
- subtype: 5
frequencyMinutes: 43800 # 30 days
- subtype: 6
frequencyMinutes: 43800 # 30 days
domains:
- domain: example.io # e.g. example.com
- domain: example.com # e.g. otherdomain.com
couchdb:
host: localhost
port: 5984
scheme: http
username: admin
password: YOURPASSWORD
redis:
host: localhost
port: 6379
username: default
password: YOURPASSWORD
queue:
concurrency: 50
prometheus:
enabled: true
username: prometheus
password: YOURPASSWORD
# currently only mailgun supported
# check docs to implement: https://github.com/mailio/go-mailio-mailgun-smtp-handler
smtpservers:
- provider: mailgun
webhookurl: /webhook/mailgun_mime
webhookkey: a55...
domains:
- domain: example.com
sendapikey: 78...
- domain: otherexample.com
sendapikey: 674...
storage:
type: s3
key: ATR...
secret: D+...
bucket: mailio-bucket
region: us-east-1
diskusagehandlers:
- provider: aws
path: mailio-attachments/mailio-attachments/user-attachment-inventory
Ensure all passwords, keys, and sensitive information are correctly set in a secure manner.
For production, change the scheme to https
and update the host and serverDomain
to your actual domain.
The serverSubdomainQueryList is a list of potential third-party subdomains that our server will search for when communicating using the DIDComm protocol. This setting ensures that communication remains functional even if your serverDomain
is a subdomain rather than the root domain.
For instance, if your serverDomain
is mio.example.com
instead of example.com
, and people are sharing only their email addresses (as they commonly do), the communication will still work seamlessly.
Example scenario
- DID (Decentralized Identifier): did:web:mio.example.com:0x606d2...
- Email Address: myemail@example.com
In this example:
- The DID uses the subdomain mio.example.com. This is our servers domain.
- The email addresses, however, are associated with the root domain example.com.
By including mio.example.com
in the serverSubdomainQueryList
, our server can correctly interpret and route communications, when requesting remote DID documents, ensuring that messages sent to myemail@example.com
can be processed using the DID did:web:mio.example.com:0x606d2...
This setting is crucial for maintaining compatibility and functionality in scenarios where subdomains are used for DIDs, while emails are tied to the root domain.
git clone https://github.com/mailio/go-mailio-server.git
Create configuration file conf.yaml
in the root folder
docker-compose up -d
TDB (Kubernetes) or Helm chart maybe
- Clone this repository
- Create
conf.yaml
file swag init --parseDependency=true
to re-create swagger documentationgo run setup.go main.go
to run the app
The application supports the integration of multiple SMTP service providers through a plugin interface. This interface allows for the seamless addition of new email service providers as needed, without requiring significant changes to the application's core functionality. The current implementation includes support for Mailgun, with the architecture designed to easily accommodate additional providers.
The SMTP handler configuration is driven by the application's global configuration, typically defined in a configuration file (cony.yaml
). Each SMTP provider's settings, such as API keys and domain information, are specified within this configuration file under the MailWebhooks
section.
mailwebhooks:
- provider: mailgun
domain: sndmail.example.com
sendapikey: sendapikey
webhookurl: /webhook/mailgun_mime
webhookkey: webhookkey
Implement the SMTP handler interface, ensuring that it satisfies any required methods:
type SmtpHandler interface {
// ReceiveMail is a method called on the specific ESP handler webhook implementation
ReceiveMail(request http.Request) (*mailiosmtp.Mail, error)
// SendMimeMail returns generated message id or error
SendMimeMail(mime []byte, to []mail.Address) (string, error)
}
Example implementation here
You can find all helper functions here
// Parsing raw EML messages using enmime library: https://github.com/emime
func ParseMime(mime []byte) (*mailiosmtp.Mail, error)
// converts a message to a mime message preparing it for sending
func ToMime(msg *mailiosmtp.Mail, mailhost string) ([]byte, error) {
/*
Recommeneded to handle the following bounce reasons:
Mailbox Does Not Exist — SMTP Reply Code = 550, SMTP Status Code = 5.1.1
Message Too Large — SMTP Reply Code = 552, SMTP Status Code = 5.3.4
Mailbox Full — SMTP Reply Code = 552, SMTP Status Code = 5.2.2
Message Content Rejected — SMTP Reply Code = 500, SMTP Status Code = 5.6.1
Unknown Failure — SMTP Reply Code = 554, SMTP Status Code = 5.0.0
Temporary Failure — SMTP Reply Code = 450, SMTP Status Code = 4.0.0
where 4.x.x codes are soft bounces, and 5.x..x codes are hard bounces
*/
func ToBounce(recipient mail.Address, msg mailiosmtp.Mail, bounceCode string, bounceReason string, mailhost string) ([]byte, error)
// Collecting complaints. Report complaint to designated recipient (something like complaints@mail.io).
func ToComplaint(recipient mail.Address, reporter mail.Address, msg mailiosmtp.Mail, complaintReason string, mailhost string) ([]byte, error)
// add your provider in th api_mailreceive_webhook.go registration loop. Example:
for _, wh := range global.Conf.MailWebhooks {
if wh.Provider == "your-provider-name" {
handler := yourprovider.NewYourProviderSmtpHandler(wh.APIKey, wh.OtherConfig)
smtpmodule.RegisterSmtpHandler(wh.Provider, handler)
}
}
Add your provider configuration under conf.yaml
-> mailwebhooks
:
mailwebhooks:
- provider: mailgun
domain: sndmail.example.com
sendapikey: sendapikey
webhookurl: /webhook/mailgun_mime
webhookkey: webhookkey
- provider: my-provider-name
domain: my-provider-domain
sendapikey: apikey
webhookurl: /webhook/my-provider-webhook-url
webhookkey: not-used