【问题标题】:Go sendgrid failing去 sendgrid 失败
【发布时间】:2016-02-08 10:14:38
【问题描述】:

我正在尝试使用 sendgrid 和 golang 发送邮件。 我正在使用"github.com/sendgrid/sendgrid-go"

每当我在代码中运行发送电子邮件的部分时,都会收到此错误:

sendgrid.go: error:net/http: Client Transport of type init.failingTransport doesn't support CancelRequest; Timeout not supported; response:<nil>

我不知道它是什么..

这是我的代码:

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
    }

【问题讨论】:

  • 看起来好像你正在超时。如果您也尝试远程登录到邮件服务器上的 25 端口,是否会超时?
  • 我无法使用端口 25 远程登录到 smtp.sendgrid.net。但是如果我使用另一个端口 587 可以远程登录。也许这就是问题所在?
  • 让我重新表述一下:如果您遇到超时错误,请先验证连接,而不是验证代码。我不知道这个特定的服务,所以我不能确切地告诉你应该如何测试它——但如果你使用 SMTP,你可能必须告诉你的应用程序使用 587 而不是 25。如果你'再次使用 HTTP/HTTPS API,首先验证与该端口的连接。
  • 只是烦人:它被称为 Go 而不是 golang。
  • Golang 的浏览器友好性,是的。这很烦人。

标签: google-app-engine go sendgrid


【解决方案1】:

Go 中的普通 Sendgrid API 用法

在 Go 中使用 Sendgrid API 的最小程序如下所示:

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)
    }
}

你可以看到Sendgrid Go Documentation on Github。

App Engine 上的怪癖

问题是您尝试使用默认的 net/http 客户端获取 URL,这是 App Engine 不允许的。 You must use urlfetch to make HTTP requests on App Engine.

您可以通过将*http.Client 指定为使用urlfetch 来解决此问题,因为Sendgrid 使用默认情况下使用不允许的http.DefaultTransport 的客户端。 init.failingTransport 是一个虚拟传输方法,基本上只是抛出一个错误。

这最终是一个简单的改变。只需导入"appengine/urlfetch" 并添加

client := urlfetch.Client(ctx)

App Engine 上 SendGrid Go API 的完整示例

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)
}

现在每次访问 / 都会导致 SendGrid 向 test@example.org 发送一封电子邮件。

To: test@example.org
From: ezra@usefuliftrue.com
Subject: SUBJECT HERE

BODY OF THE EMAIL

请注意

不要在源代码中包含您的 API 密钥,或将它们提交给您的源代码控制。上述方法不可取。

【讨论】:

  • 我还没来得及测试它。该代码使用 sendgrid 以外的另一种解决方案进行部署。每当我更改该解决方案时,我都会回到这一点,并且我将来会这样做。非常感谢您理解我的问题并提供您的解决方案。
  • 请问您的替代提供商是谁?
  • 当然。我正在使用 Google 应用引擎自己的邮件系统。缺点是我必须创建一个单独的电子邮件用户才能从“noreply”发送。但它比 sendgrid 还要简单。
  • 有趣。谢谢!我假设您是 100% 事务性的,所以这没什么大不了的,但我发现大多数专门的邮件提供商供应商的“破折号”和统计数据是我永远不想没有的东西。祝你的应用好运!干杯,
猜你喜欢
  • 2018-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-04
  • 1970-01-01
  • 2021-09-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多