Im trying to send a mail with sendgrid and golang. Im using "github.com/sendgrid/sendgrid-go"
Whenever I run the part sending email in my code, I get this error:
sendgrid.go: error:net/http: Client Transport of type init.failingTransport doesn't support CancelRequest; Timeout not supported; response:<nil>
I cant figure out what it is..
This is my code:
sg := sendgrid.NewSendGridClientWithApiKey("string")
email := sendgrid.NewMail()
email.AddTo(req.Email)
email.SetSubject("Confirm your registration at domain")
email.SetFrom("noreply@domain.com")
email.SetFromName("domain")
email.SetText(url)
if r := sg.Send(email); r == nil {
log.Infof(ctx, "email sent")
} else {
log.Errorf(ctx, "email not sent %v", r)
w.WriteHeader(http.StatusInternalServerError)
return
}
The minimal program to use the Sendgrid API in Go is something like the following:
package main
import (
"fmt"
"github.com/sendgrid/sendgrid-go"
)
func main() {
key := "SENDGRID_API_KEY"
sg := sendgrid.NewSendGridClientWithApiKey(key)
message := sendgrid.NewMail()
message.AddTo("ezra@usefultiftrue.com")
message.SetFrom("test@example.org")
message.SetSubject("SUBJECT HERE")
message.SetHTML("BODY OF THE EMAIL")
if r := sg.Send(message); r == nil {
fmt.Println("Sent!")
} else {
fmt.Println(r)
}
}
You can see the Sendgrid Go Documentation on Github.
The issue is that you're attempting to fetch a Url using the default net/http
client, which is not allowed by App Engine. You must use urlfetch
to make HTTP
requests on App Engine.
You can solve this by specifying your *http.Client
to use urlfetch
, since Sendgrid uses a client that uses the disallowed http.DefaultTransport
by default. init.failingTransport
is a dummy transport method that basically just throws an error.
This is ultimately a simple change. Simply import "appengine/urlfetch"
and add
client := urlfetch.Client(ctx)
package ezralalonde
import (
"appengine"
"appengine/urlfetch"
"fmt"
"github.com/sendgrid/sendgrid-go"
"net/http"
)
func send(w http.ResponseWriter, r *http.Request) {
key := "SENDGRID_API_KEY"
sg := sendgrid.NewSendGridClientWithApiKey(key)
// must change the net/http client to not use default transport
ctx := appengine.NewContext(r)
client := urlfetch.Client(ctx)
sg.Client = client // <-- now using urlfetch, "overriding" default
message := sendgrid.NewMail()
message.AddTo("ezra@usefultiftrue.com")
message.SetFrom("test@example.org")
message.SetSubject("SUBJECT HERE")
message.SetHTML("BODY OF THE EMAIL")
if e := sg.Send(message); e == nil {
fmt.Fprintln(w, "Sent!")
} else {
fmt.Fprintln(w, e)
}
}
func init() {
http.HandleFunc("/", send)
}
Now each visit to /
will cause an email to be sent by SendGrid to test@example.org
.
To: test@example.org
From: ezra@usefuliftrue.com
Subject: SUBJECT HERE
BODY OF THE EMAIL
Do not include your API keys in source code, or commit them to your source control. The above method is not advisable.