Not able to send mail in Golang - email

I am trying to send mail on my local system using gmail package of golang. For which I tried the following:
package main
import(
"fmt"
"github.com/SlyMarbo/gmail"
)
func main() {
email := gmail.Compose("Email subject", "Email body")
email.From = "account#gmail.com"
email.Password = "password"
// Defaults to "text/plain; charset=utf-8" if unset.
email.ContentType = "text/html; charset=utf-8"
// Normally you'll only need one of these, but I thought I'd show both.
email.AddRecipient("recepient#domain.com")
err := email.Send()
if err != nil {
fmt.Println(err)
// handle error.
}
}
I am neither getting any error nor mail. Not sure if it is not sent due to local server. Can anyone please guide me what am I missing? I took reference from this page.

Related

How to get path and filename from postman request body using Go

This question already asked but it is not solve my issue.
In my Go project am not able to print path and filename. It is showing some error like below:
2021/10/13 16:25:07 http: panic serving [::1]:60170: runtime error: invalid memory address or nil pointer dereference goroutine 6 [running]:
My Postman collection
my code
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func encodeFfmpeg(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "multipart/form-data")
_, header, _ := r.FormFile("video")
fmt.Println(header.Filename)
}
func main() {
router := mux.NewRouter()
router.HandleFunc("/encode", encodeFfmpeg).Methods("POST")
// config port
fmt.Printf("Starting server at 8080 \n")
http.ListenAndServe(":8080", router)
}
Am trying to print filename with path eg: /home/ramesh/videos/video.mp4
The sent request is missing the boundary parameter in the Content-Type header. This parameter is required for multipart/form-data to work properly.
In Postman remove the explicit Content-Type header setting and leave it to Postman to automatically set the header with the boundary parameter.
For more see: https://stackoverflow.com/a/16022213/965900 & https://stackoverflow.com/a/41435972/965900
Last but not least, do not ignore errors.

Go HTTP Request with Basic Auth returning a 401 instead of a 301 redirect

Using Go 1.5.1.
When I try to make a request to a site that automatically redirects to HTTPS using Basic Auth I would expect to get a 301 Redirect response, instead I get a 401.
package main
import "net/http"
import "log"
func main() {
url := "http://aerolith.org/files"
username := "cesar"
password := "password"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Println("error", err)
}
if username != "" || password != "" {
req.SetBasicAuth(username, password)
log.Println("[DEBUG] Set basic auth to", username, password)
}
cli := &http.Client{
}
resp, err := cli.Do(req)
if err != nil {
log.Println("Do error", err)
}
log.Println("[DEBUG] resp.Header", resp.Header)
log.Println("[DEBUG] req.Header", req.Header)
log.Println("[DEBUG] code", resp.StatusCode)
}
Note that curl returns a 301:
curl -vvv http://aerolith.org/files --user cesar:password
Any idea what could be going wrong?
A request to http://aerolith.org/files redirects to https://aerolith.org/files (note change from http to https). A request to https://aerolith.org/files redirects to https://aerolith.org/files/ (note addition of trailing /).
Curl does not follow redirects. Curl prints the 301 status for the redirect from http://aerolith.org/files to https://aerolith.org/files/.
The Go client follows the two redirects to https://aerolith.org/files/. The request to https://aerolith.org/files/ returns with status 401 because the Go client does not propagate the authorization header through the redirects.
Requests to https://aerolith.org/files/ from the Go client and Curl return status 200.
If you want to follow the redirects and auth successfully, set auth header in a CheckRedirect function:
cli := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
if len(via) >= 10 {
return errors.New("stopped after 10 redirects")
}
req.SetBasicAuth(username, password)
return nil
}}
resp, err := cli.Do(req)
If you want to match what Curl does, use a transport directly. The transport does not follow redirects.
resp, err := http.DefaultTransport.RoundTrip(req)
The application can also use the client CheckRedirect function and a distinguished error to prevent redirects as shown in an answer to How Can I Make the Go HTTP Client NOT Follow Redirects Automatically?. This technique seems to be somewhat popular, but is more complicated than using the transport directly.
redirectAttemptedError := errors.New("redirect")
cli := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return redirectAttemptedError
}}
resp, err := cli.Do(req)
if urlError, ok := err.(*url.Error); ok && urlError.Err == redirectAttemptedError {
// ignore error from check redirect
err = nil
}
if err != nil {
log.Println("Do error", err)
}

smtp.SendMail cannot send mail to multiple recipent golang

