Golang package that generates clean, responsive HTML e-mails for sending transactional mail

Overview

Hermes

Build Status Go Report Card Go Coverage Godoc FOSSA Status

Hermes is the Go port of the great mailgen engine for Node.js. Check their work, it's awesome! It's a package that generates clean, responsive HTML e-mails for sending transactional e-mails (welcome e-mails, reset password e-mails, receipt e-mails and so on), and associated plain text fallback.

Demo

Usage

First install the package:

go get -u github.com/matcornic/hermes/v2

Starting from release v2.0.0, Hermes uses Go modules. The latest version of Hermes requires at least Go 1.11 with gomodules enabled. You can still use an Hermes release compatible with prior Go versions by using v1.2.0 release

Then, start using the package by importing and configuring it:

// Configure hermes by setting a theme and your product info
h := hermes.Hermes{
    // Optional Theme
    // Theme: new(Default) 
    Product: hermes.Product{
        // Appears in header & footer of e-mails
        Name: "Hermes",
        Link: "https://example-hermes.com/",
        // Optional product logo
        Logo: "http://www.duchess-france.org/wp-content/uploads/2016/01/gopher.png",
    },
}

Next, generate an e-mail using the following code:

email := hermes.Email{
    Body: hermes.Body{
        Name: "Jon Snow",
        Intros: []string{
            "Welcome to Hermes! We're very excited to have you on board.",
        },
        Actions: []hermes.Action{
            {
                Instructions: "To get started with Hermes, please click here:",
                Button: hermes.Button{
                    Color: "#22BC66", // Optional action button color
                    Text:  "Confirm your account",
                    Link:  "https://hermes-example.com/confirm?token=d9729feb74992cc3482b350163a1a010",
                },
            },
        },
        Outros: []string{
            "Need help, or have questions? Just reply to this email, we'd love to help.",
        },
    },
}

// Generate an HTML email with the provided contents (for modern clients)
emailBody, err := h.GenerateHTML(email)
if err != nil {
    panic(err) // Tip: Handle error with something else than a panic ;)
}

// Generate the plaintext version of the e-mail (for clients that do not support xHTML)
emailText, err := h.GeneratePlainText(email)
if err != nil {
    panic(err) // Tip: Handle error with something else than a panic ;)
}

// Optionally, preview the generated HTML e-mail by writing it to a local file
err = ioutil.WriteFile("preview.html", []byte(emailBody), 0644)
if err != nil {
    panic(err) // Tip: Handle error with something else than a panic ;)
}

This code would output the following HTML template:

And the following plain text:


------------
Hi Jon Snow,
------------

Welcome to Hermes! We're very excited to have you on board.

To get started with Hermes, please click here: https://hermes-example.com/confirm?token=d9729feb74992cc3482b350163a1a010

Need help, or have questions? Just reply to this email, we'd love to help.

Yours truly,
Hermes - https://example-hermes.com/

Copyright © 2017 Hermes. All rights reserved.

Theme templates will be embedded in your application binary. If you want to use external templates (for configuration), use your own theme by implementing hermes.Theme interface with code searching for your files.

More Examples

To run the examples, go to examples folder, then run go run -a *.go. HTML and Plaintext example should be created in given theme folders.

Optionaly you can set the following variables to send automatically the emails to one your mailbox. Nice for testing template in real email clients.

  • HERMES_SEND_EMAILS=true
  • HERMES_SMTP_SERVER=<smtp_server> : for Gmail it's smtp.gmail.com
  • HERMES_SMTP_PORT=<smtp_port> : for Gmail it's 465
  • HERMES_SENDER_EMAIL=<your_sender_email>
  • HERMES_SENDER_IDENTITY=<the sender name>
  • HERMES_SMTP_USER=<smtp user> : usually the same than HERMES_SENDER_EMAIL
  • HERMES_TO=<recipients emails>: split by commas like [email protected],[email protected]

The program will ask for your SMTP password. If needed, you can set it with HERMES_SMTP_PASSWORD variable (but be careful where you put this information !)

Plaintext E-mails

