Giter Site home page Giter Site logo

email's Introduction

email

Build Status GoDoc

Robust and flexible email library for Go

Email for humans

The email package is designed to be simple to use, but flexible enough so as not to be restrictive. The goal is to provide an email interface for humans.

The email package currently supports the following:

  • From, To, Bcc, and Cc fields
  • Email addresses in both "[email protected]" and "First Last <[email protected]>" format
  • Text and HTML Message Body
  • Attachments
  • Read Receipts
  • Custom headers
  • More to come!

Installation

go get github.com/jordan-wright/email

Note: Version > 1 of this library requires Go v1.5 or above.

If you need compatibility with previous Go versions, you can use the previous package at gopkg.in/jordan-wright/email.v1

Examples

Sending email using Gmail

e := email.NewEmail()
e.From = "Jordan Wright <[email protected]>"
e.To = []string{"[email protected]"}
e.Bcc = []string{"[email protected]"}
e.Cc = []string{"[email protected]"}
e.Subject = "Awesome Subject"
e.Text = []byte("Text Body is, of course, supported!")
e.HTML = []byte("<h1>Fancy HTML is supported, too!</h1>")
e.Send("smtp.gmail.com:587", smtp.PlainAuth("", "[email protected]", "password123", "smtp.gmail.com"))

Another Method for Creating an Email

You can also create an email directly by creating a struct as follows:

e := &email.Email {
	To: []string{"[email protected]"},
	From: "Jordan Wright <[email protected]>",
	Subject: "Awesome Subject",
	Text: []byte("Text Body is, of course, supported!"),
	HTML: []byte("<h1>Fancy HTML is supported, too!</h1>"),
	Headers: textproto.MIMEHeader{},
}

Creating an Email From an io.Reader

You can also create an email from any type that implements the io.Reader interface by using email.NewEmailFromReader.

Attaching a File

e := NewEmail()
e.AttachFile("test.txt")

A Pool of Reusable Connections

(var ch <-chan *email.Email)
p := email.NewPool(
	"smtp.gmail.com:587",
	4,
	smtp.PlainAuth("", "[email protected]", "password123", "smtp.gmail.com"),
)
for i := 0; i < 4; i++ {
	go func() {
		for e := range ch {
			p.Send(e, 10 * time.Second)
		}
	}()
}

Documentation

http://godoc.org/github.com/jordan-wright/email

Other Sources

Sections inspired by the handy gophermail project.

Contributors

I'd like to thank all the contributors and maintainers of this package.

A special thanks goes out to Jed Denlea jeddenlea for his numerous contributions and optimizations.

email's People

Contributors

barnjamin avatar bosim avatar bughou avatar chborges avatar cristaloleg avatar diligiant avatar dmaciejak avatar fank avatar halaalajlan avatar ichinaski avatar ifraixedes avatar jeddenlea avatar jensrantil avatar jeremywohl avatar jessta avatar jordan-wright avatar knadh avatar l-ross avatar leucos avatar maddyblue avatar mgrachev avatar quasilyte avatar rolandshoemaker avatar saromanov avatar steelphase avatar tarmo-randma avatar teepark avatar ursc avatar wscherphof avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

email's Issues

What's mean +4?

