dongliao6777
2018-04-01 07:55
浏览 82
已采纳

如何从Google App Engine Golang使用SendGrid?

The example code at: https://sendgrid.com/blog/send-email-go-google-app-engine/

My guess this is very old sample code to use sendgrid-go on Google App Engine.

I've attempted 4 permutations and failed each time with:

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/

Here is a minimum hardcoded attempt with some logging:

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)


}

图片转代码服务由CSDN问答提供 功能建议

示例代码位于:”> 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和http.DefaultClient在App Engine中不可用。 请参阅https://cloud.google.com/appengine/docs/go/urlfetch/
   
 
 

以下是使用某些日志记录的最小硬编码尝试:

 程序包sendgridgo 
 
 
import(
“ github.com/sendgrid/sendgrid-go"
” fmt“ 
 _” google.golang.org/appengine“ \  n“ 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, 错误:= sg.Send(m)
请求:= sendgrid.GetRequest(“ SENDGRID_API_KEY”,“ / v3 / mail / send”,“ https://api.sendgrid.com”)
 request.Method =“  POST” 
 
 request.Body = [] byte(`{
“个性化”:[
 {
“收件人”:[
 {
“电子邮件”:“ darian.hickman@gmail.com  “ 
} 
],
”主题“:”使用SendGrid发送很有趣“ 
} 
],
”来自“:{
”电子邮件“:” darian.hickman@villagethegame.com“  
},
“ content”:[
 {
“ type”:“ text / plain”,
“ value”:“即使在Go语言下,也可以轻松地在任何地方做” 
} 
] \  n}`)
响应,错误:= sendgrid.API(请求)
 
如果错误!= nil {
 log.Errorf(ctx,“失败的%v”,错误)
} 
 
  fmt.Fprint(w,resp)
 
 
} 
   
 
  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • donglvhe7591 2018-04-03 00:40
    已采纳

    After 8 different attempts, including trying an example published in Google Cloud docs for using Sendgrid, an example from Sendgrid blog, and trying to use deprecated versions of Sendgrid api, I found Sendgrid curl examples at:

    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!"}]}'
    

    I then translated the HelloWorld example to into URLFetch usage

    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)
    

    One Easter weekend, later, it works!

    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • dongtan7351 2018-04-02 07:26

    You were on the right track, but skipped overriding the default sendgrid client with urlfetch client.

    .
    .
    .
    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"
    .
    .
    .
    

    Explanation

    The error occurs as sendgrid tries to fetch a url with the default net/http method.

    Quoting AppEngine Documentation

    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.

    The workaround is to override the Sendgrid client to use urlfetch

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

    References

    1. GCloud Documentation- Issuing HTTP(S) Requests in App Engine Golang
    评论
    解决 无用
    打赏 举报
  • douxin20081125 2018-08-04 13:52

    The solution is documented in sendgrid.go:

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

    So just do this at the beginning of your send, where ctx is appengine.NewContext(req):

    sendgrid.DefaultClient = &rest.Client{HTTPClient: urlfetch.Client(ctx)}
    
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题