Il s'agit de la bibliothèque Go officielle pour l'envoi de notifications avec l'API Courier REST.
Pour une description complète des charges utiles et des propriétés des requêtes et des réponses, veuillez consulter la documentation officielle de l'API Courier.
Ce module nécessite la version Go >= 1.13.
Exécutez la commande suivante pour utiliser la bibliothèque Go dans votre module 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 )
Notre API, notamment la méthode send, utilise plusieurs unions. Notre SDK Go définit des structures pour construire ces unions, telles que courier.Message
, illustrées ci-dessous :
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!" ,
},
},
},
},
}
Nous avons introduit une meilleure expérience de construction de syndicats dans la version 3.0.8. Par exemple, le type courier.Message
a été précédemment construit avec ce qui suit :
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!" ,
},
),
},
),
}
Bien que la construction semble assez similaire, l'ancienne approche nécessitait de naviguer dans une variété de noms de fonctions de constructeur encombrants (par exemple courier.NewContentFromElementalContentSugar
).
La nouvelle approche supprime complètement ces constructeurs, ce qui simplifie considérablement l'expérience. Migrer depuis l'ancienne approche est aussi simple que de définir le type concret dans le champ approprié, comme ceci :
Avant
...
Content : courier . NewContentFromElementalContentSugar (
& courier. ElementalContentSugar {
Title : "Back to the Future" ,
Body : "Oh my {{name}}, we need 1.21 Gigawatts!" ,
},
),
...
Après
...
Content : & courier. Content {
ElementalContentSugar : & courier. ElementalContentSugar {
Title : "Back to the Future" ,
Body : "Oh my {{name}}, we need 1.21 Gigawatts!" ,
},
},
...
Définir un délai d'attente pour chaque requête individuelle est aussi simple que d'utiliser la bibliothèque context
standard. La définition d'un délai d'expiration d'une seconde pour un appel d'API individuel ressemble à ce qui suit :
ctx , cancel := context . WithTimeout ( context . TODO (), time . Second )
defer cancel ()
response , err := client . Send (
ctx ,
& courier. SendMessageRequest {
Message : ...
},
)
Une variété d'options client sont incluses pour adapter le comportement de la bibliothèque, notamment la configuration des jetons d'autorisation à envoyer à chaque demande, ou la fourniture de votre propre *http.Client
instrumenté. Ces deux options sont présentées ci-dessous :
client := courierclient . NewClient (
option . WithAuthorizationToken ( "" ),
option . WithHTTPClient (
& http. Client {
Timeout : 5 * time . Second ,
},
),
)
Il est recommandé de fournir votre propre
*http.Client
. Sinon,http.DefaultClient
sera utilisé et votre client attendra indéfiniment une réponse (à moins que le délai d'attente contextuel par demande ne soit utilisé).
Les types d'erreur structurés sont renvoyés par les appels d'API qui renvoient des codes d'état d'échec. Par exemple, vous pouvez vérifier si l'erreur était due à une mauvaise demande (c'est-à-dire le code d'état 400) avec ce qui suit :
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
}
Ces erreurs sont également compatibles avec les API errors.Is
et errors.As
, vous pouvez donc accéder à l'erreur comme suit :
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
}
Si vous souhaitez envelopper les erreurs avec des informations supplémentaires tout en conservant la possibilité d'accéder au type avec errors.Is
et errors.As
, vous pouvez utiliser la directive %w
:
response , err := client . Send (
context . TODO (),
& courier. SendMessageRequest {},
)
if err != nil {
return fmt . Errorf ( "failed to list employees: %w" , err )
}
Bien que nous apprécions les contributions open source à ce SDK, cette bibliothèque est générée par programme. Les ajouts effectués directement à cette bibliothèque devraient être déplacés vers notre code de génération, sinon ils seraient écrasés lors de la prochaine version générée. N'hésitez pas à ouvrir un PR comme preuve de concept, mais sachez que nous ne pourrons pas le fusionner tel quel. Nous vous suggérons d’ouvrir d’abord un numéro pour en discuter avec nous !
D’un autre côté, les contributions au README sont toujours les bienvenues !