Esta é a biblioteca Go oficial para envio de notificações com a API Courier REST.
Para obter uma descrição completa das cargas e propriedades de solicitação e resposta, consulte os documentos oficiais da API Courier.
Este módulo requer a versão Go >= 1.13.
Execute o seguinte comando para usar a biblioteca Go em seu módulo 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 )
Nossa API, principalmente o método send, usa diversas uniões. Nosso Go SDK define estruturas para construir essas uniões, como courier.Message
, mostradas abaixo:
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!" ,
},
},
},
},
}
Introduzimos uma melhor experiência de construção de sindicatos na versão 3.0.8. Por exemplo, o tipo courier.Message
foi construído anteriormente com o seguinte:
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!" ,
},
),
},
),
}
Embora a construção pareça bastante semelhante, a abordagem antiga exigia navegar por uma variedade de nomes complicados de funções construtoras (por exemplo, courier.NewContentFromElementalContentSugar
).
A nova abordagem elimina totalmente esses construtores, o que simplifica significativamente a experiência. Migrar da abordagem antiga é tão simples quanto definir o tipo concreto no campo apropriado da seguinte forma:
Antes
...
Content : courier . NewContentFromElementalContentSugar (
& courier. ElementalContentSugar {
Title : "Back to the Future" ,
Body : "Oh my {{name}}, we need 1.21 Gigawatts!" ,
},
),
...
Depois
...
Content : & courier. Content {
ElementalContentSugar : & courier. ElementalContentSugar {
Title : "Back to the Future" ,
Body : "Oh my {{name}}, we need 1.21 Gigawatts!" ,
},
},
...
Definir um tempo limite para cada solicitação individual é tão simples quanto usar a biblioteca context
padrão. Definir um tempo limite de um segundo para uma chamada de API individual é semelhante ao seguinte:
ctx , cancel := context . WithTimeout ( context . TODO (), time . Second )
defer cancel ()
response , err := client . Send (
ctx ,
& courier. SendMessageRequest {
Message : ...
},
)
Uma variedade de opções de cliente estão incluídas para adaptar o comportamento da biblioteca, o que inclui a configuração de tokens de autorização a serem enviados em cada solicitação ou o fornecimento de seu próprio *http.Client
instrumentado. Ambas as opções são mostradas abaixo:
client := courierclient . NewClient (
option . WithAuthorizationToken ( "" ),
option . WithHTTPClient (
& http. Client {
Timeout : 5 * time . Second ,
},
),
)
É recomendado fornecer seu próprio
*http.Client
. Caso contrário, ohttp.DefaultClient
será usado e seu cliente aguardará indefinidamente por uma resposta (a menos que o tempo limite baseado em contexto por solicitação seja usado).
Os tipos de erros estruturados são retornados de chamadas de API que retornam códigos de status de falha. Por exemplo, você pode verificar se o erro foi devido a uma solicitação incorreta (ou seja, código de status 400) com o seguinte:
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
}
Esses erros também são compatíveis com as APIs errors.Is
e errors.As
, então você pode acessar o erro assim:
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
}
Se quiser agrupar os erros com informações adicionais e ainda manter a capacidade de acessar o tipo com errors.Is
e errors.As
, você pode usar a diretiva %w
:
response , err := client . Send (
context . TODO (),
& courier. SendMessageRequest {},
)
if err != nil {
return fmt . Errorf ( "failed to list employees: %w" , err )
}
Embora valorizemos as contribuições de código aberto para este SDK, esta biblioteca é gerada programaticamente. Adições feitas diretamente a esta biblioteca teriam que ser movidas para nosso código de geração, caso contrário seriam substituídas na próxima versão gerada. Sinta-se à vontade para abrir um PR como prova de conceito, mas saiba que não poderemos mesclá-lo como está. Sugerimos abrir uma edição primeiro para discutir conosco!
Por outro lado, contribuições para o README são sempre muito bem-vindas!