Skip to content

Instantly share code, notes, and snippets.

@iwashi623
Created February 21, 2023 07:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iwashi623/36607d75f6035b3a511cdda8e334fd76 to your computer and use it in GitHub Desktop.
Save iwashi623/36607d75f6035b3a511cdda8e334fd76 to your computer and use it in GitHub Desktop.
SendGridのWebAPIを使ってメールを送信するためのLambdaアプリケーション
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/sendgrid/sendgrid-go"
)
type systemManagerResponse struct {
Parameter systemManagerResponseParameter `json:"Parameter"`
}
type systemManagerResponseParameter struct {
Arn string `json:"ARN"`
DataType string `json:"DataType"`
LastModifiedDate time.Time `json:"LastModifiedDate"`
Name string `json:"Name"`
Selector interface{} `json:"Selector"`
SourceResult interface{} `json:"SourceResult"`
Type string `json:"Type"`
Value string `json:"Value"`
Version int `json:"Version"`
}
/**
SystemManager parameter storeからAPI_KEYを取得する
@see https://docs.aws.amazon.com/systems-manager/latest/userguide/ps-integration-lambda-extensions.html
*/
func getAPIKey() (*string, error) {
url := fmt.Sprintf("http://localhost:2773/systemsmanager/parameters/get?name=%s&withDecryption=true", os.Getenv("API_KEY_PATH"))
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Printf("ERROR: %v", err)
return nil, err
}
req.Header.Set("X-Aws-Parameters-Secrets-Token", os.Getenv("AWS_SESSION_TOKEN"))
client := http.Client{
Timeout: 5 * time.Second,
}
res, err := client.Do(req)
if err != nil {
log.Printf("ERROR: %v", err)
return nil, err
}
defer res.Body.Close()
var smr systemManagerResponse
json.NewDecoder(res.Body).Decode(&smr)
if err != nil {
log.Printf("ERROR: %v", err)
return nil, err
}
return &smr.Parameter.Value, nil
}
func sendMail(messageBody string) error {
apiKey, err := getAPIKey()
if err != nil {
log.Printf("ERROR: %v", err)
return err
}
// SQSのキュー情報をそのままメール送信APIに渡すだけ
req := sendgrid.GetRequest(*apiKey, "/v3/mail/send", "https://api.sendgrid.com")
req.Method = "POST"
req.Body = []byte(messageBody)
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
res, err := sendgrid.MakeRequestWithContext(ctx, req)
// @see https://sendgrid.kke.co.jp/docs/API_Reference/Web_API_v3/Mail/errors.html
if err != nil || res.StatusCode != 202 {
log.Printf("ERROR: %v", err)
log.Printf("StatusCode: %v", res.StatusCode)
log.Printf("Response Headers: %v", res.Headers)
log.Printf("Response Body: %v", res.Body)
return fmt.Errorf("%s", "failed to send email.")
}
return nil
}
func handler(ctx context.Context, sqsEvent events.SQSEvent) error {
for _, message := range sqsEvent.Records {
err := sendMail(message.Body)
if err != nil {
log.Printf("ERROR: %v", err.Error())
// 関数を異常終了させてキューを戻す
os.Exit(1)
}
}
return nil
}
func init() {
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
}
func main() {
lambda.Start(handler)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment