diff --git a/go.mod b/go.mod index 184014d8d..4f315d351 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/mattn/go-sqlite3 v1.10.0 // indirect github.com/nyaruka/ezconf v0.2.1 github.com/nyaruka/gocommon v1.3.0 - github.com/nyaruka/goflow v0.102.0 + github.com/nyaruka/goflow v0.102.1 github.com/nyaruka/librato v1.0.0 github.com/nyaruka/logrus_sentry v0.8.2-0.20190129182604-c2962b80ba7d github.com/nyaruka/null v1.2.0 diff --git a/go.sum b/go.sum index 02280c601..dc6cc1e92 100644 --- a/go.sum +++ b/go.sum @@ -130,8 +130,8 @@ github.com/nyaruka/ezconf v0.2.1 h1:TDXWoqjqYya1uhou1mAJZg7rgFYL98EB0Tb3+BWtUh0= github.com/nyaruka/ezconf v0.2.1/go.mod h1:ey182kYkw2MIi4XiWe1FR/mzI33WCmTWuceDYYxgnQw= github.com/nyaruka/gocommon v1.3.0 h1:IqaPT4KQ2oVq/2Ivp/c+RVCs8v71+RzPU2VhMoRrgpU= github.com/nyaruka/gocommon v1.3.0/go.mod h1:w7lKxIkm/qLAoO9Y3aI1LV7EiYogn6+1C8MTEjxTC9M= -github.com/nyaruka/goflow v0.102.0 h1:WdcQYZ8smr+M2Xbz+3kg1wSl8pVPwz7Ba0Z2ivvehlQ= -github.com/nyaruka/goflow v0.102.0/go.mod h1:wuvXZTs6a6S1rjSRLaQGVxDfKomDJ/1XQoLXCqFekK4= +github.com/nyaruka/goflow v0.102.1 h1:7QX2jTwV7uIbaGnkkpmB+ao+E7Cmyar9g7sRQH4Bu3M= +github.com/nyaruka/goflow v0.102.1/go.mod h1:wuvXZTs6a6S1rjSRLaQGVxDfKomDJ/1XQoLXCqFekK4= github.com/nyaruka/librato v1.0.0 h1:Vznj9WCeC1yZXbBYyYp40KnbmXLbEkjKmHesV/v2SR0= github.com/nyaruka/librato v1.0.0/go.mod h1:pkRNLFhFurOz0QqBz6/DuTFhHHxAubWxs4Jx+J7yUgg= github.com/nyaruka/logrus_sentry v0.8.2-0.20190129182604-c2962b80ba7d h1:hyp9u36KIwbTCo2JAJ+TuJcJBc+UZzEig7RI/S5Dvkc= diff --git a/mailroom_test.dump b/mailroom_test.dump index cb0c74125..40f1474af 100644 Binary files a/mailroom_test.dump and b/mailroom_test.dump differ diff --git a/models/contacts.go b/models/contacts.go index 3bd00c6d9..5ce6be945 100644 --- a/models/contacts.go +++ b/models/contacts.go @@ -19,10 +19,10 @@ import ( "github.com/nyaruka/goflow/flows" "github.com/nyaruka/goflow/utils/uuids" "github.com/nyaruka/null" - "github.com/olivere/elastic" "github.com/jmoiron/sqlx" "github.com/lib/pq" + "github.com/olivere/elastic" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -52,10 +52,18 @@ const ( ContactStatusArchived = "V" ) -var contactStatusMap = map[flows.ContactStatus]ContactStatus{ - flows.ContactStatusActive: ContactStatusActive, - flows.ContactStatusBlocked: ContactStatusBlocked, - flows.ContactStatusStopped: ContactStatusStopped, +var contactToModelStatus = map[flows.ContactStatus]ContactStatus{ + flows.ContactStatusActive: ContactStatusActive, + flows.ContactStatusBlocked: ContactStatusBlocked, + flows.ContactStatusStopped: ContactStatusStopped, + flows.ContactStatusArchived: ContactStatusArchived, +} + +var contactToFlowStatus = map[ContactStatus]flows.ContactStatus{ + ContactStatusActive: flows.ContactStatusActive, + ContactStatusBlocked: flows.ContactStatusBlocked, + ContactStatusStopped: flows.ContactStatusStopped, + ContactStatusArchived: flows.ContactStatusArchived, } // LoadContact loads a contact from the passed in id @@ -93,8 +101,7 @@ func LoadContacts(ctx context.Context, db Queryer, org *OrgAssets, ids []Contact uuid: e.UUID, name: e.Name, language: e.Language, - isStopped: e.IsStopped, - isBlocked: e.IsBlocked, + status: e.Status, createdOn: e.CreatedOn, modifiedOn: e.ModifiedOn, lastSeenOn: e.LastSeenOn, @@ -354,7 +361,7 @@ func (c *Contact) FlowContact(org *OrgAssets) (*flows.Contact, error) { flows.ContactID(c.id), c.name, c.language, - c.Status(), + contactToFlowStatus[c.Status()], org.Env().Timezone(), c.createdOn, c.lastSeenOn, @@ -387,7 +394,7 @@ func (c *Contact) Unstop(ctx context.Context, db *sqlx.DB) error { if err != nil { return errors.Wrapf(err, "error unstopping contact") } - c.isStopped = false + c.status = ContactStatusActive return nil } @@ -397,8 +404,7 @@ type Contact struct { uuid flows.ContactUUID name string language envs.Language - isStopped bool - isBlocked bool + status ContactStatus fields map[string]*flows.Value groups []*Group urns []urns.URN @@ -411,8 +417,7 @@ func (c *Contact) ID() ContactID { return c.id } func (c *Contact) UUID() flows.ContactUUID { return c.uuid } func (c *Contact) Name() string { return c.name } func (c *Contact) Language() envs.Language { return c.language } -func (c *Contact) IsStopped() bool { return c.isStopped } -func (c *Contact) IsBlocked() bool { return c.isBlocked } +func (c *Contact) Status() ContactStatus { return c.status } func (c *Contact) Fields() map[string]*flows.Value { return c.fields } func (c *Contact) Groups() []*Group { return c.groups } func (c *Contact) URNs() []urns.URN { return c.urns } @@ -420,15 +425,6 @@ func (c *Contact) CreatedOn() time.Time { return c.createdOn } func (c *Contact) ModifiedOn() time.Time { return c.modifiedOn } func (c *Contact) LastSeenOn() *time.Time { return c.lastSeenOn } -func (c *Contact) Status() flows.ContactStatus { - if c.isBlocked { - return flows.ContactStatusBlocked - } else if c.isStopped { - return flows.ContactStatusStopped - } - return flows.ContactStatusActive -} - // fieldValueEnvelope is our utility struct for the value of a field type fieldValueEnvelope struct { Text types.XText `json:"text"` @@ -484,8 +480,7 @@ type contactEnvelope struct { UUID flows.ContactUUID `json:"uuid"` Name string `json:"name"` Language envs.Language `json:"language"` - IsStopped bool `json:"is_stopped"` - IsBlocked bool `json:"is_blocked"` + Status ContactStatus `json:"status"` Fields map[assets.FieldUUID]*fieldValueEnvelope `json:"fields"` GroupIDs []GroupID `json:"group_ids"` URNs []ContactURN `json:"urns"` @@ -501,8 +496,7 @@ SELECT ROW_TO_JSON(r) FROM (SELECT uuid, name, language, - is_stopped, - is_blocked, + status, is_active, created_on, modified_on, @@ -1349,7 +1343,7 @@ func UpdateContactStatus(ctx context.Context, tx Queryer, changes []*ContactStat for _, ch := range changes { blocked := ch.Status == flows.ContactStatusBlocked stopped := ch.Status == flows.ContactStatusStopped - status := contactStatusMap[ch.Status] + status := contactToModelStatus[ch.Status] if blocked || stopped { archiveTriggersForContactIDs = append(archiveTriggersForContactIDs, ch.ContactID) diff --git a/models/msgs.go b/models/msgs.go index 24ce2e249..d64b989e2 100644 --- a/models/msgs.go +++ b/models/msgs.go @@ -774,7 +774,7 @@ func CreateBroadcastMessages(ctx context.Context, db Queryer, rp *redis.Pool, oa // utility method to build up our message buildMessage := func(c *Contact, forceURN urns.URN) (*Msg, error) { - if c.IsStopped() || c.IsBlocked() { + if c.Status() != ContactStatusActive { return nil, nil } diff --git a/tasks/handler/worker.go b/tasks/handler/worker.go index 31eb026fa..4798057c1 100644 --- a/tasks/handler/worker.go +++ b/tasks/handler/worker.go @@ -218,8 +218,8 @@ func handleTimedEvent(ctx context.Context, db *sqlx.DB, rp *redis.Pool, eventTyp return errors.Wrapf(err, "error loading contact") } - // contact has been deleted or is blocked, ignore this event - if len(contacts) == 0 || contacts[0].IsBlocked() { + // contact has been deleted or is blocked/stopped/archived, ignore this event + if len(contacts) == 0 || contacts[0].Status() != models.ContactStatusActive { return nil } @@ -314,8 +314,8 @@ func HandleChannelEvent(ctx context.Context, db *sqlx.DB, rp *redis.Pool, eventT return nil, errors.Wrapf(err, "error loading contact") } - // contact has been deleted or is blocked, ignore this event - if len(contacts) == 0 || contacts[0].IsBlocked() { + // contact has been deleted or is blocked/stopped/archived, ignore this event + if len(contacts) == 0 || contacts[0].Status() != models.ContactStatusActive { return nil, nil } @@ -526,7 +526,7 @@ func handleMsgEvent(ctx context.Context, db *sqlx.DB, rp *redis.Pool, event *Msg } // if this channel is no longer active or this contact is blocked, ignore this message (mark it as handled) - if channel == nil || modelContact.IsBlocked() { + if channel == nil || modelContact.Status() == models.ContactStatusBlocked { err := models.UpdateMessage(ctx, db, event.MsgID, models.MsgStatusHandled, models.VisibilityArchived, models.TypeInbox, topupID) if err != nil { return errors.Wrapf(err, "error marking blocked or nil channel message as handled") @@ -536,7 +536,7 @@ func handleMsgEvent(ctx context.Context, db *sqlx.DB, rp *redis.Pool, event *Msg // stopped contact? they are unstopped if they send us an incoming message newContact := event.NewContact - if modelContact.IsStopped() { + if modelContact.Status() == models.ContactStatusStopped { err := modelContact.Unstop(ctx, db) if err != nil { return errors.Wrapf(err, "error unstopping contact") diff --git a/web/ivr/ivr.go b/web/ivr/ivr.go index afc03f770..ee08e5cfe 100644 --- a/web/ivr/ivr.go +++ b/web/ivr/ivr.go @@ -318,7 +318,7 @@ func handleFlow(ctx context.Context, s *web.Server, r *http.Request, rawW http.R if len(contacts) == 0 { return client.WriteErrorResponse(w, errors.Errorf("no contact width id: %d", conn.ContactID())) } - if contacts[0].IsStopped() || contacts[0].IsBlocked() { + if contacts[0].Status() != models.ContactStatusActive { return client.WriteErrorResponse(w, errors.Errorf("no contact width id: %d", conn.ContactID())) } diff --git a/web/ivr/ivr_test.go b/web/ivr/ivr_test.go index fef2b8db1..cc4cc5c11 100644 --- a/web/ivr/ivr_test.go +++ b/web/ivr/ivr_test.go @@ -344,7 +344,7 @@ func TestNexmoIVR(t *testing.T) { } else { type CallForm struct { To []struct { - Number int64 `json:"number` + Number int64 `json:"number"` } `json:"to"` } body, _ := ioutil.ReadAll(r.Body)