Skip to content

Commit

Permalink
Notifications (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
rowanseymour committed Aug 30, 2021
1 parent 36984ab commit 2e4216b
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 0 deletions.
97 changes: 97 additions & 0 deletions core/models/notifications.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package models

import (
"context"

"github.com/nyaruka/mailroom/utils/dbutil"
"github.com/pkg/errors"
)

// LogID is our type for log ids
type LogID int

type LogType string

const (
LogTypeBroadcastStarted LogType = "bcast:started"
LogTypeBroadcastCompleted LogType = "bcast:completed"
LogTypeChannelAlert LogType = "channel:alert"
LogTypeExportStarted LogType = "export:started"
LogTypeExportCompleted LogType = "export:completed"
LogTypeFlowStartStarted LogType = "start:started"
LogTypeFlowStartCompleted LogType = "start:completed"
LogTypeImportStarted LogType = "import:started"
LogTypeImportCompleted LogType = "import:completed"
LogTypeTicketOpened LogType = "ticket:opened"
LogTypeTicketNewMsgs LogType = "ticket:msgs"
LogTypeTicketAssignment LogType = "ticket:assign"
LogTypeTicketNote LogType = "ticket:note"
)

type NotifyWho string

const (
NotifyAll NotifyWho = "all"
NotifyAllExceptUser NotifyWho = "all_except_user"
NotifyAdmins NotifyWho = "admins"
NotifyAdminsExceptUser NotifyWho = "admins_except_user"
NotifyUser NotifyWho = "user"
NotifyNobody NotifyWho = "nobody"
)

type Log struct {
ID LogID `db:"id"`
OrgID OrgID `db:"org_id"`
LogType LogType `db:"log_type"`
CreatedByID UserID `db:"created_by_id"`

BroadcastID BroadcastID `db:"broadcast_id"`
FlowStartID StartID `db:"flow_start_id"`
TicketID TicketID `db:"ticket_id"`
}

type Notification struct {
ID LogID `db:"id"`
OrgID OrgID `db:"org_id"`
UserID UserID `db:"log_type"`
LogID LogID `db:"created_by_id"`
}

func LogTicketOpened(ctx context.Context, db Queryer, oa *OrgAssets, ticket *Ticket) error {
return logAndNotify(ctx, db, oa, &Log{OrgID: ticket.OrgID(), LogType: LogTypeTicketOpened, TicketID: ticket.ID()}, NotifyAllExceptUser)
}

const insertLogSQL = `
INSERT INTO notifications_log(org_id, log_type, created_on, created_by_id, broadcast_id, flow_start_id, ticket_id)
VALUES(:org_id, :log_type, NOW(), :created_by_id, :broadcast_id, :flow_start_id, :ticket_id)
RETURNING id`

const insertNotificationSQL = `
INSERT INTO notifications_notification(org_id, user_id, log_id)
VALUES(:org_id, :user_id, :log_id)`

func logAndNotify(ctx context.Context, db Queryer, oa *OrgAssets, log *Log, notifyWho NotifyWho) error {
err := dbutil.BulkQuery(ctx, db, insertLogSQL, []interface{}{log})
if err != nil {
return errors.Wrapf(err, "error inserting %s log", log.LogType)
}

userIDs, err := getUsersToNotify(oa, notifyWho, log.CreatedByID)
if err != nil {
return errors.Wrap(err, "error getting notification users")
}

var notifications []interface{}
for _, userID := range userIDs {
notifications = append(notifications, &Notification{OrgID: log.OrgID, UserID: userID, LogID: log.ID})
}

err = dbutil.BulkQuery(ctx, db, insertNotificationSQL, notifications)

return errors.Wrap(err, "error inserting notifications")
}

func getUsersToNotify(oa *OrgAssets, who NotifyWho, user UserID) ([]UserID, error) {
// TODO
return nil, nil
}
26 changes: 26 additions & 0 deletions core/models/notifications_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package models_test

import (
"testing"

"github.com/nyaruka/mailroom/core/models"
"github.com/nyaruka/mailroom/testsuite"
"github.com/nyaruka/mailroom/testsuite/testdata"
"github.com/stretchr/testify/require"
)

func TestNotifications(t *testing.T) {
ctx, _, db, _ := testsuite.Reset()

oa, err := models.GetOrgAssets(ctx, db, testdata.Org1.ID)
require.NoError(t, err)

ticket := testdata.InsertOpenTicket(db, testdata.Org1, testdata.Cathy, testdata.Internal, testdata.SupportTopic, "", "Where my pants", "", nil)
modelTicket := ticket.Load(db)

err = models.LogTicketOpened(ctx, db, oa, modelTicket)
require.NoError(t, err)

testsuite.AssertQuery(t, db, `SELECT org_id, log_type, ticket_id FROM notifications_log`).
Columns(map[string]interface{}{"org_id": int64(testdata.Org1.ID), "log_type": "ticket:opened", "ticket_id": int64(modelTicket.ID())})
}
Binary file modified mailroom_test.dump
Binary file not shown.

0 comments on commit 2e4216b

Please sign in to comment.