func (e *Email) msgHeaders() (textproto.MIMEHeader, error) {
	res := make(textproto.MIMEHeader, len(e.Headers)+4)
	if e.Headers != nil {
	res := make(textproto.MIMEHeader, len(e.Headers)+4)

Sorry, I Don't understood mean +4.

Maybe, not need +4?

Opportunistic TLS

We're getting this error when trying to send an email via a client's mail server:
x509: certificate is valid for {contents of LDAP/AD CN=___ here},

They advise that the server answering the connection on TCP:25 has a self-signed certificate and is using Opportunistic TLS. They say it is configured and performing correctly and our error is not the result of anything they will fix. We had also showed them that:

$ openssl s_client -connect {mail server}:25 -starttls smtp 2>&1 | openssl x509 -text -noout 2>&1 | grep DNS

Returns nothing from their mail server, but does from ours and various public mail servers around the internet.

Not sure if "Opportunistic TLS" is unsupported, or is even the issue at all... Any advice appreciated. Thanks.

TLS error with email 3

TLS worked in 2.2 and now I get first record does not look like a TLS handshake

Comes from https://golang.org/src/crypto/tls/conn.go row 635

plainAuth := smtp.PlainAuth("", mail.username, mail.password, mail.host)
if len(mail.username) == 0 {
  plainAuth = nil
}

err = e.SendWithTLS(fmt.Sprintf("%s:%s", mail.host, mail.smtpPort), plainAuth, &tls.Config{InsecureSkipVerify: true})

Any pointers?

Not able to parse an email: no media type

Email content:

From: "Keith Packard" <[email protected]>
To: [email protected]
Date: Tue, 17 Nov 2009 18:03:17 -0800
Subject: [notmuch] Introducing myself
In-Reply-To: <20091118002059.067214ed@hikari>
References: <20091118002059.067214ed@hikari>
Message-ID: <[email protected]>

On Wed, 18 Nov 2009 00:20:59 +0100, Adrian Perez de Castro <aperez at igalia.com> wrote:

> Some time ago I thought
> about doing something like Not Much and in fact I played a bit with the
> Python+Xapian and the Python+Whoosh combinations, because I find relaxing
> to code things in Python when I am not working and also it is installed
> by default on most distribution. I got to have some mailboxes indexed and
> basic searching working a couple of months ago.

Sup certainly started a lot of people thinking...

> Also, I would like to share one idea I had in mind, that you might find
> interesting: One thing I have found very annoying is having to re-tag my
> mail when the indexes get b0rked (it happened a couple of times to me while
> using Sup), so I was planning to mails as read/unread and adding the tags
> not just to the index, but to the mail text itself, e.g. by adding a
> "X-Tags" header field or by reusing the "Keywords" one.

Easier than that, notmuch (and sup too), provide a 'dump' command which
just lists all of the message IDs and their associated tags. Makes
saving tags easy and doesn't involve rewriting messages. I do this once
a day just before my computer is backed up to an external drive.

If the index is destroyed, you can reindex the messages and then reapply
all of the tags with 'notmuch restore'.

--
keith.packard at intel.com

Getting the error mime: no media type when I try to parse the email above. Found that developing Gmuch email_bug branch.

Emails with no body insert attachment as text.

I.E.

From: [email protected]
Subject: Invoice from My Apartment Motel
Date: 11 December 2014 2:42:59 pm NZDT
To: [email protected]

Content-Type: application/octet-stream
Content-Disposition: attachment;
filename="Invoice 2474.PDF"
Content-Id: <Invoice 2474.PDF>
Content-Transfer-Encoding: base64

JVBERi0xLjQKJaqrrK0KNCAwIG9iago8PAovQ3JlYXRvciAoQXBhY2hlIEZPUCBWZXJzaW9uIDEu
MCkKL1Byb2R1Y2VyIC...

Connection-Timeout on Send

Hi,

I just found this library and it is great! Recently I ran into the problem that I used a wrong smtp host and the application stucked. Is there a possibility to set a connection timout on an email or globally?

Helo with localhost

It opens SMTP connections with the hardcoded "localhost" string.

helo localhost

Then, it shows in message sources:

Received: from localhost (xxx])
    by xxx
    for xxx

Which gets flagged by many anti-spam:

X-Spam-Status: No, score=4.53 ....
    ...
    HELO_LOCALHOST=3.828, ...

My hostname is configured properly on my machine. I also checked with this simple script:

package main

import (
        "fmt"
        "os"
)

func main() {
        fmt.Println(os.Hostname())
}

unexpected behavior for go 1.9.2

I use this package to send some emails in Chinese. When compiling with go 1.8.3, it's OK, but when compiling with go 1.9.2, the content seems to be encoded (I'm not sure, something like: =E5=86=85=E5=AE=B9)

Is there any easy solution to this?

Preserve upper and lower case for header keys.

Even if it doesn't make any difference according to the standards, there is one in practice. For example, rspamd increases the spam score for Mime-Version (instead of MIME-Version). Some time ago the code in this repo was changed to set MIME-Version instead of Mime-Version. But the usage of net/textproto applies CanonicalMIMEHeaderKey on all header keys which changes MIME-Version back to Mime-Version. golang/go#29965 suggets forking net/textproto.

No Content-Type found for MIME entity

Parsing the following email (pasted as is)

