diff --git a/core/goflow/engine.go b/core/goflow/engine.go index 816b83dba..1979e5ce8 100644 --- a/core/goflow/engine.go +++ b/core/goflow/engine.go @@ -108,8 +108,8 @@ type simulatorTicketService struct { ticketer *flows.Ticketer } -func (s *simulatorTicketService) Open(session flows.Session, subject, body string, logHTTP flows.HTTPLogCallback) (*flows.Ticket, error) { - return flows.OpenTicket(s.ticketer, subject, body), nil +func (s *simulatorTicketService) Open(session flows.Session, topic *flows.Topic, subject, body string, assignee *flows.User, logHTTP flows.HTTPLogCallback) (*flows.Ticket, error) { + return flows.OpenTicket(s.ticketer, topic, subject, body, assignee), nil } func simulatorAirtimeServiceFactory(session flows.Session) (flows.AirtimeService, error) { diff --git a/core/goflow/engine_test.go b/core/goflow/engine_test.go index aa33562e3..be94e4446 100644 --- a/core/goflow/engine_test.go +++ b/core/goflow/engine_test.go @@ -68,7 +68,7 @@ func TestSimulatorTicket(t *testing.T) { svc, err := goflow.Simulator(rt.Config).Services().Ticket(nil, flows.NewTicketer(ticketer)) assert.NoError(t, err) - ticket, err := svc.Open(nil, "New ticket", "Where are my cookies?", nil) + ticket, err := svc.Open(nil, nil, "New ticket", "Where are my cookies?", nil, nil) assert.NoError(t, err) assert.Equal(t, testdata.Mailgun.UUID, ticket.Ticketer().UUID()) assert.Equal(t, "New ticket", ticket.Subject()) diff --git a/core/handlers/ticket_opened_test.go b/core/handlers/ticket_opened_test.go index 54585e745..9c4a6b726 100644 --- a/core/handlers/ticket_opened_test.go +++ b/core/handlers/ticket_opened_test.go @@ -53,10 +53,26 @@ func TestTicketOpened(t *testing.T) { { Actions: handlers.ContactActionMap{ testdata.Cathy: []flows.Action{ - actions.NewOpenTicket(handlers.NewActionUUID(), assets.NewTicketerReference(testdata.Mailgun.UUID, "Mailgun (IT Support)"), "Need help", "Where are my cookies?", "Email Ticket"), + actions.NewOpenTicket( + handlers.NewActionUUID(), + assets.NewTicketerReference(testdata.Mailgun.UUID, "Mailgun (IT Support)"), + nil, + "Need help", + "Where are my cookies?", + assets.NewUserReference(testdata.Admin.Email, "Admin"), + "Email Ticket", + ), }, testdata.Bob: []flows.Action{ - actions.NewOpenTicket(handlers.NewActionUUID(), assets.NewTicketerReference(testdata.Zendesk.UUID, "Zendesk (Nyaruka)"), "Interesting", "I've found some cookies", "Zen Ticket"), + actions.NewOpenTicket( + handlers.NewActionUUID(), + assets.NewTicketerReference(testdata.Zendesk.UUID, "Zendesk (Nyaruka)"), + nil, + "Interesting", + "I've found some cookies", + nil, + "Zen Ticket", + ), }, }, SQLAssertions: []handlers.SQLAssertion{ @@ -94,6 +110,11 @@ func TestTicketOpened(t *testing.T) { SQL: "select count(*) from tickets_ticketevent where event_type = 'O'", Count: 2, }, + { // one of our tickets is assigned to admin + SQL: "select count(*) from tickets_ticket where assignee_id = $1", + Args: []interface{}{testdata.Admin.ID}, + Count: 1, + }, }, }, } diff --git a/core/models/assets.go b/core/models/assets.go index b5b4527b1..0e0d0f302 100644 --- a/core/models/assets.go +++ b/core/models/assets.go @@ -367,7 +367,8 @@ const ( RefreshLabels = Refresh(1 << 12) RefreshFlows = Refresh(1 << 13) RefreshTicketers = Refresh(1 << 14) - RefreshUsers = Refresh(1 << 15) + RefreshTopics = Refresh(1 << 15) + RefreshUsers = Refresh(1 << 16) ) // GetOrgAssets creates or gets org assets for the passed in org @@ -629,6 +630,10 @@ func (a *OrgAssets) TicketerByUUID(uuid assets.TicketerUUID) *Ticketer { return a.ticketersByUUID[uuid] } +func (a *OrgAssets) Topics() ([]assets.Topic, error) { + return nil, nil // TODO +} + func (a *OrgAssets) Users() ([]assets.User, error) { return a.users, nil } diff --git a/core/models/tickets.go b/core/models/tickets.go index 4f1f0267f..cdd922cb9 100644 --- a/core/models/tickets.go +++ b/core/models/tickets.go @@ -133,6 +133,7 @@ func (t *Ticket) FlowTicket(oa *OrgAssets) (*flows.Ticket, error) { return flows.NewTicket( t.UUID(), oa.SessionAssets().Ticketers().Get(modelTicketer.UUID()), + nil, // TODO t.Subject(), t.Body(), string(t.ExternalID()), diff --git a/go.mod b/go.mod index f808a4c72..f38092220 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.13.0 - github.com/nyaruka/goflow v0.131.1 + github.com/nyaruka/goflow v0.132.0 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 783d2cdab..b27283386 100644 --- a/go.sum +++ b/go.sum @@ -134,8 +134,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.13.0 h1:WPL//ekajA30KinYRr6IrdP1igNZpcUAfABleHCuxPQ= github.com/nyaruka/gocommon v1.13.0/go.mod h1:Jn7UIE8zwIr4JaviDf4PZrrQlN8r6QGVhOuaF/JoKus= -github.com/nyaruka/goflow v0.131.1 h1:jgwxO+A/FK1YtL7cDndiLpMIB15/IkI+hXnmuAIu41I= -github.com/nyaruka/goflow v0.131.1/go.mod h1:Xp1p21TyYiMM/fVQNWQRok/fZ1ZeNoeQGUd//LvYxq4= +github.com/nyaruka/goflow v0.132.0 h1:8dtnwWFJgGElSJl7r6XPtiWq8Vy6j9Lq4qMAm54gjBk= +github.com/nyaruka/goflow v0.132.0/go.mod h1:Xp1p21TyYiMM/fVQNWQRok/fZ1ZeNoeQGUd//LvYxq4= 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/services/tickets/intern/service.go b/services/tickets/intern/service.go index 42c103b6c..85d01f0a4 100644 --- a/services/tickets/intern/service.go +++ b/services/tickets/intern/service.go @@ -28,8 +28,8 @@ func NewService(rtCfg *config.Config, httpClient *http.Client, httpRetries *http } // Open just returns a new ticket - no external service to notify -func (s *service) Open(session flows.Session, subject, body string, logHTTP flows.HTTPLogCallback) (*flows.Ticket, error) { - return flows.OpenTicket(s.ticketer, subject, body), nil +func (s *service) Open(session flows.Session, topic *flows.Topic, subject, body string, assignee *flows.User, logHTTP flows.HTTPLogCallback) (*flows.Ticket, error) { + return flows.OpenTicket(s.ticketer, topic, subject, body, assignee), nil } // Forward is a noop diff --git a/services/tickets/intern/service_test.go b/services/tickets/intern/service_test.go index a7836ac0d..9fd47152c 100644 --- a/services/tickets/intern/service_test.go +++ b/services/tickets/intern/service_test.go @@ -42,7 +42,7 @@ func TestOpenAndForward(t *testing.T) { logger := &flows.HTTPLogger{} - ticket, err := svc.Open(session, "Need help", "Where are my cookies?", logger.Log) + ticket, err := svc.Open(session, nil, "Need help", "Where are my cookies?", nil, logger.Log) assert.NoError(t, err) assert.Equal(t, flows.TicketUUID("e7187099-7d38-4f60-955c-325957214c42"), ticket.UUID()) assert.Equal(t, "Need help", ticket.Subject()) diff --git a/services/tickets/mailgun/service.go b/services/tickets/mailgun/service.go index 3dd435da8..f32ce4a28 100644 --- a/services/tickets/mailgun/service.go +++ b/services/tickets/mailgun/service.go @@ -107,10 +107,14 @@ func NewService(rtCfg *config.Config, httpClient *http.Client, httpRetries *http } // Open opens a ticket which for mailgun means just sending an initial email -func (s *service) Open(session flows.Session, subject, body string, logHTTP flows.HTTPLogCallback) (*flows.Ticket, error) { - ticket := flows.OpenTicket(s.ticketer, subject, body) +func (s *service) Open(session flows.Session, topic *flows.Topic, subject, body string, assignee *flows.User, logHTTP flows.HTTPLogCallback) (*flows.Ticket, error) { + ticket := flows.OpenTicket(s.ticketer, topic, subject, body, assignee) contactDisplay := tickets.GetContactDisplay(session.Environment(), session.Contact()) + if topic != nil { + subject = topic.Name() + } + from := s.ticketAddress(contactDisplay, ticket.UUID()) context := s.templateContext(subject, body, "", string(session.Contact().UUID()), contactDisplay) fullBody := evaluateTemplate(openBodyTemplate, context) diff --git a/services/tickets/mailgun/service_test.go b/services/tickets/mailgun/service_test.go index 26636fdc2..83f2a983c 100644 --- a/services/tickets/mailgun/service_test.go +++ b/services/tickets/mailgun/service_test.go @@ -80,12 +80,12 @@ func TestOpenAndForward(t *testing.T) { logger := &flows.HTTPLogger{} - _, err = svc.Open(session, "Need help", "Where are my cookies?", logger.Log) + _, err = svc.Open(session, nil, "Need help", "Where are my cookies?", nil, logger.Log) assert.EqualError(t, err, "error calling mailgun API: unable to connect to server") logger = &flows.HTTPLogger{} - ticket, err := svc.Open(session, "Need help", "Where are my cookies?", logger.Log) + ticket, err := svc.Open(session, nil, "Need help", "Where are my cookies?", nil, logger.Log) assert.NoError(t, err) assert.Equal(t, flows.TicketUUID("9688d21d-95aa-4bed-afc7-f31b35731a3d"), ticket.UUID()) assert.Equal(t, "Need help", ticket.Subject()) diff --git a/services/tickets/rocketchat/service.go b/services/tickets/rocketchat/service.go index fa842eb86..a8f096c17 100644 --- a/services/tickets/rocketchat/service.go +++ b/services/tickets/rocketchat/service.go @@ -51,8 +51,8 @@ func NewService(rtCfg *config.Config, httpClient *http.Client, httpRetries *http type VisitorToken models.ContactID // Open opens a ticket which for RocketChat means open a room associated to a visitor user -func (s *service) Open(session flows.Session, subject, body string, logHTTP flows.HTTPLogCallback) (*flows.Ticket, error) { - ticket := flows.OpenTicket(s.ticketer, subject, body) +func (s *service) Open(session flows.Session, topic *flows.Topic, subject, body string, assignee *flows.User, logHTTP flows.HTTPLogCallback) (*flows.Ticket, error) { + ticket := flows.OpenTicket(s.ticketer, topic, subject, body, assignee) contact := session.Contact() email := "" phone := "" diff --git a/services/tickets/rocketchat/service_test.go b/services/tickets/rocketchat/service_test.go index 2e6a191bc..f95dec3db 100644 --- a/services/tickets/rocketchat/service_test.go +++ b/services/tickets/rocketchat/service_test.go @@ -71,11 +71,11 @@ func TestOpenAndForward(t *testing.T) { assert.NoError(t, err) logger := &flows.HTTPLogger{} - _, err = svc.Open(session, "Need help", "Where are my cookies?", logger.Log) + _, err = svc.Open(session, nil, "Need help", "Where are my cookies?", nil, logger.Log) assert.EqualError(t, err, "error calling RocketChat: unable to connect to server") logger = &flows.HTTPLogger{} - ticket, err := svc.Open(session, "Need help", "Where are my cookies?", logger.Log) + ticket, err := svc.Open(session, nil, "Need help", "Where are my cookies?", nil, logger.Log) assert.NoError(t, err) assert.Equal(t, flows.TicketUUID("59d74b86-3e2f-4a93-aece-b05d2fdcde0c"), ticket.UUID()) assert.Equal(t, "Need help", ticket.Subject()) diff --git a/services/tickets/zendesk/service.go b/services/tickets/zendesk/service.go index 51af565f9..2af3126bb 100644 --- a/services/tickets/zendesk/service.go +++ b/services/tickets/zendesk/service.go @@ -75,8 +75,8 @@ func NewService(rtCfg *config.Config, httpClient *http.Client, httpRetries *http } // Open opens a ticket which for mailgun means just sending an initial email -func (s *service) Open(session flows.Session, subject, body string, logHTTP flows.HTTPLogCallback) (*flows.Ticket, error) { - ticket := flows.OpenTicket(s.ticketer, subject, body) +func (s *service) Open(session flows.Session, topic *flows.Topic, subject, body string, assignee *flows.User, logHTTP flows.HTTPLogCallback) (*flows.Ticket, error) { + ticket := flows.OpenTicket(s.ticketer, topic, subject, body, assignee) contactDisplay := session.Contact().Format(session.Environment()) msg := &ExternalResource{ diff --git a/services/tickets/zendesk/service_test.go b/services/tickets/zendesk/service_test.go index 5f423abf1..7c1693bc1 100644 --- a/services/tickets/zendesk/service_test.go +++ b/services/tickets/zendesk/service_test.go @@ -86,12 +86,12 @@ func TestOpenAndForward(t *testing.T) { logger := &flows.HTTPLogger{} // try with connection failure - _, err = svc.Open(session, "Need help", "Where are my cookies?", logger.Log) + _, err = svc.Open(session, nil, "Need help", "Where are my cookies?", nil, logger.Log) assert.EqualError(t, err, "error pushing message to zendesk: unable to connect to server") logger = &flows.HTTPLogger{} - ticket, err := svc.Open(session, "Need help", "Where are my cookies?", logger.Log) + ticket, err := svc.Open(session, nil, "Need help", "Where are my cookies?", nil, logger.Log) assert.NoError(t, err) assert.Equal(t, flows.TicketUUID("59d74b86-3e2f-4a93-aece-b05d2fdcde0c"), ticket.UUID()) assert.Equal(t, "Need help", ticket.Subject())