To generate a plaintext version of the e-mail, simply call GeneratePlainText function:

// Generate plaintext email using hermes
emailText, err := h.GeneratePlainText(email)
if err != nil {
    panic(err) // Tip: Handle error with something else than a panic ;)
}

Supported Themes

The following open-source themes are bundled with this package:

RTL Support

To change the default text direction (left-to-right), simply override it as follows:

// Configure hermes by setting a theme and your product info
h := hermes.Hermes {
    // Custom text direction
    TextDirection: hermes.TDRightToLeft,
}

Language Customizations

To customize the e-mail's greeting ("Hi") or signature ("Yours truly"), supply custom strings within the e-mail's Body:

email := hermes.Email{
    Body: hermes.Body{
        Greeting: "Dear",
        Signature: "Sincerely",
    },
}

To use a custom title string rather than a greeting/name introduction, provide it instead of Name:

email := hermes.Email{
    Body: hermes.Body{
        // Title will override `Name`
        Title: "Welcome to Hermes",
    },
}

To customize the Copyright, override it when initializing Hermes within your Product as follows:

// Configure hermes by setting a theme and your product info
h := hermes.Hermes{
    // Optional Theme
    // Theme: new(Default)
    Product: hermes.Product{
        // Appears in header & footer of e-mails
        Name: "Hermes",
        Link: "https://example-hermes.com/",
        // Custom copyright notice
        Copyright: "Copyright © 2017 Dharma Initiative. All rights reserved."
    },
}

To use a custom fallback text at the end of the email, change the TroubleText field of the hermes.Product struct. The default value is If you’re having trouble with the button '{ACTION}', copy and paste the URL below into your web browser.. The {ACTION} placeholder will be replaced with the corresponding text of the supplied action button:

// Configure hermes by setting a theme and your product info
h := hermes.Hermes{
    // Optional Theme
    // Theme: new(Default)
    Product: hermes.Product{
        // Custom trouble text
        TroubleText: "If the {ACTION}-button is not working for you, just copy and paste the URL below into your web browser."
    },
}

Since v2.1.0, Hermes is automatically inlining all CSS to improve compatibility with email clients, thanks to Premailer. You can disable this feature by setting DisableCSSInlining of Hermes struct to true.

h := hermes.Hermes{
    ...
    DisableCSSInlining: true,
}

Elements

Hermes supports injecting custom elements such as dictionaries, tables and action buttons into e-mails.

Action

To inject an action button in to the e-mail, supply the Actions object as follows:

email := hermes.Email{
    Body: hermes.Body{
        Actions: []hermes.Action{
            {
                Instructions: "To get started with Hermes, please click here:",
                Button: hermes.Button{
                    Color: "#22BC66", // Optional action button color
                    Text:  "Confirm your account",
                    Link:  "https://hermes-example.com/confirm?token=d9729feb74992cc3482b350163a1a010",
                },
            },
        },
    },
}

Alternatively, instead of having a button, an action can be an invite code as follows:

email := hermes.Email{
    Body: hermes.Body{
        Actions: []hermes.Action{
            {
                Instructions: "To get started with Hermes, please use the invite code:",
                InviteCode: "123456",
            },
        },
    },
}

To inject multiple action buttons in to the e-mail, supply another struct in Actions slice Action.

Table

To inject a table into the e-mail, supply the Table object as follows:

email := hermes.Email{
    Body: hermes.Body{
        Table: hermes.Table{
            Data: [][]hermes.Entry{
                // List of rows
                {   
                    // Key is the column name, Value is the cell value
                    // First object defines what columns will be displayed
                    {Key: "Item", Value: "Golang"},
                    {Key: "Description", Value: "Open source programming language that makes it easy to build simple, reliable, and efficient software"},
                    {Key: "Price", Value: "$10.99"},
                },
                {
                    {Key: "Item", Value: "Hermes"},
                    {Key: "Description", Value: "Programmatically create beautiful e-mails using Golang."},
                    {Key: "Price", Value: "$1.99"},
                },
            },
            Columns: hermes.Columns{
                // Custom style for each rows
                CustomWidth: map[string]string{
                    "Item":  "20%",
                    "Price": "15%",
                },
                CustomAlignment: map[string]string{
                    "Price": "right",
                },
            },
        },
    },
}