I want to send mail to multiple recipients in Go, with my yahoo mail, but I from all recipients only I get mail.
Code:
err := smtp.SendMail(
"smtp.mail.yahoo.com:25",
auth,
"testmail1#yahoo.com",
[]string{"testmail1#yahoo.com, testmail2#yahoo.com"},
[]byte("test")
message:
From: "testMail1" <testmail1#yahoo.com>
To: testMail1 <testmail1#yahoo.com>, testMail2 <testmail2#yahoo.com>,
Subject: "mail"
MIME-Version: 1.0
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: base64
This is output:
2015/05/18 20:22:26 501 Syntax error in arguments
What have I done wrong?
Your code snippet is incomplete and does not match your email. Could you send more code?
Anyway you can try replacing:
[]string{"testmail1#yahoo.com, testmail2#yahoo.com"},
By:
[]string{"testmail1#yahoo.com", "testmail2#yahoo.com"},
Also you can try my package Gomail to easily send emails:
package main
import (
"gopkg.in/gomail.v2"
)
func main() {
m := gomail.NewMessage()
m.SetAddressHeader("From", "testmail1#yahoo.com", "testMail1")
m.SetHeader("To",
m.FormatAddress("testmail1#yahoo.com", "testMail1"),
m.FormatAddress("testmail2#yahoo.com", "testMail2"),
)
m.SetHeader("Subject", "mail")
m.SetBody("text/plain", "Hello!")
d := gomail.NewPlainDialer("smtp.mail.yahoo.com", 25, "login", "password")
if err := d.DialAndSend(m); err != nil {
panic(err)
}
}

Sending mail on localhost smtp does not work

I am trying to send an email to the localhost stmp server. I am using fakesmtp program to receive email from localhost.
Look at following code snippet
package mail
import (
"encoding/base64"
"fmt"
"log"
"net/mail"
"net/smtp"
"strings"
)
func encodeRFC2047(String string) string {
// use mail's rfc2047 to encode any string
addr := mail.Address{String, ""}
return strings.Trim(addr.String(), " <>")
}
func Send() {
// Set up authentication information.
smtpServer := "127.0.0.1:2525"
auth := smtp.PlainAuth(
"",
"admin",
"admin",
smtpServer,
)
from := mail.Address{"example", "info#example.com"}
to := mail.Address{"customer", "customer#example.com"}
title := "Mail"
body := "This is an email confirmation."
header := make(map[string]string)
header["From"] = from.String()
header["To"] = to.String()
header["Subject"] = encodeRFC2047(title)
header["MIME-Version"] = "1.0"
header["Content-Type"] = "text/plain; charset=\"utf-8\""
header["Content-Transfer-Encoding"] = "base64"
message := ""
for k, v := range header {
message += fmt.Sprintf("%s: %s\r\n", k, v)
}
message += "\r\n" + base64.StdEncoding.EncodeToString([]byte(body))
// Connect to the server, authenticate, set the sender and recipient,
// and send the email all in one step.
err := smtp.SendMail(
smtpServer,
auth,
from.Address,
[]string{to.Address},
[]byte(message),
//[]byte("This is the email body."),
)
if err != nil {
log.Fatal(err)
}
}
When I executed the send function, I've got the error unencrypted connection. Why?
Most likely the server does not allow you to use plain-text authentication over an unencrypted connection, which is a sensible default for almost any MTA out there. Either change authentication info to e.g. digest, or enable SSL/TLS in you client code.
Remember to use tcpdump or wireshark to check what is actually transmitted.

How to send an email using Go with an HTML formatted body?

This seems like a very common need, but I didn't find any good guides when I searched for it.
Assuming that you're using the net/smtp package and so the smtp.SendMail function, you just need to declare the MIME type in your message.
subject := "Subject: Test email from Go!\n"
mime := "MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n"
body := "<html><body><h1>Hello World!</h1></body></html>"
msg := []byte(subject + mime + body)
smtp.SendMail(server, auth, from, to, msg)
Hope this helps =)
I am the author of gomail. With this package you can easily send HTML emails:
package main
import (
"gopkg.in/gomail.v2"
)
func main() {
m := gomail.NewMessage()
m.SetHeader("From", "alex#example.com")
m.SetHeader("To", "bob#example.com")
m.SetHeader("Subject", "Hello!")
m.SetBody("text/html", "Hello <b>Bob</b>!")
// Send the email to Bob
d := gomail.NewPlainDialer("smtp.example.com", 587, "user", "123456")
if err := d.DialAndSend(m); err != nil {
panic(err)
}
}
You can also add a plain text version of the body in your email for the client that does not support HTML using the method AddAlternative.