Skip to content

Commit

Permalink
Add support for CK receive message and status handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
norkans7 committed Feb 19, 2018
1 parent e76e9d6 commit 5dd716f
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 1 deletion.
96 changes: 95 additions & 1 deletion handlers/chikka/chikka.go
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")
}
40 changes: 40 additions & 0 deletions handlers/chikka/chikka_test.go
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&timestamp=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)
}

0 comments on commit 5dd716f

Please sign in to comment.