-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for CK receive message and status handlers
- Loading branch information
Showing
2 changed files
with
135 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,97 @@ | ||
package chikka | ||
|
||
/* no logs */ | ||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
"time" | ||
|
||
"github.com/nyaruka/courier" | ||
"github.com/nyaruka/courier/handlers" | ||
"github.com/nyaruka/gocommon/urns" | ||
) | ||
|
||
type handler struct { | ||
handlers.BaseHandler | ||
} | ||
|
||
func newHandler() courier.ChannelHandler { | ||
return &handler{handlers.NewBaseHandler(courier.ChannelType("CK"), "Chikka")} | ||
} | ||
|
||
func init() { | ||
courier.RegisterHandler(newHandler()) | ||
} | ||
|
||
// Initialize is called by the engine once everything is loaded | ||
func (h *handler) Initialize(s courier.Server) error { | ||
h.SetServer(s) | ||
return s.AddHandlerRoute(h, http.MethodPost, "receive", h.ReceiveMessage) | ||
} | ||
|
||
type moMsg struct { | ||
MessageType string `name:"message_type" validate:"required"` | ||
RequestID string `name:"request_id"` | ||
MobileNumber string `name:"mobile_number"` | ||
Message string `name:"message"` | ||
Timestamp float64 `name:"timestamp"` | ||
MessageID int64 `name:"message_id"` | ||
Status string `name:"status"` | ||
} | ||
|
||
var statusMapping = map[string]courier.MsgStatusValue{ | ||
"SENT": courier.MsgSent, | ||
"FAILED": courier.MsgFailed, | ||
} | ||
|
||
// ReceiveMessage is our HTTP handler function for incoming messages | ||
func (h *handler) ReceiveMessage(ctx context.Context, channel courier.Channel, w http.ResponseWriter, r *http.Request) ([]courier.Event, error) { | ||
ckRequest := &moMsg{} | ||
err := handlers.DecodeAndValidateForm(ckRequest, r) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if ckRequest.MessageType == "outgoing" { | ||
|
||
msgStatus, found := statusMapping[ckRequest.Status] | ||
if !found { | ||
return nil, courier.WriteAndLogRequestError(ctx, w, r, channel, fmt.Errorf(`unknown status '%s', must be either 'SENT' or 'FAILED'`, ckRequest.Status)) | ||
} | ||
|
||
// write our status | ||
status := h.Backend().NewMsgStatusForID(channel, courier.NewMsgID(ckRequest.MessageID), msgStatus) | ||
err = h.Backend().WriteMsgStatus(ctx, status) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return []courier.Event{status}, courier.WriteStatusSuccess(ctx, w, r, []courier.MsgStatus{status}) | ||
|
||
} else if ckRequest.MessageType == "incoming" { | ||
|
||
// create our date from the timestamp | ||
date := time.Unix(0, int64(ckRequest.Timestamp*1000000000)).UTC() | ||
|
||
// create our URN | ||
urn := urns.NewTelURNForCountry(ckRequest.MobileNumber, channel.Country()) | ||
|
||
// build our msg | ||
msg := h.Backend().NewIncomingMsg(channel, urn, ckRequest.Message).WithExternalID(ckRequest.RequestID).WithReceivedOn(date) | ||
|
||
// and finally queue our message | ||
err = h.Backend().WriteMsg(ctx, msg) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return []courier.Event{msg}, courier.WriteMsgSuccess(ctx, w, r, []courier.Msg{msg}) | ||
} else { | ||
return nil, courier.WriteAndLogRequestIgnored(ctx, w, r, channel, "unknown message_type request") | ||
} | ||
} | ||
|
||
// SendMsg sends the passed in message, returning any error | ||
func (h *handler) SendMsg(ctx context.Context, msg courier.Msg) (courier.MsgStatus, error) { | ||
return nil, fmt.Errorf("CK sending via courier not yet implemented") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package chikka | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
"github.com/nyaruka/courier" | ||
. "github.com/nyaruka/courier/handlers" | ||
) | ||
|
||
var testChannels = []courier.Channel{ | ||
courier.NewMockChannel("8eb23e93-5ecb-45ba-b726-3b064e0c56ab", "CK", "2020", "US", nil), | ||
} | ||
|
||
var ( | ||
receiveURL = "/c/ck/8eb23e93-5ecb-45ba-b726-3b064e0c56ab/receive/" | ||
validReceive = "message_type=incoming&mobile_number=639178020779&request_id=4004&message=Hello+World×tamp=1457670059.69" | ||
validSentStatus = "message_type=outgoing&message_id=10&status=SENT" | ||
validFailedStatus = "message_type=outgoing&message_id=10&status=FAILED" | ||
invalidStatus = "message_type=outgoing&message_id=10&status=UNKNOWN" | ||
) | ||
|
||
var testCases = []ChannelHandleTestCase{ | ||
{Label: "Receive Valid", URL: receiveURL, Data: validReceive, Status: 200, Response: "Message Accepted", | ||
Text: Sp("Hello World"), URN: Sp("tel:+639178020779"), ExternalID: Sp("4004"), | ||
Date: Tp(time.Date(2016, 03, 11, 04, 20, 59, 690000128, time.UTC))}, | ||
|
||
{Label: "Ignore Invalid message_type", URL: receiveURL, Data: "message_type=invalid", Status: 200, Response: "unknown message_type request"}, | ||
{Label: "Status Sent Valid", URL: receiveURL, Data: validSentStatus, Status: 200, Response: `"status":"S"`}, | ||
{Label: "Status Failed Valid", URL: receiveURL, Data: validFailedStatus, Status: 200, Response: `"status":"F"`}, | ||
{Label: "Status Invalid", URL: receiveURL, Data: invalidStatus, Status: 400, Response: `must be either 'SENT' or 'FAILED'`}, | ||
} | ||
|
||
func TestHandler(t *testing.T) { | ||
RunChannelTestCases(t, testChannels, newHandler(), testCases) | ||
} | ||
|
||
func BenchmarkHandler(b *testing.B) { | ||
RunChannelBenchmarks(b, testChannels, newHandler(), testCases) | ||
} |