News for hackers. Stuff that matters.
Re:Show HN: email - Send emails easily in Go by curveship on Tuesday January 07, 2014 @05:20PM (#7020413)
I'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.

Re:Show HN: email - Send emails easily in Go by jwcrux on Tuesday January 07, 2014 @06:57PM (#7020856)
Thanks 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!

Re:Show HN: email - Send emails easily in Go by dradtke on Tuesday January 07, 2014 @05:57PM (#7020602)
Looks 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 <[email protected]>",
        To: []string{"[email protected]"},
        ...
    }
and then, if a value hasn't been set for it, use a default value for Headers in the send method.
Re:Show HN: email - Send emails easily in Go by jwcrux on Tuesday January 07, 2014 @06:39PM (#7020792)
With 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!

Re:Show HN: email - Send emails easily in Go by hendler on Tuesday January 07, 2014 @03:52PM (#7019820)
Re:Show HN: email - Send emails easily in Go by nodesocket on Tuesday January 07, 2014 @05:14PM (#7020377)
Wish somebody would made a go client for Mandrill (by MailChimp). https://mandrillapp.com/docs/integrations.html
Re:Show HN: email - Send emails easily in Go by jwcrux on Tuesday January 07, 2014 @05:21PM (#7020419)
Re:Show HN: email - Send emails easily in Go by elithrar on Tuesday January 07, 2014 @06:32PM (#7020765)
Beat 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...)

Re:Show HN: email - Send emails easily in Go by bnb on Tuesday January 07, 2014 @02:27PM (#7019271)
You could even call it... GMail.
Re:Show HN: email - Send emails easily in Go by zavi on Tuesday January 07, 2014 @11:17PM (#7021656)
Using plain text Gmail password looks like a red flag.

  e.Send("smtp.gmail.com:587", 
          smtp.PlainAuth("", 
                         "[email protected]", 
                         "password123", 
                         "smtp.gmail.com"))
Re:Show HN: email - Send emails easily in Go by jwcrux on Tuesday January 07, 2014 @11:26PM (#7021684)
I 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

Re:Show HN: email - Send emails easily in Go by mratzloff on Tuesday January 07, 2014 @03:03PM (#7019535)
This looks great! It will definitely make my life easier. Thanks for sharing.
Re:Show HN: email - Send emails easily in Go by Edmond on Tuesday January 07, 2014 @03:49PM (#7019798)
that homepage of yours is something special :)
Re:Show HN: email - Send emails easily in Go by mratzloff on Tuesday January 07, 2014 @04:28PM (#7020083)
And 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.

Re:Show HN: email - Send emails easily in Go by pkulak on Tuesday January 07, 2014 @06:56PM (#7020851)
http://www.matthewratzloff.com/

That is pretty badass.

Re:Show HN: email - Send emails easily in Go by yixizhang on Tuesday January 07, 2014 @07:13PM (#7020919)
The 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.
Re:Show HN: email - Send emails easily in Go by tshadwell on Tuesday January 07, 2014 @02:22PM (#7019235)
Interesting choice of NewEmail() over the more idiomatic email.New().
Re:Show HN: email - Send emails easily in Go by jwcrux on Tuesday January 07, 2014 @02:30PM (#7019300)
Good 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

[2] https://sites.google.com/site/gopatterns/object-oriented/con...

Re:Show HN: email - Send emails easily in Go by scott_s on Tuesday January 07, 2014 @07:20PM (#7020949)
Stuart 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."

Re:Show HN: email - Send emails easily in Go by DrJokepu on Tuesday January 07, 2014 @02:51PM (#7019438)
If 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

Re:Show HN: email - Send emails easily in Go by mseepgood on Tuesday January 07, 2014 @05:41PM (#7020514)
Many packages have a dominant type and a couple of satellite types. If the package name is the same as or similar to the name of the dominant type, 'New' can be appropriate as well.
Re:Show HN: email - Send emails easily in Go by DrJokepu on Tuesday January 07, 2014 @06:07PM (#7020644)
Right. As long it’s super obvious which type New creates, it’s perfectly fine.
Re:Show HN: email - Send emails easily in Go by dkuntz2 on Tuesday January 07, 2014 @02:32PM (#7019307)
Like ihsw said, in Go you probably should leave it as `NewEmail` because `New` is ambiguous.
Re:Show HN: email - Send emails easily in Go by ihsw on Tuesday January 07, 2014 @02:30PM (#7019296)
In 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.
Re:Show HN: email - Send emails easily in Go by staunch on Tuesday January 07, 2014 @02:53PM (#7019452)

   package main
   
   import (
       "log"
       "net/smtp"
       "github.com/jordan-wright/email"
   )
   
   func main() {
       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 = "Text Body is, of course, supported!"
       e.HTML = "<h1>Fancy HTML is supported, too!</h1>"
       err := e.Send("smtp.gmail.com:587",
           smtp.PlainAuth("", "[email protected]", "pw", "smtp.gmail.com"))
       if err != nil {
           log.Fatal(err)
       }
   }
Re:Show HN: email - Send emails easily in Go by mratzloff on Tuesday January 07, 2014 @02:58PM (#7019499)
There are dozens of instances of New() in the standard library.
Re:Show HN: email - Send emails easily in Go by dkuntz2 on Tuesday January 07, 2014 @02:28PM (#7019282)
In 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.

Re:Show HN: email - Send emails easily in Go by ihsw on Tuesday January 07, 2014 @02:31PM (#7019304)
Re:Show HN: email - Send emails easily in Go by noselasd on Tuesday January 07, 2014 @04:26PM (#7020066)
There's a lot of NewXXX too. The convention is if a package exports only one single type, call it New(...), otherwise call it NewXXX(...)