如何使用 Google App Engine Golang 中的 SendGrid?

How to use SendGrid from Google App Engine Golang?

示例代码位于:https://sendgrid.com/blog/send-email-go-google-app-engine/

我猜这是在 Google App Engine 上使用 sendgrid-go 的非常古老的示例代码。

我尝试了 4 次排列,但每次都失败了:

https://api.sendgrid.com/v3/mail/send: http.DefaultTransport and http.DefaultClient are not available in App Engine. See https://cloud.google.com/appengine/docs/go/urlfetch/

这是对一些日志记录的最小硬编码尝试:

package sendgridgo


import(
    "github.com/sendgrid/sendgrid-go"
    "fmt"
    _"google.golang.org/appengine"
    "net/http"
    "google.golang.org/appengine/log"
    "google.golang.org/appengine"
    "google.golang.org/appengine/urlfetch"
     _ "github.com/sendgrid/sendgrid-go/helpers/mail"
)

func init(){
    http.HandleFunc("/", IndexHandler)
    appengine.Main()
}

func IndexHandler (w http.ResponseWriter, r *http.Request){
    ctx := appengine.NewContext(r)

    log.Infof(ctx, "IndexHandler")
    sg := sendgrid.NewSendClient("SENDGRID_API_KEY")
    log.Infof(ctx, "%v", sg)
    bob := urlfetch.Client(ctx)

    log.Infof(ctx, "UrlFetchClient %v", bob)
    //resp, err := sg.Send(m)
    request := sendgrid.GetRequest("SENDGRID_API_KEY", "/v3/mail/send", "https://api.sendgrid.com")
    request.Method = "POST"

    request.Body = []byte(` {
    "personalizations": [
        {
            "to": [
                {
                    "email": "darian.hickman@gmail.com"
                }
            ],
            "subject": "Sending with SendGrid is Fun"
        }
    ],
    "from": {
        "email": "darian.hickman@villagethegame.com"
    },
    "content": [
        {
            "type": "text/plain",
            "value": "and easy to do anywhere, even with Go"
        }
    ]
}`)
    resp, err := sendgrid.API(request)

    if err != nil{
        log.Errorf(ctx, "Failed %v", err)
    }

    fmt.Fprint(w, resp)


}

您走在正确的轨道上,但是跳过了使用 urlfetch 客户端覆盖默认 sendgrid 客户端。

.
.
.
func IndexHandler (w http.ResponseWriter, r *http.Request){
    ctx := appengine.NewContext(r)    
    sg := sendgrid.NewSendClient("REPLACE_WITH_API_KEY")
    bob := urlfetch.Client(ctx)

    sg.Client = bob

    request := sendgrid.GetRequest("REPLACE_WITH_API_KEY", "/v3/mail/send", "https://api.sendgrid.com")
    request.Method = "POST"
.
.
.

说明

当 sendgrid 尝试使用默认 net/http 方法获取 url 时发生错误。

引用 AppEngine 文档

App Engine uses the URL Fetch service to issue outbound HTTP(S) requests. To issue an outbound HTTP request, use the http package as usual, but create your client using urlfetch.Client. urlfetch.Client returns an *http.Client that uses urlfetch.Transport, which is an implementation of the http.RoundTripper interface that makes requests using the URL Fetch API.

解决方法是覆盖 Sendgrid 客户端以使用 urlfetch

        context := appengine.NewContext(r)
        sg := sendgrid.NewSendClient(os.Getenv("SENDGRID_API_KEY"))
        sg.Client = urlfetch.Client(context)

参考资料

  1. GCloud Documentation- Issuing HTTP(S) Requests in App Engine Golang

经过 8 次不同的尝试,包括尝试在 Google Cloud 文档中发布的使用 Sendgrid 的示例、来自 Sendgrid 博客的示例,以及尝试使用已弃用的 Sendgrid 版本 api,我找到了 Sendgrid卷曲示例位于:

https://sendgrid.com/docs/Classroom/Send/v3_Mail_Send/curl_examples.html

curl --request POST \
  --url https://api.sendgrid.com/v3/mail/send \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{"personalizations": [{"to": [{"email": "recipient@example.com"}]}],"from": {"email": "sendeexampexample@example.com"},"subject": "Hello, World!","content": [{"type": "text/plain", "value": "Heya!"}]}'

然后我将 HelloWorld 示例翻译成 URLFetch 用法

client := urlfetch.Client(ctx)

request, err := http.NewRequest("POST", "https://api.sendgrid.com/v3/mail/send", buf)
    if err != nil {
        log.Errorf(ctx, "Failed Request %v", request)
    }
    request.Header.Set("Authorization", "Bearer SENDGRID_API_KEY")
    request.Header.Set("Content-Type", "application/json")
    resp, err := client.Do(request)

一个复活节周末,稍后,它起作用了!

解决方案记录在sendgrid.go:

// DefaultClient is used if no custom HTTP client is defined
var DefaultClient = rest.DefaultClient

所以只需在发送开始时执行此操作,其中 ctxappengine.NewContext(req):

sendgrid.DefaultClient = &rest.Client{HTTPClient: urlfetch.Client(ctx)}

SendGrid 记录在 AppEngine 中使用 Go 发送电子邮件所需的最少代码 How to send email using Go。它不同于@birju-prajapati 的回答;客户端是用 sendgrid.NewSendClient.

创建的

必须生成 API 密钥,并使用 SENDGRID_API_KEY 更新您的开发环境。然后用 go get github.com/sendgrid/sendgrid-go 安装 sendgrid-go 及其依赖项。

// using SendGrid's Go Library
// https://github.com/sendgrid/sendgrid-go
package main

import (
    "fmt"
    "log"
    "os"

    "github.com/sendgrid/sendgrid-go"
    "github.com/sendgrid/sendgrid-go/helpers/mail"
)

func main() {
    from := mail.NewEmail("Example User", "test@example.com")
    subject := "Sending with SendGrid is Fun"
    to := mail.NewEmail("Example User", "test@example.com")
    plainTextContent := "and easy to do anywhere, even with Go"
    htmlContent := "<strong>and easy to do anywhere, even with Go</strong>"
    message := mail.NewSingleEmail(from, subject, to, plainTextContent, htmlContent)
    client := sendgrid.NewSendClient(os.Getenv("SENDGRID_API_KEY"))
    response, err := client.Send(message)
    if err != nil {
        log.Println(err)
    } else {
        fmt.Println(response.StatusCode)
        fmt.Println(response.Body)
        fmt.Println(response.Headers)
    }
}