如何从Google App Engine Golang使用SendGrid?

时间:2018-04-01 07:55:02

标签: google-app-engine go sendgrid urlfetch sendgrid-api-v3

示例代码: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)


}

4 个答案:

答案 0 :(得分:2)

经过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)

一个复活节周末,之后,它有效!

答案 1 :(得分:1)

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

.
.
.
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方法获取网址。

引用AppEngine文档

  

App Engine使用URL Fetch服务发出出站HTTP(S)请求。要发出出站HTTP请求,请照常使用http包,但使用urlfetch.Client创建客户端。 urlfetch.Client返回一个使用urlfetch.Transport的* http.Client,它是http.RoundTripper接口的一个实现,它使用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

答案 2 :(得分:1)

该解决方案记录在 sendgrid.go 中:

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

因此,只需在发送开始时进行操作,其中 ctx appengine.NewContext(req)

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

答案 3 :(得分:0)

SendGrid 记录了使用Go on AppEngine发送电子邮件所需的最低代码 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)
    }
}