Skip to content

Commit

Permalink
Add handle for zendesk csat
Browse files Browse the repository at this point in the history
  • Loading branch information
Robi9 committed Jan 3, 2025
1 parent 6ba1d6f commit 61d215e
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 0 deletions.
32 changes: 32 additions & 0 deletions services/tickets/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,38 @@ func SendReply(ctx context.Context, rt *runtime.Runtime, ticket *models.Ticket,
return nil, nil
}

func SendReplyCSAT(ctx context.Context, rt *runtime.Runtime, ticket *models.Ticket, channelUUID string, text string, url string) (*models.Msg, error) {
// look up our assets
oa, err := models.GetOrgAssets(ctx, rt, ticket.OrgID())
if err != nil {
return nil, errors.Wrapf(err, "error looking up org #%d", ticket.OrgID())
}

channel := oa.ChannelByUUID(assets.ChannelUUID(channelUUID))

msg := models.WppBroadcastMessage{
Text: text,
CTAMessage: flows.CTAMessage{
DisplayText_: "Pesquisa de Satisfação",
URL_: url,
},
}

// we'll use a broadcast to send this message
bcast := models.NewWppBroadcast(oa.OrgID(), models.NilBroadcastID, msg, nil, []models.ContactID{ticket.ContactID()}, nil, channel.ID())
batch := bcast.CreateBatch([]models.ContactID{ticket.ContactID()})
msgs, err := models.CreateWppBroadcastMessages(ctx, rt, oa, batch)
if err != nil {
return nil, errors.Wrapf(err, "error creating message batch")
}

msgio.SendMessages(ctx, rt, rt.DB, nil, msgs)
if len(msgs) > 0 {
return msgs[0], nil
}
return nil, nil
}

var retries = httpx.NewFixedRetries(time.Second*5, time.Second*10)

// File represents a file sent to us from a ticketing service
Expand Down
19 changes: 19 additions & 0 deletions services/tickets/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,22 @@ func TestCloseTicket(t *testing.T) {
testsuite.AssertContactTasks(t, 1, testdata.Cathy.ID,
[]string{`{"type":"ticket_closed","org_id":1,"task":{"id":1,"org_id":1,"contact_id":10000,"ticket_id":1,"event_type":"C","created_on":"2021-06-08T16:40:32Z"},"queued_on":"2021-06-08T16:40:35Z"}`})
}

func TestSendReplyCSAT(t *testing.T) {
ctx, rt, db, _ := testsuite.Get()

defer testsuite.Reset(testsuite.ResetAll)

defer uuids.SetGenerator(uuids.DefaultGenerator)
uuids.SetGenerator(uuids.NewSeededGenerator(12345))

// create a ticket
ticket := testdata.InsertOpenTicket(db, testdata.Org1, testdata.Cathy, testdata.Mailgun, testdata.DefaultTopic, "Have you seen my cookies?", "", nil)
modelTicket := ticket.Load(db)

msg, err := tickets.SendReplyCSAT(ctx, rt, modelTicket, "74729f45-7f29-4868-9dc4-90e491e3c7d8", "Satisfaction Survey", "https://csat.zen/e88512d8-acea-46d0-80a0-c7ae19d12cec")
require.NoError(t, err)

assert.Equal(t, "Satisfaction Survey", msg.Text())
assert.Equal(t, testdata.Cathy.ID, msg.ContactID())
}
34 changes: 34 additions & 0 deletions services/tickets/zendesk/testdata/csat.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[
{
"label": "error response if missing required field",
"method": "POST",
"path": "/mr/tickets/types/zendesk/csat",
"body": {},
"status": 400,
"response": {
"error": "error looking up ticket "
}
},
{
"label": "create csat message and send to contact if everything correct",
"method": "POST",
"path": "/mr/tickets/types/zendesk/csat",
"body": {
"message": "Satisfaction Survey",
"thread_id": "$cathy_ticket_uuid$",
"channel_uuid": "74729f45-7f29-4868-9dc4-90e491e3c7d8",
"csat_url": "https://csat.zen/e88512d8-acea-46d0-80a0-c7ae19d12cec"
},
"status": 200,
"response": {
"external_id": "1",
"allow_channelback": true
},
"db_assertions": [
{
"query": "select count(*) from msgs_msg where direction = 'O' and text = 'We can help'",
"count": 1
}
]
}
]
29 changes: 29 additions & 0 deletions services/tickets/zendesk/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func init() {
web.RegisterJSONRoute(http.MethodPost, base+"/channelback", handleChannelback)
web.RegisterJSONRoute(http.MethodPost, base+"/event_callback", web.WithHTTPLogs(handleEventCallback))
web.RegisterJSONRoute(http.MethodPost, base+`/webhook/{ticketer:[a-f0-9\-]+}`, web.WithHTTPLogs(handleTicketerWebhook))
web.RegisterJSONRoute(http.MethodPost, base+`/csat`, web.WithHTTPLogs(handleCSAT))
}

type integrationMetadata struct {
Expand All @@ -43,6 +44,13 @@ type channelbackRequest struct {
Metadata string `form:"metadata" validate:"required"`
}

type CSATRequest struct {
Message string `json:"message"`
URL string `json:"csat_url"`
ThreadID string `json:"thread_id"`
ChannelUUID string `json:"channel_uuid"`
}

type channelbackResponse struct {
ExternalID string `json:"external_id"`
AllowChannelback bool `json:"allow_channelback"`
Expand Down Expand Up @@ -301,3 +309,24 @@ func handleTicketerWebhook(ctx context.Context, rt *runtime.Runtime, r *http.Req

return map[string]string{"status": "handled"}, http.StatusOK, nil
}

func handleCSAT(ctx context.Context, rt *runtime.Runtime, r *http.Request, l *models.HTTPLogger) (interface{}, int, error) {
request := &CSATRequest{}
if err := utils.UnmarshalAndValidateWithLimit(r.Body, request, web.MaxRequestBytes); err != nil {
return err, http.StatusBadRequest, nil
}

// lookup the ticket and ticketer
ticket, _, _, err := tickets.FromTicketUUID(ctx, rt, flows.TicketUUID(request.ThreadID), typeZendesk)
if err != nil {
fmt.Println(err)
return err, http.StatusBadRequest, nil
}

msg, err := tickets.SendReplyCSAT(ctx, rt, ticket, request.ChannelUUID, request.Message, request.URL)
if err != nil {
return err, http.StatusBadRequest, nil
}

return &channelbackResponse{ExternalID: fmt.Sprintf("%d", msg.ID()), AllowChannelback: true}, http.StatusOK, nil
}
12 changes: 12 additions & 0 deletions services/tickets/zendesk/web_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,15 @@ func TestWebhook(t *testing.T) {

web.RunWebTests(t, ctx, rt, "testdata/webhook.json", map[string]string{"cathy_ticket_uuid": string(ticket.UUID)})
}

func TestCSAT(t *testing.T) {
ctx, rt, db, _ := testsuite.Get()

defer testsuite.Reset(testsuite.ResetData)

// create a zendesk ticket for Cathy
ticket := testdata.InsertOpenTicket(db, testdata.Org1, testdata.Cathy, testdata.Zendesk, testdata.DefaultTopic, "Have you seen my cookies?", "1234", nil)

web.RunWebTests(t, ctx, rt, "testdata/csat.json", map[string]string{"cathy_ticket_uuid": string(ticket.UUID)})

}

0 comments on commit 61d215e

Please sign in to comment.