import "net/smtp"
smtp包实现了简单邮件传输协议(SMTP),参见RFC 5321。同时本包还实现了如下扩展:
8BITMIME RFC 1652 AUTH RFC 2554 STARTTLS RFC 3207
客户端可以自行管理其他的扩展。
// Connect to the remote SMTP server. c, err := smtp.Dial("mail.example.com:25") if err != nil { log.Fatal(err) } // Set the sender and recipient first if err := c.Mail("sender@example.org"); err != nil { log.Fatal(err) } if err := c.Rcpt("recipient@example.net"); err != nil { log.Fatal(err) } // Send the email body. wc, err := c.Data() if err != nil { log.Fatal(err) } _, err = fmt.Fprintf(wc, "This is the email body") if err != nil { log.Fatal(err) } err = wc.Close() if err != nil { log.Fatal(err) } // Send the QUIT command and close the connection. err = c.Quit() if err != nil { log.Fatal(err) }
type ServerInfo struct { Name string // SMTP服务器的名字 TLS bool // Name有合法的证书并使用TLS时为真 Auth []string // 支持的认证机制 }
ServerInfo类型记录一个SMTP服务器的信息。
type Auth interface { // 方法开始和服务端的认证。 // 它返回认证协议的名字和可能有的应发送给服务端的包含初始认证信息的数据。 // 如果返回值proto == "",表示应跳过认证; // 如果返回一个非nil的错误,SMTP客户端应中断认证身份的尝试并关闭连接。 Start(server *ServerInfo) (proto string, toServer []byte, err error) // 方法继续认证过程。fromServer为服务端刚发送的数据。 // 如果more为真,服务端会期望一个回复,回复内容应被Next返回,即toServer; // 否则返回值toServer应为nil。 // 如果返回一个非nil的错误,SMTP客户端应中断认证身份的尝试并关闭连接。 Next(fromServer []byte, more bool) (toServer []byte, err error) }
Auth接口应被每一个SMTP认证机制实现。
func CRAMMD5Auth(username, secret string) Auth
返回一个实现了CRAM-MD5身份认证机制(参见RFC 2195)的Auth接口。返回的接口使用给出的用户名和密码,采用响应——回答机制与服务端进行身份认证。
func PlainAuth(identity, username, password, host string) Auth
返回一个实现了PLAIN身份认证机制(参见RFC 4616)的Auth接口。返回的接口使用给出的用户名和密码,通过TLS连接到主机认证,采用identity为身份管理和行动(通常应设identity为"",以便使用username为身份)。
// Set up authentication information. auth := smtp.PlainAuth("", "user@example.com", "password", "mail.example.com") // Connect to the server, authenticate, set the sender and recipient, // and send the email all in one step. to := []string{"recipient@example.net"} msg := []byte("This is the email body.") err := smtp.SendMail("mail.example.com:25", auth, "sender@example.org", to, msg) if err != nil { log.Fatal(err) }
type Client struct { // 代表被Client使用的textproto.Conn,它可以导出,以便使用者添加扩展。 Text *textproto.Conn // 内含隐藏或非导出字段 }
Client代表一个连接到SMTP服务器的客户端。
func Dial(addr string) (*Client, error)
Dial返回一个连接到地址为addr的SMTP服务器的*Client;addr必须包含端口号。
func NewClient(conn net.Conn, host string) (*Client, error)
NewClient使用已经存在的连接conn和作为服务器名的host(用于身份认证)来创建一个*Client。
func (c *Client) Extension(ext string) (bool, string)
Extension返回服务端是否支持某个扩展,扩展名是大小写不敏感的。如果扩展被支持,方法还会返回一个包含指定给该扩展的各个参数的字符串。
func (c *Client) Hello(localName string) error
Hello发送给服务端一个HELO或EHLO命令。本方法只有使用者需要控制使用的本地主机名时才应使用,否则程序会将本地主机名设为“localhost”,Hello方法只能在最开始调用。
func (c *Client) Auth(a Auth) error
Auth使用提供的认证机制进行认证。失败的认证会关闭该连接。只有服务端支持AUTH时,本方法才有效。(但是不支持时,调用会默默的成功)
func (c *Client) Verify(addr string) error
Verify检查一个邮箱地址在其服务器是否合法,如果合法会返回nil;但非nil的返回值并不代表不合法,因为许多服务器出于安全原因不支持这种查询。
func (c *Client) StartTLS(config *tls.Config) error
StartTLS方法发送STARTTLS命令,并将之后的所有数据往来加密。只有服务器附加了STARTTLS扩展,这个方法才有效。
func (c *Client) Mail(from string) error
Mail发送MAIL命令和邮箱地址from到服务器。如果服务端支持8BITMIME扩展,本方法会添加BODY=8BITMIME参数。方法初始化一次邮件传输,后应跟1到多个Rcpt方法的调用。
func (c *Client) Rcpt(to string) error
Rcpt发送RCPT命令和邮箱地址to到服务器。调用Rcpt方法之前必须调用了Mail方法,之后可以再一次调用Rcpt方法,也可以调用Data方法。
func (c *Client) Data() (io.WriteCloser, error)
Data发送DATA指令到服务器并返回一个io.WriteCloser,用于写入邮件信息。调用者必须在调用c的下一个方法之前关闭这个io.WriteCloser。方法必须在一次或多次Rcpt方法之后调用。
func (c *Client) Reset() error
Reset向服务端发送REST命令,中断当前的邮件传输。
func (c *Client) Quit() error
Quit发送QUIT命令并关闭到服务端的连接。
func (c *Client) Close() error
Close关闭连接。
func SendMail(addr string, a Auth, from string, to []string, msg []byte) error
SendMail连接到addr指定的服务器;如果支持会开启TLS;如果支持会使用a认证身份;然后以from为邮件源地址发送邮件msg到目标地址to。(可以是多个目标地址:群发)