# How to send emails using Go(golang).

# Prerequisites
To follow along, you will need to have golang installed locally

# Step 1: Create a project and configure it
Create a project directory, and in that type the following commands.

```bash
go mod init send_mail
```

We are going to use the __GoDotEnv__ package to load the _.env_ file

```bash
go get github.com/joho/godotenv
```

In the root directory create a go file called main.go

```go
package main

import (
	"fmt"
	"log"
	"net/smtp"
	"os"

	"github.com/joho/godotenv"
)

func main() {
	err := godotenv.Load(".env")

	if err != nil {
		log.Fatalf("Error loading .env file")
	}

	_, ok := os.LookupEnv("MAIL_USER")

	if !ok {
		log.Fatalf("SMTP username not set")
	}

	_, ok = os.LookupEnv("MAIL_PASSWORD")

	if !ok {
		log.Fatalf("SMTP password not set")
	}

	_, ok = os.LookupEnv("MAIL_HOST")

	if !ok {
		log.Fatalf("SMTP host not set")
	}

	_, ok = os.LookupEnv("MAIL_PORT")

	if !ok {
		log.Fatalf("SMTP port not set")
	}

	response := sendMail("walkerbrownmason@outlook.com", "This is a test mail", "Hello walker what are you up to")
	fmt.Println(response)
	os.Exit(0)
}
```
This is just a boiler plate to start our project.

# Step 2: Create the sendMail function

To send mail using the **net/smtp** standard library, you first need to authenticate with your smtp server using the ```smtp.PlainAuth``` function.

```go
func sendMail(to, subject, body string) Response {

	username := os.Getenv("MAIL_USER")
	password := os.Getenv("MAIL_PASSWORD")
	host := os.Getenv("MAIL_HOST")
	port := os.Getenv("MAIL_PORT")
	auth := smtp.PlainAuth("", username, password, host)
}
```

After authenticating with your smtp server, you can now send an email with the ```smtp.SendMail``` function. Append the following code to our```sendMail``` function.

```go
err := smtp.SendMail(host+":"+port, auth, username, []string{to}, []byte("Subject: "+subject+"\n"+body))

	if err != nil {
		log.Fatalf(err.Error())
	}

	return Response{
		status:  200,
		message: "Mail sent",
	}
```

The ```sendMail``` function now becomes:

```go
func sendMail(to, subject, body string) Response {

	username := os.Getenv("MAIL_USER")
	password := os.Getenv("MAIL_PASSWORD")
	host := os.Getenv("MAIL_HOST")
	port := os.Getenv("MAIL_PORT")
	auth := smtp.PlainAuth("", username, password, host)

	err := smtp.SendMail(host+":"+port, auth, username, []string{to}, []byte("Subject: "+subject+"\n"+body))

	if err != nil {
		log.Fatalf(err.Error())
	}

	return Response{
		status:  200,
		message: "Mail sent",
	}
}
``` 

Let's now define the ```Response``` struct.

```go
type Response struct {
	status  int
	message string
}
```


# Step 3: Run the script using the ```go run``` command

```bash
go run main.go
```

You should get a response like

```bash
{200 Mail sent}
```

#### NB: For some reasons the ```net/smtp``` library only works with gmail smtp on port 587. I would love to get feedback on how to configure it to work with other smtps. 

