-
Notifications
You must be signed in to change notification settings - Fork 71
/
Copy pathhandler.go
102 lines (83 loc) · 3.56 KB
/
handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package test
import (
"context"
"errors"
"net/http"
"github.com/nyaruka/courier"
"github.com/nyaruka/courier/utils/clogs"
"github.com/nyaruka/gocommon/httpx"
"github.com/nyaruka/gocommon/urns"
)
func init() {
courier.RegisterHandler(NewMockHandler())
}
type mockHandler struct {
server courier.Server
backend courier.Backend
}
// NewMockHandler returns a new mock handler
func NewMockHandler() courier.ChannelHandler {
return &mockHandler{}
}
func (h *mockHandler) Server() courier.Server { return h.server }
func (h *mockHandler) ChannelName() string { return "Mock Handler" }
func (h *mockHandler) ChannelType() courier.ChannelType { return courier.ChannelType("MCK") }
func (h *mockHandler) UseChannelRouteUUID() bool { return true }
func (h *mockHandler) RedactValues(courier.Channel) []string { return []string{"sesame"} }
func (h *mockHandler) GetChannel(ctx context.Context, r *http.Request) (courier.Channel, error) {
dmChannel := NewMockChannel("e4bb1578-29da-4fa5-a214-9da19dd24230", "MCK", "2020", "US", []string{urns.Phone.Prefix}, map[string]any{})
return dmChannel, nil
}
// Initialize is called by the engine once everything is loaded
func (h *mockHandler) Initialize(s courier.Server) error {
h.server = s
h.backend = s.Backend()
s.AddHandlerRoute(h, http.MethodGet, "receive", courier.ChannelLogTypeMsgReceive, h.receiveMsg)
return nil
}
// Send sends the given message, logging any HTTP calls or errors
func (h *mockHandler) Send(ctx context.Context, msg courier.MsgOut, res *courier.SendResult, clog *courier.ChannelLog) error {
// log a request that contains a header value that should be redacted
req, _ := httpx.NewRequest("GET", "http://mock.com/send", nil, map[string]string{"Authorization": "Token sesame"})
trace, err := httpx.DoTrace(http.DefaultClient, req, nil, nil, 1024)
clog.HTTP(trace)
if err != nil || trace.Response.StatusCode/100 == 5 {
return courier.ErrConnectionFailed
} else if trace.Response.StatusCode == 403 {
return courier.ErrContactStopped
} else if trace.Response.StatusCode == 429 {
return courier.ErrConnectionThrottled
}
// log an error than contains a value that should be redacted
clog.Error(&clogs.LogError{Code: "seeds", Message: "contains sesame seeds"})
if msg.Text() == "err:config" {
return courier.ErrChannelConfig
}
return nil
}
func (h *mockHandler) WriteStatusSuccessResponse(ctx context.Context, w http.ResponseWriter, statuses []courier.StatusUpdate) error {
return courier.WriteStatusSuccess(w, statuses)
}
func (h *mockHandler) WriteMsgSuccessResponse(ctx context.Context, w http.ResponseWriter, msgs []courier.MsgIn) error {
return courier.WriteMsgSuccess(w, msgs)
}
func (h *mockHandler) WriteRequestError(ctx context.Context, w http.ResponseWriter, err error) error {
return courier.WriteError(w, http.StatusBadRequest, err)
}
func (h *mockHandler) WriteRequestIgnored(ctx context.Context, w http.ResponseWriter, details string) error {
return courier.WriteIgnored(w, details)
}
// ReceiveMsg sends the passed in message, returning any error
func (h *mockHandler) receiveMsg(ctx context.Context, channel courier.Channel, w http.ResponseWriter, r *http.Request, clog *courier.ChannelLog) ([]courier.Event, error) {
r.ParseForm()
from := r.Form.Get("from")
text := r.Form.Get("text")
if from == "" || text == "" {
return nil, errors.New("missing from or text")
}
msg := h.backend.NewIncomingMsg(channel, urns.URN("tel:"+from), text, "", clog)
w.WriteHeader(200)
w.Write([]byte("ok"))
h.backend.WriteMsg(ctx, msg, clog)
return []courier.Event{msg}, nil
}