Dictionary

To inject key-value pairs of data into the e-mail, supply the Dictionary object as follows:

email := hermes.Email{
    Body: hermes.Body{
        Dictionary: []hermes.Entry{
            {Key: "Date", Value: "20 November 1887"},
            {Key: "Address", Value: "221B Baker Street, London"},
        },
    },
}

Free Markdown

If you need more flexibility in the content of your generated e-mail, while keeping the same format than any other e-mail, use Markdown content. Supply the FreeMarkdown object as follows:

email := hermes.Email{
		Body: hermes.Body{
			FreeMarkdown: `
> _Hermes_ service will shutdown the **1st August 2017** for maintenance operations. 

Services will be unavailable based on the following schedule:

| Services | Downtime |
| :------:| :-----------: |
| Service A | 2AM to 3AM |
| Service B | 4AM to 5AM |
| Service C | 5AM to 6AM |

---

Feel free to contact us for any question regarding this matter at [[email protected]](mailto:[email protected]) or in our [Gitter](https://gitter.im/)

`,
		},
	}
}

This code would output the following HTML template:

And the following plaintext:

------------
Hi Jon Snow,
------------

> 
> 
> 
> Hermes service will shutdown the *1st August 2017* for maintenance
> operations.
> 
> 

Services will be unavailable based on the following schedule:

+-----------+------------+
| SERVICES  |  DOWNTIME  |
+-----------+------------+
| Service A | 2AM to 3AM |
| Service B | 4AM to 5AM |
| Service C | 5AM to 6AM |
+-----------+------------+

