Skip to content

Commit

Permalink
Merge pull request rapidpro#427 from nyaruka/resend_endpoint
Browse files Browse the repository at this point in the history
Resend messages endpoint
  • Loading branch information
rowanseymour authored May 19, 2021
2 parents 0ccb380 + f24a25c commit 1171613
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 2 deletions.
1 change: 1 addition & 0 deletions cmd/mailroom/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
_ "github.com/nyaruka/mailroom/web/expression"
_ "github.com/nyaruka/mailroom/web/flow"
_ "github.com/nyaruka/mailroom/web/ivr"
_ "github.com/nyaruka/mailroom/web/msg"
_ "github.com/nyaruka/mailroom/web/org"
_ "github.com/nyaruka/mailroom/web/po"
_ "github.com/nyaruka/mailroom/web/simulation"
Expand Down
4 changes: 2 additions & 2 deletions core/models/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ type Msg struct {
MsgType MsgType `db:"msg_type"`
MsgCount int `db:"msg_count" json:"tps_cost"`
ErrorCount int `db:"error_count" json:"error_count"`
NextAttempt time.Time `db:"next_attempt" json:"next_attempt"`
NextAttempt *time.Time `db:"next_attempt" json:"next_attempt"`
ExternalID null.String `db:"external_id" json:"external_id"`
Attachments pq.StringArray `db:"attachments" json:"attachments"`
Metadata null.Map `db:"metadata" json:"metadata,omitempty"`
Expand Down Expand Up @@ -153,7 +153,7 @@ func (m *Msg) Status() MsgStatus { return m.m.Status }
func (m *Msg) Visibility() MsgVisibility { return m.m.Visibility }
func (m *Msg) MsgType() MsgType { return m.m.MsgType }
func (m *Msg) ErrorCount() int { return m.m.ErrorCount }
func (m *Msg) NextAttempt() time.Time { return m.m.NextAttempt }
func (m *Msg) NextAttempt() *time.Time { return m.m.NextAttempt }
func (m *Msg) ExternalID() null.String { return m.m.ExternalID }
func (m *Msg) Metadata() map[string]interface{} { return m.m.Metadata.Map() }
func (m *Msg) MsgCount() int { return m.m.MsgCount }
Expand Down
63 changes: 63 additions & 0 deletions web/msg/msg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package msg

import (
"context"
"net/http"

"github.com/nyaruka/goflow/flows"
"github.com/nyaruka/goflow/utils"
"github.com/nyaruka/mailroom/core/models"
"github.com/nyaruka/mailroom/core/msgio"
"github.com/nyaruka/mailroom/web"

"github.com/pkg/errors"
)

func init() {
web.RegisterJSONRoute(http.MethodPost, "/mr/msg/resend", web.RequireAuthToken(handleResend))
}

// Request to resend failed messages.
//
// {
// "org_id": 1,
// "msg_ids": [123456, 345678]
// }
//
type resendRequest struct {
OrgID models.OrgID `json:"org_id" validate:"required"`
MsgIDs []models.MsgID `json:"msg_ids" validate:"required"`
}

// handles a request to resend the given messages
func handleResend(ctx context.Context, s *web.Server, r *http.Request) (interface{}, int, error) {
request := &resendRequest{}
if err := utils.UnmarshalAndValidateWithLimit(r.Body, request, web.MaxRequestBytes); err != nil {
return errors.Wrapf(err, "request failed validation"), http.StatusBadRequest, nil
}

// grab our org
oa, err := models.GetOrgAssets(s.CTX, s.DB, request.OrgID)
if err != nil {
return nil, http.StatusInternalServerError, errors.Wrapf(err, "unable to load org assets")
}

msgs, err := models.LoadMessages(ctx, s.DB, request.OrgID, models.DirectionOut, request.MsgIDs)
if err != nil {
return nil, http.StatusInternalServerError, errors.Wrap(err, "error loading messages to resend")
}

err = models.ResendMessages(ctx, s.DB, s.RP, oa, msgs)
if err != nil {
return nil, http.StatusInternalServerError, errors.Wrap(err, "error resending messages")
}

msgio.SendMessages(ctx, s.DB, s.RP, nil, msgs)

// response is the ids of the messages that were actually resent
resentMsgIDs := make([]flows.MsgID, len(msgs))
for i, m := range msgs {
resentMsgIDs[i] = m.ID()
}
return map[string]interface{}{"msg_ids": resentMsgIDs}, http.StatusOK, nil
}
11 changes: 11 additions & 0 deletions web/msg/msg_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package msg_test

import (
"testing"

"github.com/nyaruka/mailroom/web"
)

func TestServer(t *testing.T) {
web.RunWebTests(t, "testdata/resend.json")
}
52 changes: 52 additions & 0 deletions web/msg/testdata/resend.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
[
{
"label": "illegal method",
"method": "GET",
"path": "/mr/msg/resend",
"status": 405,
"response": {
"error": "illegal method: GET"
}
},
{
"label": "invalid org_id",
"method": "POST",
"path": "/mr/msg/resend",
"body": {
"org_id": 1234,
"msg_ids": [
1234
]
},
"status": 500,
"response": {
"error": "unable to load org assets: error loading environment for org 1234: no org with id: 1234"
}
},
{
"label": "response is the ids of the messages that were actually resent",
"method": "POST",
"path": "/mr/msg/resend",
"body": {
"org_id": 1,
"msg_ids": [
10000,
10001,
10002
]
},
"status": 200,
"response": {
"msg_ids": [
10001,
10002
]
},
"db_assertions": [
{
"query": "SELECT count(*) FROM msgs_msg WHERE status = 'P'",
"count": 2
}
]
}
]

0 comments on commit 1171613

Please sign in to comment.