From: Mikhail Gusarov <[email protected]>
To: [email protected]
References: <[email protected]>
Date: Wed, 18 Nov 2009 01:02:38 +0600
In-Reply-To: <[email protected]> (Lars
    Kellogg-Stedman's message of "Tue, 17 Nov 2009 14:00:54 -0500")
Message-ID: <[email protected]>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux)
MIME-Version: 1.0
Subject: Re: [notmuch] Working with Maildir storage?
X-BeenThere: [email protected]
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: "Use and development of the notmuch mail system."
    <notmuch.notmuchmail.org>
List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
    <mailto:[email protected]?subject=unsubscribe>
List-Archive: <http://notmuchmail.org/pipermail/notmuch>
List-Post: <mailto:[email protected]>
List-Help: <mailto:[email protected]?subject=help>
List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
    <mailto:[email protected]?subject=subscribe>
Content-Type: multipart/mixed; boundary="===============1958295626=="
Sender: [email protected]
Errors-To: [email protected]

--===============1958295626==
Content-Type: multipart/signed; boundary="=-=-=";
    micalg=pgp-sha1; protocol="application/pgp-signature"

--=-=-=
Content-Transfer-Encoding: quoted-printable


Twas brillig at 14:00:54 17.11.2009 UTC-05 when [email protected] did g=
yre and gimble:

 LK> Resulted in 4604 lines of errors along the lines of:

 LK>   Error opening
 LK>   /home/lars/Mail/read-messages.2008/cur/1246413773.24928_27334.hostna=
me,U=3D3026:2,S:
 LK>   Too many open files

See the patch just posted here.

=2D-=20
  http://fossarchy.blogspot.com/

--=-=-=
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iQIcBAEBAgAGBQJLAvNOAAoJEJ0g9lA+M4iIjLYQAKp0PXEgl3JMOEBisH52AsIK
CzzfP4Fzd41K9VH/c1EdQWDYR6FCAA4IUSNICnJhITsYUb0eC5AKJiey3JP0+rmd
s4qEFBKH2iuphv8Llltcv2Q8DyPuJBkVa3mO9XCCeABZ6v4UvnTSWRVG12csSEih
ScgienU8sMrM9LwvvVI1ZB2flm2TzsH2hWi30jIgmtBntIKJaTgbFXB50FYFwULa
gGL/oH3u+YpumedWzPZdCJrw2q7nMvYx8aQ29EDCNLZibAZe+6oDTa6Fv6/0ldpQ
U+DptR0nJGbJTWa26OTSvmyeIORjAfM+TEI68n7KO9VHYPmVh6awcf0MNKYh2xWk
eRQNBcKyQNWxeKyCCpT/rrTlpxBWahpvg+V8lkDH2W09wjRp6CUKvifK3Sz3am9m
5ZUMpvXbwkZD6Ci6l/QytbYK50e8UpvFSu5DBaxBz59ykoypuNg2ayO5Kdi6IF5d
T+Sw6wo8UKn9a33+vheIc0fkhZXbeSotEmDm7huazm6CgM3dcWXUpTuJvik1cSWp
4buv98gY6IKWKoUTXODWUr+7VR4gei8du8qOsKem+QDfNX7tmaIRjhrbB24B91Wy
td3MTJD7GjMNid0INqRY1CRMLo8YlPaq6NBZfcYtYgwa6gpJijz1/MAn8+GMrfhF
9LI8b9jopNP+pMYBohLA
=/ksP
-----END PGP SIGNATURE-----
--=-=-=--

--===============1958295626==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
notmuch mailing list
[email protected]
http://notmuchmail.org/mailman/listinfo/notmuch

--===============1958295626==--

From gmuch itself:

kalbasit@cratos ~/code/src/github.com/gmuch/gmuch [email_bug] ± % make test
=== RUN   TestQuery
--- PASS: TestQuery (0.01s)
=== RUN   TestThreadIDValidation
method=getMessage [email protected] operation="parse email file" path=/Users/kalbasit/code/src/github.com/gmuch/gmuch/fixtures/database-v1/new/04:2, error="No Content-Type found for MIME entity"
--- FAIL: TestThreadIDValidation (0.00s)
        thread_test.go:25: Thread("0000000000000001"): want error %!q(<nil>) got "No Content-Type found for MIME entity"
