Skip to content

Commit

Permalink
Merge pull request #701 from nyaruka/ijk-sends
Browse files Browse the repository at this point in the history
Update I*,J*, K* handlers to use new send
  • Loading branch information
rowanseymour authored Feb 28, 2024
2 parents eadf5a7 + 08ce2dc commit 7a79316
Show file tree
Hide file tree
Showing 14 changed files with 739 additions and 523 deletions.
39 changes: 12 additions & 27 deletions handlers/i2sms/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,30 +81,17 @@ type mtResponse struct {
SessionID string `json:"session_id"`
} `json:"result"`
ErrorCode string `json:"error_code"`
ErrorDesc string `json:"error_desc"`
}

func (h *handler) Send(ctx context.Context, msg courier.MsgOut, res *courier.SendResult, clog *courier.ChannelLog) error {
// TODO convert functionality from legacy method below
return nil
}

func (h *handler) SendLegacy(ctx context.Context, msg courier.MsgOut, clog *courier.ChannelLog) (courier.StatusUpdate, error) {
username := msg.Channel().StringConfigForKey(courier.ConfigUsername, "")
if username == "" {
return nil, fmt.Errorf("no username set for I2 channel")
}

password := msg.Channel().StringConfigForKey(courier.ConfigPassword, "")
if password == "" {
return nil, fmt.Errorf("no password set for I2 channel")
}

channelHash := msg.Channel().StringConfigForKey(configChannelHash, "")
if channelHash == "" {
return nil, fmt.Errorf("no channel_hash set for I2 channel")
if username == "" || password == "" || channelHash == "" {
return courier.ErrChannelConfig
}

status := h.Backend().NewStatusUpdate(msg.Channel(), msg.ID(), courier.MsgStatusErrored, clog)
for _, part := range handlers.SplitMsgByChannel(msg.Channel(), handlers.GetTextAndAttachments(msg), maxMsgLength) {
form := url.Values{
"action": []string{"send_single"},
Expand All @@ -115,37 +102,35 @@ func (h *handler) SendLegacy(ctx context.Context, msg courier.MsgOut, clog *cour

req, err := http.NewRequest(http.MethodPost, sendURL, strings.NewReader(form.Encode()))
if err != nil {
return nil, err
return err
}
req.SetBasicAuth(username, password)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Accept", "application/json")

resp, respBody, err := h.RequestHTTP(req, clog)
if err != nil || resp.StatusCode/100 != 2 {
return status, nil
if err != nil || resp.StatusCode/100 == 5 {
return courier.ErrConnectionFailed
} else if resp.StatusCode/100 != 2 {
return courier.ErrResponseStatus
}

// parse our response as JSON
response := &mtResponse{}
err = json.Unmarshal(respBody, response)
if err != nil {
clog.Error(courier.ErrorResponseUnparseable("JSON"))
break
return courier.ErrResponseUnparseable
}

// we always get 00 on success
if response.ErrorCode == "00" {
status.SetStatus(courier.MsgStatusWired)
status.SetExternalID(response.Result.SessionID)
res.AddExternalID(response.Result.SessionID)
} else {
status.SetStatus(courier.MsgStatusFailed)
clog.Error(courier.ErrorResponseValueUnexpected("error_code", "00"))
break
return courier.ErrFailedWithReason(response.ErrorCode, response.ErrorDesc)
}
}

return status, nil
return nil
}

func (h *handler) RedactValues(ch courier.Channel) []string {
Expand Down
104 changes: 67 additions & 37 deletions handlers/i2sms/handler_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package i2sms

import (
"net/http/httptest"
"net/url"
"testing"

Expand Down Expand Up @@ -46,18 +45,17 @@ func BenchmarkHandler(b *testing.B) {
RunChannelBenchmarks(b, testChannels, newHandler(), testCases)
}

func setSendURL(s *httptest.Server, h courier.ChannelHandler, c courier.Channel, m courier.MsgOut) {
sendURL = s.URL
}

var defaultSendTestCases = []OutgoingTestCase{
{
Label: "Plain Send",
MsgText: "Simple Message ☺",
MsgURN: "tel:+250788383383",
MsgAttachments: []string{"image/jpeg:https://foo.bar/image.jpg"},
MockResponseBody: `{"result":{"session_id":"5b8fc97d58795484819426"}, "error_code": "00", "error_desc": "Success"}`,
MockResponseStatus: 200,
Label: "Plain Send",
MsgText: "Simple Message ☺",
MsgURN: "tel:+250788383383",
MsgAttachments: []string{"image/jpeg:https://foo.bar/image.jpg"},
MockResponses: map[string][]*httpx.MockResponse{
"https://mx2.i2sms.net/mxapi.php": {
httpx.NewMockResponse(200, nil, []byte(`{"result":{"session_id":"5b8fc97d58795484819426"}, "error_code": "00", "error_desc": "Success"}`)),
},
},
ExpectedRequests: []ExpectedRequest{
{
Form: url.Values{
Expand All @@ -68,38 +66,70 @@ var defaultSendTestCases = []OutgoingTestCase{
},
},
},
ExpectedMsgStatus: "W",
ExpectedExtIDs: []string{"5b8fc97d58795484819426"},
SendPrep: setSendURL,
ExpectedExtIDs: []string{"5b8fc97d58795484819426"},
},
{
Label: "Invalid JSON",
MsgText: "Invalid XML",
MsgURN: "tel:+250788383383",
MockResponseBody: `not json`,
MockResponseStatus: 200,
ExpectedMsgStatus: "E",
ExpectedLogErrors: []*courier.ChannelError{courier.ErrorResponseUnparseable("JSON")},
SendPrep: setSendURL,
Label: "Invalid JSON",
MsgText: "Invalid XML",
MsgURN: "tel:+250788383383",
MockResponses: map[string][]*httpx.MockResponse{
"https://mx2.i2sms.net/mxapi.php": {
httpx.NewMockResponse(200, nil, []byte(`not json`)),
},
},
ExpectedRequests: []ExpectedRequest{
{
Form: url.Values{
"action": {"send_single"},
"mobile": {"250788383383"},
"message": {"Invalid XML"},
"channel": {"hash123"},
},
},
},
ExpectedError: courier.ErrResponseUnparseable,
},
{
Label: "Error Response",
MsgText: "Error Response",
MsgURN: "tel:+250788383383",
MockResponseBody: `{"result":{}, "error_code": "10", "error_desc": "Failed"}`,
MockResponseStatus: 200,
ExpectedMsgStatus: "F",
ExpectedLogErrors: []*courier.ChannelError{courier.ErrorResponseValueUnexpected("error_code", "00")},
SendPrep: setSendURL,
Label: "Error Response",
MsgText: "Error Response",
MsgURN: "tel:+250788383383",
MockResponses: map[string][]*httpx.MockResponse{
"https://mx2.i2sms.net/mxapi.php": {
httpx.NewMockResponse(200, nil, []byte(`{"result":{}, "error_code": "10", "error_desc": "Failed"}`)),
},
},
ExpectedRequests: []ExpectedRequest{
{
Form: url.Values{
"action": {"send_single"},
"mobile": {"250788383383"},
"message": {"Error Response"},
"channel": {"hash123"},
},
},
},
ExpectedError: courier.ErrFailedWithReason("10", "Failed"),
},
{
Label: "Error Sending",
MsgText: "Error Message",
MsgURN: "tel:+250788383383",
MockResponseBody: `Bad Gateway`,
MockResponseStatus: 501,
ExpectedMsgStatus: "E",
SendPrep: setSendURL,
Label: "Error Sending",
MsgText: "Error Message",
MsgURN: "tel:+250788383383",
MockResponses: map[string][]*httpx.MockResponse{
"https://mx2.i2sms.net/mxapi.php": {
httpx.NewMockResponse(501, nil, []byte(`Bad Gateway`)),
},
},
ExpectedRequests: []ExpectedRequest{
{
Form: url.Values{
"action": {"send_single"},
"mobile": {"250788383383"},
"message": {"Error Message"},
"channel": {"hash123"},
},
},
},
ExpectedError: courier.ErrConnectionFailed,
},
}

Expand Down
40 changes: 16 additions & 24 deletions handlers/infobip/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,19 +159,10 @@ func (h *handler) receiveMessage(ctx context.Context, channel courier.Channel, w
}

func (h *handler) Send(ctx context.Context, msg courier.MsgOut, res *courier.SendResult, clog *courier.ChannelLog) error {
// TODO convert functionality from legacy method below
return nil
}

func (h *handler) SendLegacy(ctx context.Context, msg courier.MsgOut, clog *courier.ChannelLog) (courier.StatusUpdate, error) {
username := msg.Channel().StringConfigForKey(courier.ConfigUsername, "")
if username == "" {
return nil, fmt.Errorf("no username set for IB channel")
}

password := msg.Channel().StringConfigForKey(courier.ConfigPassword, "")
if password == "" {
return nil, fmt.Errorf("no password set for IB channel")
if username == "" || password == "" {
return courier.ErrChannelConfig
}

transliteration := msg.Channel().StringConfigForKey(configTransliteration, "")
Expand Down Expand Up @@ -201,38 +192,39 @@ func (h *handler) SendLegacy(ctx context.Context, msg courier.MsgOut, clog *cour
requestBody := &bytes.Buffer{}
err := json.NewEncoder(requestBody).Encode(ibMsg)
if err != nil {
return nil, err
return err
}

// build our request
req, err := http.NewRequest(http.MethodPost, sendURL, requestBody)
if err != nil {
return nil, err
return err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
req.SetBasicAuth(username, password)

status := h.Backend().NewStatusUpdate(msg.Channel(), msg.ID(), courier.MsgStatusErrored, clog)

resp, respBody, err := h.RequestHTTP(req, clog)
if err != nil || resp.StatusCode/100 != 2 {
return status, nil
if err != nil || resp.StatusCode/100 == 5 {
return courier.ErrConnectionFailed
} else if resp.StatusCode/100 != 2 {
return courier.ErrResponseStatus
}

groupID, err := jsonparser.GetInt(respBody, "messages", "[0]", "status", "groupId")
if err != nil || (groupID != 1 && groupID != 3) {
clog.Error(courier.ErrorResponseValueUnexpected("groupId", "1", "3"))
return status, nil
return courier.ErrResponseUnexpected
}

externalID, _ := jsonparser.GetString(respBody, "messages", "[0]", "messageId")
if externalID != "" {
status.SetExternalID(externalID)
externalID, err := jsonparser.GetString(respBody, "messages", "[0]", "messageId")
if err != nil {
clog.Error(courier.ErrorResponseValueMissing("messageId"))
} else {

res.AddExternalID(externalID)
}

status.SetStatus(courier.MsgStatusWired)
return status, nil
return nil
}

func (h *handler) RedactValues(ch courier.Channel) []string {
Expand Down
Loading

0 comments on commit 7a79316

Please sign in to comment.