6 ms·
Show HN: email - Send emails easily in Go
- tshadwell 13y agoInteresting choice of NewEmail() over the more idiomatic email.New().
- dkuntz2 13y agoIn Go isn't `email.NewEmail()` more idiomatic? To be fair, you could write: e = &email.Email{ [fields and values] } The only thing NewEmail does is give you a pointer to an Email.
- ihsw 13y agoNot necessarily: https://www.google.com/search?q=golang+%22func+New(%22+site%3Agolang.org%2Fpkg https://www.google.com/search?q=golang+%22func+New(%22+site%...
- noselasd 13y agoThere's a lot of NewXXX too. The convention is if a package exports only one single type, call it New(...), otherwise call it NewXXX(...)
- ihsw 13y agoIn actuality it would be `email.NewEmail()` -- the lack of namespace specificity is due to the code examples already being part of the package. The issue with a simple `New()` 'constructor' is that there is ambiguity as to what struct it's creating.
- staunch 13y agopackage main import ( "log" "net/smtp" "github.com/jordan-wright/email" ) func main() { e := email.NewEmail() e.From = "Jordan Wright <test@gmail.com>" e.To = []string{"test@example.com"} e.Bcc = []string{"test_bcc@example.com"} e.Cc = []string{"test_cc@example.com"} e.Subject = "Awesome Subject" e.Text = "Text Body is, of course, supported!" e.HTML = "<h1>Fancy HTML is supported, too!</h1>" err := e.Send("smtp.gmail.com:587", smtp.PlainAuth("", "x@gmail.com", "pw", "smtp.gmail.com")) if err != nil { log.Fatal(err) } }
- mratzloff 13y agoThere are dozens of instances of New() in the standard library.
- jwcrux 13y agoGood point - when developing the package, I was referencing these [1][2] documents which showed the use of NewObject() instead of New(). I figured since I provide more than one possible struct (both Email and Attachment), the use of NewEmail would provide consistency. However, now that you mention it, I suppose it wouldn't have hurt, and the meaning would have been fairly clear. Oh well - live and learn, at this point, I'm doing my best not to break backwards compatibility if I don't have to. Thanks for the heads up! [1] http://golang.org/doc/effective_go.html#composite_literals http://golang.org/doc/effective_go.html#composite_literals [2] https://sites.google.com/site/gopatterns/object-oriented/constructors https://sites.google.com/site/gopatterns/object-oriented/con...
- dkuntz2 13y agoLike ihsw said, in Go you probably should leave it as `NewEmail` because `New` is ambiguous.
- DrJokepu 13y agoIf your package exports a single type only, New is more appropriate, if it exports multiple types, you should use NewObject: http://golang.org/doc/effective_go.html#names http://golang.org/doc/effective_go.html#names
- scott_s 13y agoStuart Feldman, from "The Art of Unix Programming", on why makefiles must use tabs: "Why the tab in column 1? Yacc was new, Lex was brand new. I hadn't tried either, so I figured this would be a good excuse to learn. After getting myself snarled up with my first stab at Lex, I just did something simple with the pattern newline-tab. It worked, it stayed. And then a few weeks later I had a user population of about a dozen, most of them friends, and I didn't want to screw up my embedded base. The rest, sadly, is history."
- bnb 13y agoYou could even call it... GMail.
- mratzloff 13y agoThis looks great! It will definitely make my life easier. Thanks for sharing.
- Edmond 13y agothat homepage of yours is something special :)
- mratzloff 13y agoAnd all valid HTML5. :-) I confess that I'm a bit nostalgic for a time not that long ago when people made their own websites about their interests instead of updating their Facebook profile with pointless status messages.
- pkulak 13y agohttp://www.matthewratzloff.com/ http://www.matthewratzloff.com/ That is pretty badass.
- hendler 13y agoHere's a Go smtpd. https://github.com/flashmob/go-guerrilla https://github.com/flashmob/go-guerrilla
- nodesocket 13y agoWish somebody would made a go client for Mandrill (by MailChimp). https://mandrillapp.com/docs/integrations.html https://mandrillapp.com/docs/integrations.html
- jwcrux 13y agohttps://github.com/mattbaird/gochimp https://github.com/mattbaird/gochimp
- elithrar 13y agoBeat me to it. I've been using gochimp to send emails with Mandrill templates (using MergeVars) with much success. I send them async when a user creates their post and log the details. Also means I don't have to either a) run a mail server locally or b) store a user/pass in plaintext (like so many tutorials like to do...)
- curveship 13y agoI'm a novice at Go, but I've written several email libraries in other languages. Two lessons from that experience that I thought I'd pass on: - I've found it a more flexible architecture to separate the send functionality off from your email object itself and into its own service class. So instead of doing email.Send(), you do emailService.Send(email). The content of an email, and how to send that content, are separate responsibilities. Separating the two also allows for alternate implementations of the Send functionality: one (like here) that does a synchronous SMTP transfer, one that might drop the message into an internal queue so that client code doesn't need to wait for the (potentially fairly slow) SMTP transfer, one that simply appends to a local file for debugging, etc. (These are all examples from real apps.) - Have you considered making required properties (to, from, subject) properties of the constructor? Doing so makes guaranteeing that they're set a compile-time check rather than a runtime check, which can make a library more robust and suss out bugs earlier.
- jwcrux 13y agoThanks for the suggestions! 1) I worked to create the package such that other sending services can easily be used to send the email. By calling the .Bytes() function, you will get a slice of bytes which is the raw email representation that's meant to be sent across the wire. I only included the Send() function as a helper. 2) I'm actually not sure if there's a way to do this in Go.. I suppose I could have made the NewEmail() function take arguments for required items - and I did think about doing this- but what arguments? In what order? Using previous libraries, I've always had to go look up the docs every time I use them because I forget what order the to and from are supposed to be in. Currently, only runtime checks are performed to make sure there is at least one from and to addresses given. Thanks for the suggestions - I really appreciate it!
- dradtke 13y agoLooks interesting. A couple suggestions: 1. People have already suggested this, but it would make more sense to make users call email.New() rather than email.NewEmail(). 2. Alternatively, since the user will be populating a bunch of values anyway, it might make more sense to tell users to create a message like e := &email.Email{ From: "Jordan Wright <test@gmail.com>", To: []string{"test@example.com"}, ... } and then, if a value hasn't been set for it, use a default value for Headers in the send method.
- jwcrux 13y agoWith regards to 1, it seems like I'm stuck between a rock and a hard place. I originally made the package in accordance to the docs I read which stated that if you are exporting more than one type, use NewType(). Now that so many people are using the package, I'd hate to make changes that would break it unless necessary. However, with that being said, 2 might solve that issue. I'll add an example this evening showing how to also create an email in one pass using an example similar to yours. Thanks for the suggestions!
- yixizhang 13y agoThe easiest way and properly the right way to send email is in plain text. I would be happier if the package can add a parser to read all meta data from text, in the way of HTTP header processing.
- zavi 13y agoUsing plain text Gmail password looks like a red flag. e.Send("smtp.gmail.com:587", smtp.PlainAuth("", "test@gmail.com", "password123", "smtp.gmail.com"))
- jwcrux 13y agoI am wrapping SendMail.. "SendMail connects to the server at addr, switches to TLS if possible, authenticates with the optional mechanism a if possible, and then sends an email from address from, to addresses to, with message msg"[1] [1]http://golang.org/pkg/net/smtp/#SendMail http://golang.org/pkg/net/smtp/#SendMail