=== RUN   TestThread
method=getMessage [email protected] operation="parse email file" path=/Users/kalbasit/code/src/github.com/gmuch/gmuch/fixtures/database-v1/new/04:2, error="No Content-Type found for MIME entity"
--- FAIL: TestThread (0.03s)
        thread_test.go:40: g.Thread("0000000000000001"): got error: No Content-Type found for MIME entity
FAIL
coverage: 87.7% of statements
exit status 1
FAIL    github.com/gmuch/gmuch  0.064s
make: *** [test] Error 1

Sending without auth?

One of our clients gave us an account on their SMTP server to send mails. However, it does not have any password so it fails all authentication methods (I tried PlainAuth which the server does not recognize and LoginAuth implementation which the server recognizes but fails to auth)

Is there a way for this kind of situations for bypassing the auth?

How to insert a linebreak into plain text body?

Hi I wanted to know how I can achieve a linebreak in plain text mails? This might be a more general plain text email question but maybe I have luck here.

I want something similar to
in HTML "\r\n" doesn't work for me.

IMAP support

Hi Jordan, would you like to add IMAP support to a future version, or is this project only aimed at SMTP? It would be great to have a solid Go library with send & receive functionality.

I'm using mxh/go-imap in production; it's quite a low-level implementation and seems abandoned, but I've found it to be pretty stable. I'd like to wrap it in a simpler & easier API, and I think it would have a good home in this library!

Let me know what you think/if you can contribute as well. :)

Make message ID a function of {sender, subject, body…}

Message IDs are used for duplicate suppression. It's not necessary that they are truly random, nor satisfy any nonce-criteria from the field of cryptography.

Anything from hash.Hash->Sum(x) will be sufficient.

A duplicate can easily be detected by making the aforementioned x the flattened sorted set {sender, subject, body, [part of date], attachment[]}.

Support UTF-8 in attachment filenames

Hi, it appears the attachment filenames do not support UTF-8 (or non-ascii in general).

I was able to perform a workaround with the following code

filename := "non-ascii øæä.txt"
contentType := "text/plain"
email := email.NewEmail()
email.Attach(bytes.NewReader(attachment.Data), filename, contentType)

qEncodedFilename := mime.QEncoding.Encode("UTF-8", filename)
hexEncoded := ""
for i := 0; i < len(filename); i++ {
	hexEncoded += fmt.Sprintf("%%%X", filename[i])
}
email.Attachments[0].Header.Set("Content-Disposition", "attachment;\r\n filename*=utf-8''"+hexEncoded)
email.Attachments[0].Header.Set("Content-Type", fmt.Sprintf("%s;\r\n name=\"%s=\"", contentType, qEncodedFilename))
email.Attachments[0].Header.Del("Content-ID")

Would it be possible for you to support this in the email.Attach directly?

HTML, not Html

Go style is to never mix case in abbreviations. So you'd write htmlFoo or fooHTML but never fooHTML or Html.

Therefore, the Html field should be named HTML.

SSL/TLS communication isn't possible when using Pool

I tried to use the the Pool for sending emails to a SMTP server which offers SSL/TLS connections (not STARTTLS) and the pool.Send hangs on pool.build; that doesn't happen with Email.SendWithTLS because it uses the TLS package to dial the connection.

Hence the pool type cannot send emails using SSL/TLS connections, only send emails on unencrypted connections or encrypted ones through STARTTLS.

On the other hand, in ab implementation of a function which checks SMTP server connections which I've done, I deal differently.
When the server advertise the STARTTLS connection, there is no need to dial a TLS connection, a unencrypted dial (net.Dial) works and after, it's the client.StartTLS which upgrades the connection, that's mostly is how the pool works. The thing is that it differs from the implementation of Email.SendWithTLS function, which always dial the connection with TLS independently if STARTTLS is available or not.

I cannot say if that's an issue or not, because I haven't used the Email.SendWithTLS of this package, so I'm mostly reporting as an insight.

Create NewEmailFromReader Method

While this library provides the ability to create a raw string of bytes from an email.Email struct, it would be handy to have the reverse - provide an io.Reader and receive an email.Email.

This will likely need the implementation of a quotePrintDecode function to parse the contents of the body.

read tcp xx.xx.xx.xx:xx->xx.xx.xx.xx:xx: read: connection reset by peer

hello,
the code

package main

import (
	"github.com/jordan-wright/email"
	"net/smtp"
	"fmt"
)

