这是使用 Courier REST API 发送通知的官方 Go 库。
有关请求和响应负载及属性的完整说明,请参阅官方 Courier API 文档。
该模块需要 Go 版本 >= 1.13。
运行以下命令以在 Go 模块中使用 Go 库:
go get github.com/trycourier/courier-go/v3
import (
"context"
"fmt"
courierclient "github.com/trycourier/courier-go/v3/client"
option "github.com/trycourier/courier-go/v3/option"
)
client := courierclient . NewClient (
option . WithAuthorizationToken ( "" ),
)
import ( "context" "fmt" courier "github.com/trycourier/courier-go/v3" courierclient "github.com/trycourier/courier-go/v3/client" option "github.com/trycourier/courier-go/v3/option" ) client := courierclient . NewClient ( option . WithAuthorizationToken ( "" ), ) sendResponse , err := client . Send ( context . TODO (), & courier. SendMessageRequest { Message : courier. NewMessageFromTemplateMessage ({ Template : "" , }), }, ) if err != nil { return err } fmt . Printf ( "Sent message %s n " , sendResponse . RequestId )
我们的 API,特别是 send 方法,使用了多个联合。我们的 Go SDK 定义了构建这些联合的结构,例如courier.Message
,如下所示:
import (
courier "github.com/trycourier/courier-go/v3"
)
request := & courier. SendMessageRequest {
// Construct a content message.
Message : & courier. Message {
ContentMessage : & courier. ContentMessage {
// Construct a single recepient that is a user recepient.
To : & courier. MessageRecipient {
Recipient : & courier. Recipient {
UserRecipient : & courier. UserRecipient {
Email : courier . String ( "[email protected]" ),
Data : & courier. MessageData {
"name" : "Marty" ,
},
},
},
},
// Construct content from elemental content sugar.
Content : & courier. Content {
ElementalContentSugar : & courier. ElementalContentSugar {
Title : "Back to the Future" ,
Body : "Oh my {{name}}, we need 1.21 Gigawatts!" ,
},
},
},
},
}
我们在3.0.8中引入了更好的工会建设体验。例如, courier.Message
类型之前是使用以下内容构造的:
import (
courier "github.com/trycourier/courier-go/v3"
)
request := courier. SendMessageRequest {
// Construct a content message.
Message : courier . NewMessageFromContentMessage (
& courier. ContentMessage {
// Construct a single recepient that is a user recepient.
To : courier . NewMessageRecipientFromRecipient (
courier . NewRecipientFromUserRecipient (
& courier. UserRecipient {
Email : courier . String ( "[email protected]" ),
Data : & courier. MessageData {
"name" : "Marty" ,
},
},
),
),
// Construct content from elemental content sugar.
Content : courier . NewContentFromElementalContentSugar (
& courier. ElementalContentSugar {
Title : "Back to the Future" ,
Body : "Oh my {{name}}, we need 1.21 Gigawatts!" ,
},
),
},
),
}
尽管构造看起来非常相似,但旧方法需要导航各种繁琐的构造函数名称(例如courier.NewContentFromElementalContentSugar
)。
新方法完全放弃了这些构造函数,从而显着简化了体验。从旧方法迁移就像将具体类型设置为适当的字段一样简单,如下所示:
前
...
Content : courier . NewContentFromElementalContentSugar (
& courier. ElementalContentSugar {
Title : "Back to the Future" ,
Body : "Oh my {{name}}, we need 1.21 Gigawatts!" ,
},
),
...
后
...
Content : & courier. Content {
ElementalContentSugar : & courier. ElementalContentSugar {
Title : "Back to the Future" ,
Body : "Oh my {{name}}, we need 1.21 Gigawatts!" ,
},
},
...
为每个单独的请求设置超时就像使用标准context
文库一样简单。为单个 API 调用设置一秒超时如下所示:
ctx , cancel := context . WithTimeout ( context . TODO (), time . Second )
defer cancel ()
response , err := client . Send (
ctx ,
& courier. SendMessageRequest {
Message : ...
},
)
包含各种客户端选项来适应库的行为,其中包括配置在每个请求上发送的授权令牌,或提供您自己的检测*http.Client
。这两个选项如下所示:
client := courierclient . NewClient (
option . WithAuthorizationToken ( "" ),
option . WithHTTPClient (
& http. Client {
Timeout : 5 * time . Second ,
},
),
)
建议提供您自己的
*http.Client
。否则,将使用http.DefaultClient
,并且您的客户端将无限期地等待响应(除非使用每个请求、基于上下文的超时)。
结构化错误类型是从返回非成功状态代码的 API 调用返回的。例如,您可以使用以下命令检查错误是否是由于错误请求(即状态代码 400)引起的:
response , err := client . Send (
context . TODO (),
& courier. SendMessageRequest {},
)
if err != nil {
if apiErr , ok := err .( * core. APIError ); ok && apiErr . StatusCode == http . StatusBadRequest {
// Do something with the bad request ...
}
return err
}
这些错误也与errors.Is
和errors.As
API兼容,因此您可以像这样访问错误:
response , err := client . Send (
context . TODO (),
& courier. SendMessageRequest {},
)
if err != nil {
var apiErr * core. APIError
if errors . As ( err , apiError ); ok {
switch apiErr . StatusCode {
case http . StatusBadRequest :
// Do something with the bad request ...
}
}
return err
}
如果您想用附加信息包装错误,并仍然保留使用errors.Is
和errors.As
访问类型的能力,您可以使用%w
指令:
response , err := client . Send (
context . TODO (),
& courier. SendMessageRequest {},
)
if err != nil {
return fmt . Errorf ( "failed to list employees: %w" , err )
}
虽然我们重视对此 SDK 的开源贡献,但该库是通过编程方式生成的。直接对该库进行的添加必须移至我们的生成代码中,否则它们将在下一个生成的版本中被覆盖。请随意打开 PR 作为概念证明,但要知道我们无法按原样合并它。我们建议先打开一个问题与我们讨论!
另一方面,我们始终非常欢迎对自述文件做出贡献!