Skip to content

Commit

Permalink
Support email received webhook (#271)
Browse files Browse the repository at this point in the history
  • Loading branch information
harryzcy authored May 28, 2023
1 parent 89d95f3 commit 562a090
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 1 deletion.
16 changes: 15 additions & 1 deletion functions/emailReceive/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/harryzcy/mailbox/internal/env"
"github.com/harryzcy/mailbox/internal/thread"
"github.com/harryzcy/mailbox/internal/util/format"
"github.com/harryzcy/mailbox/internal/webhook"
)

func main() {
Expand Down Expand Up @@ -108,7 +109,20 @@ func receiveEmail(ctx context.Context, ses events.SimpleEmailService) {
Timestamp: ses.Mail.Timestamp.UTC().Format(time.RFC3339),
})
if err != nil {
log.Fatalf("failed to send email receipt to SQS, %v", err)
log.Printf("failed to send email receipt to SQS, %v\n", err)
}
}

if webhook.Enabled() {
err = webhook.SendWebhook(ctx, &webhook.Webhook{
Event: webhook.EventEmail,
Action: webhook.ActionReceived,
Email: webhook.Email{
ID: ses.Mail.MessageID,
},
})
if err != nil {
log.Printf("failed to send webhook, %v\n", err)
}
}
}
2 changes: 2 additions & 0 deletions internal/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ var (
GsiIndexName = os.Getenv("DYNAMODB_TIME_INDEX")
S3Bucket = os.Getenv("S3_BUCKET")
QueueName = os.Getenv("SQS_QUEUE")

WebhookURL = os.Getenv("WEBHOOK_URL")
)
53 changes: 53 additions & 0 deletions internal/webhook/webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package webhook

import (
"bytes"
"context"
"encoding/json"
"net/http"
"time"

"github.com/harryzcy/mailbox/internal/env"
)

const (
EventEmail = "email"
ActionReceived = "received"
)

type Webhook struct {
Event string `json:"event"`
Action string `json:"action"`
Email Email
}

type Email struct {
ID string `json:"id"` // message id
}

func Enabled() bool {
return env.WebhookURL != ""
}

func SendWebhook(ctx context.Context, data *Webhook) error {
client := http.Client{
Timeout: 5 * time.Second,
}

body, err := json.Marshal(data)
if err != nil {
return err
}
req, err := http.NewRequestWithContext(ctx, "POST", env.WebhookURL, bytes.NewReader(body))
if err != nil {
return err
}

res, err := client.Do(req)
if err != nil {
return err
}
defer res.Body.Close()

return nil
}
45 changes: 45 additions & 0 deletions internal/webhook/webhook_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package webhook

import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"

"github.com/harryzcy/mailbox/internal/env"
"github.com/stretchr/testify/assert"
)

func TestSendWebhook(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
var webhook Webhook
err := json.NewDecoder(req.Body).Decode(&webhook)
assert.Nil(t, err)
assert.Equal(t, EventEmail, webhook.Event)
assert.Equal(t, ActionReceived, webhook.Action)
assert.Equal(t, "123", webhook.Email.ID)

_, err = rw.Write([]byte("OK"))
assert.Nil(t, err)
}))
defer server.Close()

env.WebhookURL = server.URL
err := SendWebhook(context.Background(), &Webhook{
Event: EventEmail,
Action: ActionReceived,
Email: Email{ID: "123"},
})
assert.Nil(t, err)
}

func TestSendWebhook_Error(t *testing.T) {
env.WebhookURL = ""
err := SendWebhook(context.Background(), &Webhook{
Event: EventEmail,
Action: ActionReceived,
Email: Email{ID: "123"},
})
assert.NotNil(t, err)
}

0 comments on commit 562a090

Please sign in to comment.