Feel free to contact us for any question regarding this matter at [email protected] ( [email protected] ) or in our Gitter ( https://gitter.im/ )

Yours truly,
Hermes - https://example-hermes.com/

Copyright © 2017 Hermes. All rights reserved.

Be aware that this content will replace existing tables, dictionary and actions. Only intros, outros, header and footer will be kept.

This is helpful when your application needs sending e-mails, wrote on-the-fly by adminstrators.

Markdown is rendered with Blackfriday, so every thing Blackfriday can do, Hermes can do it as well.

Troubleshooting

  1. After sending multiple e-mails to the same Gmail / Inbox address, they become grouped and truncated since they contain similar text, breaking the responsive e-mail layout.

Simply sending the X-Entity-Ref-ID header with your e-mails will prevent grouping / truncation.

Contributing

See CONTRIBUTING.md

License

Apache 2.0

FOSSA Status

Issues
  • Add support for windows 10 mail/Outlook

    Add support for windows 10 mail/Outlook

    This adds support into the default template for M$ based email clients e.g Windows 10 Mail and Outlook. Without this the button is not visible at all in those clients.

    opened by mvrhov 20
  • On Oct 29, 2018 started getting problems deployment with blackfriday.v2

    On Oct 29, 2018 started getting problems deployment with blackfriday.v2

    During deployments I started getting this error:

    ../github.com/matcornic/hermes/hermes.go:8:2: cannot find package "github.com/russross/blackfriday/v2" in any of: /usr/local/go/src/github.com/russross/blackfriday/v2 (from $GOROOT) /go/src/github.com/russross/blackfriday/v2 (from $GOPATH)

    I have worked around the problem by forking hermes and changing blackfriday references from github.com to gopkg.in.

    opened by croaker8 13
  • Feat/improve css compatibility

    Feat/improve css compatibility

    Great news, a friend of mine has lent me a Windows with a licensed Outlook. So I can fix the Outlook compatibility issue.

    So this PR contains code for:

    • Fix outlook missing button #59
    • Fix outlook quotes display
    • Add CSS inlining by default with https://github.com/vanng822/go-premailer/premailer (now Outlook displays the text as centered)

    => Replaces PR #48

    Hey @kauffj @loeffel-io @vjeantet @dmuriel @elliots 🙌 Can you test this PR on your side ?

    It worked for me on a Windows 10 with latest version of Outlook. I think it's still perfectible, but it does the work.

    Edit: the size of the button now adapts to content in default theme.

    opened by matcornic 10
  • When I try to install 1.2 version it returns an error

    When I try to install 1.2 version it returns an error

    go get -u github.com/matcornic/hermes

    ../github.com/matcornic/hermes/hermes.go:8:2: cannot find package "github.com/russross/blackfriday/v2" in any of: /usr/local/go/src/github.com/russross/blackfriday/v2 (from $GOROOT) /go/src/github.com/russross/blackfriday/v2 (from $GOPATH)

    opened by AkezhanOb1 6
  • undefined: blackfriday.Run

    undefined: blackfriday.Run

    New install:

    vendor/github.com/matcornic/hermes/hermes.go:76:23: undefined: blackfriday.Run

    Seems blackfriday API has changed:

    // ToHTML converts Markdown to HTML
        func (c Markdown) ToHTML() template.HTML {
                return template.HTML(blackfriday.Run([]byte(string(c))))
        }
    
    need user feedback 
    opened by AlexDunmow 5
  • Customisation of 'Action Trouble Text'

    Customisation of 'Action Trouble Text'

    Currently I can't find any possibility to change the 'action trouble text' inside the footer:

    If you’re having trouble with the button 'Hier Anmelden', copy and paste the URL below into your web browser.
    

    This makes it impossible to fully customise the email template (e.g. i18n).

    I would propose the following changes: https://github.com/fridolin-koch/hermes/commit/44be3778410a55d7aa5f6951118d4c70de9cc0ad

    I've you are happy with the proposed solution, I can sent a PR.

    Best Regards, Frido

    enhancement 
    opened by fridolin-koch 5
  • Added InviteCode action.

    Added InviteCode action.

    Description

    I'm working on a personal project that needs to email users an invite code. This PR adds an optional InviteCode field in the action struct.

    Preview

    Screen Shot 2019-12-23 at 11 30 47 AM
    opened by mack 4
  • Use /v2 suffix for new go modules v2

    Use /v2 suffix for new go modules v2

    Hey @matcornic

    thanks for merging my changes (#44) related to supporting go modules. Because you created a new major version (v2) for the go module changes, we should reflect that in go.mod.

    In go modules, if the major version changes, the import path also changes. So I also updated all the examples and the go get in the README.

    Thanks, Atrox

    opened by Atrox 4
  • add support for go modules

    add support for go modules

    Hey,

    I switched to go modules on my projects and because blackfriday is now supporting go modules too, I'm unable to use hermes because you are importing it with gopkg.in but blackfriday's module path is github.com.

    To get the tests working, I switched from gometalinter to golangci-lint. gometalinter does not support go modules yet and it seems other popular projects are switching to golangci-lint too.

    My current changes will only work for go 1.11+ projects, if you want we can check in the vendor directory generated by go mod vendor to support the versions below.

    opened by Atrox 4
  • Use blackfriday v2

    Use blackfriday v2

    Hello Mathieu,

    Looks like you upgraded the blackfriday package in dep, but not in your regular imports, which breaks the build. This PR is a proposal to fix it.

    Not sure if the Gopkg.toml should also be updated for the constraint path of blackfriday, I'm not (yet) a regular user of dep.

    Thanks, Pierre

    opened by jinroh 4
  • Unconfigured Email

    Unconfigured Email

    I'm running some tests using hermes, but one of the emails appears unconfigured to me. Did I do something wrong?

    E-mail image

    http://prntscr.com/gj4e4z

    My Script

    body, err := h.GenerateHTML(email)
    if err != nil {
    	panic(err)
    }
    
    emailAddress := "my-email"
    to := []string{emailAddress}
    title := "Recuperar senha"
    
    mime := "MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n"
    subject := "Subject: " + title + "!\n"
    msg := []byte(subject + mime + "\n" + body)
    addr := "smtp.gmail.com:587"
    
    auth := smtp.PlainAuth("", emailAddress, "my-password", "smtp.gmail.com")
    if err := smtp.SendMail(addr, auth, emailAddress, to, msg); err != nil {
    	log.Println("Error")
    } else {
    	log.Println("Success")
    }
    

    Content Email

    Date: Sat, 09 Sep 2017 11:00:18 -0700 (PDT)
    From: my-email
    Subject: Recuperar senha!
    MIME-version: 1.0;
    Content-Type: text/html; charset="UTF-8";
    
    
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
      <style type="text/css" rel="stylesheet" media="all">
         
        *:not(br):not(tr):not(html) {
          font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
          -webkit-box-sizing: border-box;
          box-sizing: border-box;
        }
        body {
          width: 100% !important;
          height: 100%;
          margin: 0;
          line-height: 1.4;
          background-color: #2c3e50;
          color: #74787E;
          -webkit-text-size-adjust: none;
        }
        a {
          color: #3869D4;
        }
    
         
        .email-wrapper {
          width: 100%;
          margin: 0;
          padding: 0;
          background-color: #2c3e50;
        }
        .email-content {
          width: 100%;
          margin: 0;
          padding: 0;
        }
         
        .email-masthead {
          padding: 25px 0;
          text-align: center;
        }
        .email-masthead_logo {
          max-width: 400px;
          border: 0;
        }
        .email-masthead_name {
          font-size: 16px;
          font-weight: bold;
          color: #2F3133;
          text-decoration: none;
          text-shadow: 0 1px 0 white;
        }
        .email-logo {
          max-height: 50px;
        }
         
        .email-body {
          width: 100%;
          margin: 0;
          padding: 0;
          border-top: 1px solid #EDEFF2;
          border-bottom: 1px solid #EDEFF2;
          background-color: #FFF;
        }
        .email-body_inner {
          width: 570px;
          margin: 0 auto;
          padding: 0;
        }
        .email-footer {
          width: 570px;
          margin: 0 auto;
          padding: 0;
          text-align: center;
        }
        .email-footer p {
          color: #eaeaea;
        }
        .body-action {
          width: 100%;
          margin: 30px auto;
          padding: 0;
          text-align: center;
        }
    
        .body-dictionary {
          width: 100%;
          overflow: hidden;
          margin: 20px auto 20px;
          padding: 0;
        }
        .body-dictionary dt {
          clear: both;
          color: #000;
          font-weight: bold;
          float: left;
          width: 50%;
          padding: 0;
          margin: 0;
          margin-bottom: 0.3em;
        }
        .body-dictionary dd {
          float: left;
          width: 50%;
          padding: 0;
          margin: 0;
        }
        .body-sub {
          margin-top: 25px;
          padding-top: 25px;
          border-top: 1px solid #EDEFF2;
          table-layout: fixed;
        }
        .body-sub a {
          word-break: break-all;
        }
        .content-cell {
          padding: 35px;
        }
        .align-right {
          text-align: right;
        }
         
        h1 {
          margin-top: 0;
          color: #2F3133;
          font-size: 19px;
          font-weight: bold;
        }
        h2 {
          margin-top: 0;
          color: #2F3133;
          font-size: 16px;
          font-weight: bold;
        }
        h3 {
          margin-top: 0;
          color: #2F3133;
          font-size: 14px;
          font-weight: bold;
        }
        blockquote {
          margin: 1.7rem 0;
          padding-left: 0.85rem;
          border-left: 10px solid #F0F2F4;
        }
        blockquote p {
            font-size: 1.1rem;
            color: #999;
        }
        blockquote cite {
            display: block;
            text-align: right;
            color: #666;
            font-size: 1.2rem;
        }
        cite {
          display: block;
          font-size: 0.925rem; 
        }
        cite:before {
          content: "\2014 \0020";
        }
        p {
          margin-top: 0;
          color: #74787E;
          font-size: 16px;
          line-height: 1.5em;
        }
        p.sub {
          font-size: 12px;
        }
        p.center {
          text-align: center;
        }
        table {
          width: 100%;
        }
        th {
          padding: 0px 5px;
          padding-bottom: 8px;
          border-bottom: 1px solid #EDEFF2;
        }
        th p {
          margin: 0;
          color: #9BA2AB;
          font-size: 12px;
        }
        td {
          padding: 10px 5px;
          color: #74787E;
          font-size: 15px;
          line-height: 18px;
        }
        .content {
          align: center;
          padding: 0;
        }
         
        .data-wrapper {
          width: 100%;
          margin: 0;
          padding: 35px 0;
        }
        .data-table {
          width: 100%;
          margin: 0;
        }
        .data-table th {
          text-align: left;
          padding: 0px 5px;
          padding-bottom: 8px;
          border-bottom: 1px solid #EDEFF2;
        }
        .data-table th p {
          margin: 0;
          color: #9BA2AB;
          font-size: 12px;
        }
        .data-table td {
          padding: 10px 5px;
          color: #74787E;
          font-size: 15px;
          line-height: 18px;
        }
         
        .button {
          display: inline-block;
          width: 100%;
          background-color: #00948d;
          color: #ffffff;
          font-size: 15px;
          line-height: 45px;
          text-align: center;
          text-decoration: none;
          -webkit-text-size-adjust: none;
          mso-hide: all;
        }
         
        @media only screen and (max-width: 600px) {
          .email-body_inner,
          .email-footer {
            width: 100% !important;
          }
        }
      </style>
    </head>
    <body dir="ltr">
      <table class="email-wrapper" width="100%" cellpadding="0" cellspacing="0">
        <tr>
          <td class="content">
            <table class="email-content" width="100%" cellpadding="0" cellspacing="0">
              
              <tr>
                <td class="email-masthead">
                  <a class="email-masthead_name" href="https://example-hermes.com/" target="_blank">
                    
                      <img src="http://www.duchess-france.org/wp-content/uploads/2016/01/gopher.png" class="email-logo" />
                    
                    </a>
                </td>
              </tr>
    
              
              <tr>
                <td class="email-body" width="100%">
                  <table class="email-body_inner" align="center" width="570" cellpadding="0" cellspacing="0">
                    
                    <tr>
                      <td class="content-cell">
                        <h1>Hi Jon Snow,</h1>
                        
                            
                              
                                <p>You have received this email because a password reset request for Hermes account was received.</p>
                              
                            
                        
                        
    
                          
    
                          
                          
                            
                            
                            
                          
    
                          
                          
                            
                              
                                <p>Click the button below to reset your password:</p>
                                <table class="body-action" align="center" width="100%" cellpadding="0" cellspacing="0">
                                  <tr>
                                    <td align="center">
                                      <div>
                                        <a href="https://hermes-example.com/reset-password?token=d9729feb74992cc3482b350163a1a010" class="button" style="background-color: #DC4D2F" target="_blank">
                                          Reset your password
                                        </a>
                                      </div>
                                    </td>
                                  </tr>
                                </table>
                              
                            
                          
    
                        
                         
                            
                              
                                <p>If you did not request a password reset, no further action is required on your part.</p>
                              
                            
                          
    
                        <p>
                          Thanks,
                          <br />
                          Hermes
                        </p>
    
                        
                           
                            <table class="body-sub">
                              <tbody>
                                  
                                    <tr>
                                      <td>
                                        <p class="sub">If you’re having trouble with the button &#39;Reset your password&#39;, copy and paste the URL below into your web browser.</p>
                                        <p class="sub"><a href="https://hermes-example.com/reset-password?token=d9729feb74992cc3482b350163a1a010">https://hermes-example.com/reset-password?token=d9729feb74992cc3482b350163a1a010</a></p>
                                      </td>
                                    </tr>
                                  
                              </tbody>
                            </table>
                          
                        
                      </td>
                    </tr>
                  </table>
                </td>
              </tr>
              <tr>
                <td>
                  <table class="email-footer" align="center" width="570" cellpadding="0" cellspacing="0">
                    <tr>
                      <td class="content-cell">
                        <p class="sub center">
                          Copyright © 2017 Hermes. All rights reserved.
                        </p>
                      </td>
                    </tr>
                  </table>
                </td>
              </tr>
            </table>
          </td>
        </tr>
      </table>
    </body>
    </html>
    ```
    need user feedback 
    opened by wilsontamarozzi 4
  • the theme renders two invitecode block

    the theme renders two invitecode block

    image

    this was coused by https://github.com/matcornic/hermes/commit/b49681588c91ffdbdb768a09fcfb460e535baafe

    there are two if statements to render the InviteCode . i think the first one should be deleted

                                  {{ if $action.InviteCode }}
                                    <div style="margin-top:30px;margin-bottom:30px">
                                      <table class="body-action" align="center" width="100%" cellpadding="0" cellspacing="0">
                                        <tr>
                                          <td align="center">
                                            <table align="center" cellpadding="0" cellspacing="0" style="padding:0;text-align:center">
                                              <tr>
                                                <td style="display:inline-block;border-radius:3px;font-family:Consolas, monaco, monospace;font-size:28px;text-align:center;letter-spacing:8px;color:#555;background-color:#eee;padding:20px">
                                                  {{ $action.InviteCode }}
                                                </td>
                                              </tr>
                                            </table>
                                          </td>
                                        </tr>
                                      </table>
                                    </div>
                                  {{ end }}   
                                  {{safe "<![endif]-->" }}
    
                                        <div>
                                          {{ if $action.Button.Text }}
                                            <a href="{{ $action.Button.Link }}" class="button" style="{{ with $action.Button.Color }}background-color: {{ . }};{{ end }} {{ with $action.Button.TextColor }}color: {{ . }};{{ end }} width: {{$width}}px;" target="_blank">
                                              {{ $action.Button.Text }}
                                            </a>
                                          {{end}}
                                          {{ if $action.InviteCode }}
                                            <span class="invite-code">{{ $action.InviteCode }}</span>
                                          {{end}}
                                        </div>
    

    for any one looking for a temporary solution , just copy the flat.go or default.go , and delete the codes in first code block.

    opened by catusax 0
  • Adding newline to Instructions: element

    Adding newline to Instructions: element

    Hi, First of all thank you for the package and community.

    I just started exploring hermes. I am looking to add multiline message to email. In below code I tried using \n, \r, \r\n between two sentences in the Instructions element. It does not add separate my two lines. Is there a way to do so?

    		Actions: []hermes.Action{
    			{
    				Instructions: "Google Groups automation just completed SUCCESSFULLY.\rTo view the logs, please click the View Log button.",
    

    -Kamlesh

    opened by kpikamlesh 1
  • allow themes to provide pre-parsed templates

    allow themes to provide pre-parsed templates

    Parsing a static template every time that it's used is a pretty big performance overhead. This pull request adds some optional interfaces that can be defined by themes to allow them to avoid needing to do that every time.

    opened by DeedleFake 0
  • hermes.Theme has no support for exported fields

    hermes.Theme has no support for exported fields

    Given a Theme like this:

    type Theme struct {
        Color string
        Logo  string
    }
    
    func (t *Theme) Name() string { ... }
    func (t *Theme) HTMLTemplate() string { ... }
    func (t *Theme) PlainTextTemplate() string { ... }
    

    And calling hermes like this:

    h := hermes.Hermes{
        Theme: new(Theme),
        // ...
    }
    email := hermes.Email{
        //  ...
    }
    html, err = h.GenerateHTML(email)
    if err != nil {
    	...
    }
    

    Will result int

    panic: reflect: Field index out of range [recovered]
    	panic: reflect: Field index out of range
    

    The reason for this is the exported fields, which are tried to be merged into hermes.Default theme which is of type struct{}. Therefore it's not possible to have exported fields on a struct implementing hermes.Theme interface.

    opened by juliusmh 0
Releases(v2.1.0)
Owner
Mathieu Cornic
Mathieu Cornic
Mail-alias-resolve-ldap - Resolve mail alias addresses in LDAP

alias-resolve-ldap alias-resolve-ldap was written to be used as a hook for the c

Björn Busse 1 Jan 30, 2022
📧 Example of sending mail via SendGrid in Golang.

?? go-sendgrid-example Example of sending mail via SendGrid in Golang. Get it started $ make setup # Edit environment variables $ vim ./env/local.env

ducci 1 Jan 11, 2022
Go library for sending mail with the Mailgun API.

Mailgun with Go Go library for interacting with the Mailgun API. Usage package main import ( "context" "fmt" "log" "time" "githu

Mailgun Team 611 Aug 4, 2022
Mail_sender - This library is for sending emails from your mail

Mail Sender This library is for sending emails from your mail Installation mail_

null 1 Dec 30, 2021
Inline styling for html mail in golang

go-premailer Inline styling for HTML mail in golang Document install go get github.com/vanng822/go-premailer/premailer Example import ( "fmt" "gith

Nguyen Van Nhu 90 Jun 9, 2022
Sending emails using email server talking to RabbitMQ and send grid server sending emails to email ids consumed from RabbitMQ

Sending emails using email server talking to RabbitMQ and send grid server sending emails to email ids consumed from RabbitMQ

Shivanshu Raj Shrivastava 1 Feb 9, 2022
A simple Go POP3 client library for connecting and reading mails from POP3 servers.

go-pop3 A simple Go POP3 client library for connecting and reading mails from POP3 servers. This is a full rewrite of TheCreeper/go-pop3 with bug fixe

Kailash Nadh 34 Jun 8, 2022
A simple parser for the query used in gmail to filter for e-mails

Go Gmail Query Parser by Dustin Breuer This project is work in progress. Prerequisites Before installing this project you need: ?? Go (at least 1.17)

Dustin Breuer 0 Feb 2, 2022
MIME mail encoding and decoding package for Go

enmime enmime is a MIME encoding and decoding library for Go, focused on generating and parsing MIME encoded emails. It is being developed in tandem w

James Hillyerd 322 Aug 7, 2022
VMail - check the markup (HTML, CSS) of HTML email template compatibility with email clients

VMail - check the markup (HTML, CSS) of HTML email template compatibility with email clients Email clients use different rendering standards. This is

Alexey Vasiliev 20 Jul 28, 2022
:envelope: A streaming Go library for the Internet Message Format and mail messages

go-message A Go library for the Internet Message Format. It implements: RFC 5322: Internet Message Format RFC 2045, RFC 2046 and RFC 2047: Multipurpos

Simon Ser 260 Jul 18, 2022
✉️ Composable all-in-one mail server.

Maddy Mail Server Composable all-in-one mail server. Maddy Mail Server implements all functionality required to run a e-mail server. It can send messa

Max Mazurov 3.2k Aug 5, 2022
an MDA that sends a webhook on recieval of mail

an MDA that sends a webhook on recieval of mail

forlater 9 Dec 8, 2021
Filtering spam in mail server, protecting both client privacy and server algorithm

HE Spamfilter SNUCSE 2021 "Intelligent Computing System Design Project" Hyesun Kwak Myeonghwan Ahn Dongwon Lee abstract Naïve Bayesian spam filtering

Myeonghwan Ahn 1 Mar 23, 2022
Mcopa - A library allows for parsing an email message into a more convenient form than the net/mail provides

Mail content parsing This library allows for parsing an email message into a mor

Mr Chen 0 Jan 1, 2022
Simple tool to test SMTP mail send with various settings including TLS1.1 downgrade

smtptest Simple tool to test SMTP mail send with various settings including TLS1.1 downgrade All settings are configurable in the config.yaml file ser

Mario 0 Jan 6, 2022
Go-mail - Email service using Kafka consumer

?? The Project This project consists in a Kafka consumer that reads messages of

Gustavo Belmonte Cioccari 2 Feb 5, 2022
Send markdown files as MIME-encoded electronic mail.

Send markdown files as MIME-encoded electronic mail.

Dmitry Kotik 4 May 7, 2022
Golang library for sending email using gmail credentials

library for sending email using gmail credentials

@Yassine Messaoudi 0 Jan 22, 2022