func main() {
	e := email.NewEmail()
	e.From = "robot <[email protected]>"
	e.To = []string{"[email protected]"}
	//e.Bcc = []string{"[email protected]"}
	//e.Cc = []string{"[email protected]"}
	e.Subject = "Awesome Subject"
	e.Text = []byte("Text Body is, of course, supported!")
	e.HTML = []byte("<h1>Fancy HTML is supported, too!</h1>")
	var res = e.Send("hwsmtp.exmail.qq.com:25", smtp.PlainAuth("", "example.com", "xxxx", "hwsmtp.exmail.qq.com"))
	fmt.Print(res)
}

output

read tcp xx.xx.xx.xx:xx->xx.xx.xx.xx:xx: read: connection reset by peer

who can give me some help,thanks.

Unrecognized import path "mime/quotedprintable"

I'm relatively new in Go. I'm getting this error when building the dependencies thru Capistrano in our server

$ go get -u github.com/jordan-wright/email
    | package github.com/jordan-wright/email
    imports mime/quotedprintable: unrecognized import path "mime/quotedprintable"

The dependencies are being installed through depman. I tried godep but still getting the same error. Weird thing is I'm only getting the error when I'm deploying. In my local machine it's working fine.

My deps.json is:

{        
    "email": {
        "repo": "github.com/jordan-wright/email",
        "version": "",
        "type": "git"
    } 
 }

Any thoughts?

Handle Default Content-Type

If a Content-Type is not specified then, by default, it should be "text/plain; charset=us-ascii".

This logic is not in the stdlib, so it needs to be added.

Related to #24

Any chance to send a html template?

I try to copy the html code from a template and sent but i didnt got the email and any errors at all. there is any trick to send formated html template mail?

thanks

Don't Assume Multipart Emails

Emails are required to be multipart. In fact, many aren't.

Need to be able to handle cases where the email is a single MIME part.

Related to #24

Issue having email parsed with sup client

There exists an issue where email sent with this package is not properly parsed by some mail clients.

It was determined in an open pull-request to @zachlatta's postman utility that the sup MUA doesn't properly parse emails sent by this package (specifically, an example was provided that contained both a text and an HTML segment). This issue will serve as a reference.

It is unclear if this is an issue with this library, or with sup, so an issue will appear in both repos.

might be cool?

Might be cool if the Send mech had a way to do this in a go routine? to avoid blocking code using the package?

I would think we need some community guidance about whether the go routines should inside the packages or expected to be done by the users of the package...

opinion?

Consider the Use of a Sender Interface

It would be nice to have flexibility with how emails are sent. For example, providers like MailChimp, Sendgrid, etc. all use API's to send emails.

Ideally, I could see us changing the signature for email.Send() to, instead of taking an smtp.Auth object, taking anything that implements the Sender interface.

This interface could be simple:

type Sender interface {
    Send(e Email) (err error)
}

We could also do this via another method such as SendWithSender() or similar. This way, people could send the email using whatever client they wanted.

We could then provide various clients in a separate package: email/senders that support various APIs.

Yahoo interface?

When I insert smtp.mail.yahoo.com:25 as the sending address, the Send command seems to hang forever.

Any idea what settings you would require?

Note:
However, if you create the mail using this package, you can stream the output of the Bytes() command into MSMTP to send the email using os.exec(). Digital Ocean have good notes on setting up MSMTP to access Yahoo. I Can give details/sample code if needed.

MaxLineLength, not MAX_LINE_LENGTH

Go style is to not use CONSTANTS_LIKE_THIS, except in old legacy cases where we're mimicing some syscall or os constant.

In general, Go constants should be named like any other variable. likeThis or LikeThis, depending on whether or not it's public.

Therefore: MaxLineLength, not MAX_LINE_LENGTH

Consideration to accept context by parameter

I wanted to ask if you would consider to accept to add new functions to the API, in order of not breaking the backward compatibility, which receives the [context.Context] by parameter and the implementation of those use it for allowing manual cancelations and deadline cancelations.

For what I've seen, adding a new Send... methods to the Email type and supporting it, shouldn't be that much work, however adding a new method for the Pool could be quite a bit more work.

Currently, it isn't something that I would work, but if you would accept such additions, I could bear in mind and may do a contribution.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.