diff --git a/cmd/sims/channel.go b/cmd/sims/channel.go index c3d3efb..6444e74 100644 --- a/cmd/sims/channel.go +++ b/cmd/sims/channel.go @@ -1,12 +1,17 @@ package main import ( + "golang.org/x/text/language" + "github.com/tapglue/snaas/core" serr "github.com/tapglue/snaas/error" "github.com/tapglue/snaas/platform/sns" "github.com/tapglue/snaas/service/app" + "github.com/tapglue/snaas/service/device" ) +var languageDefault = language.English + type channelFunc func(*app.App, *core.Message) error func channelPush( @@ -43,7 +48,7 @@ func channelPush( return err } - err = push(d.Platform, d.EndpointARN, p.Scheme, msg.URN, msg.Message) + err = push(d.Platform, d.EndpointARN, p.Scheme, msg.URN, localiseMessage(d, msg.Messages)) if err != nil { if sns.IsDeliveryFailure(err) { return nil @@ -56,3 +61,22 @@ func channelPush( return nil } } + +func localiseMessage(d *device.Device, msgs map[string]string) string { + t, err := language.Parse(d.Language) + if err == nil { + b, _ := t.Base() + + msg, ok := msgs[b.String()] + if ok { + return msg + } + } + + defaultMsg, ok := msgs[languageDefault.String()] + if ok { + return defaultMsg + } + + return "" +} diff --git a/core/pipieline.go b/core/pipieline.go index 39600dd..994c6f9 100644 --- a/core/pipieline.go +++ b/core/pipieline.go @@ -6,8 +6,6 @@ import ( "text/template" "time" - "golang.org/x/text/language" - serr "github.com/tapglue/snaas/error" "github.com/tapglue/snaas/service/app" "github.com/tapglue/snaas/service/connection" @@ -30,7 +28,7 @@ const ( // Message is the envelope which holds the templated message produced by a // Pipeline together with the recipient and the URN to deliver with it. type Message struct { - Message string + Messages map[string]string Recipient uint64 URN string } @@ -82,29 +80,24 @@ func PipelineConnection(users user.Service) PipelineConnectionFunc { To: to, } - for _, r := range rules { - if !r.Criteria.Match(change) { + for _, currentRule := range rules { + if !currentRule.Criteria.Match(change) { continue } - for _, recipient := range r.Recipients { - rs, err := recipientsConnection()(currentApp, context, recipient.Query) + for _, recipient := range currentRule.Recipients { + cs, err := recipientsConnection()(currentApp, context, recipient.Query) if err != nil { return nil, err } - for _, r := range rs { - urn, err := compileTemplate(context, recipient.URN) - if err != nil { - return nil, err - } - - msg, err := compileTemplate(context, recipient.Templates[language.English.String()]) + for _, c := range cs { + msg, err := compileMessage(context, recipient, c) if err != nil { return nil, err } - ms = append(ms, &Message{Message: msg, Recipient: r.ID, URN: urn}) + ms = append(ms, msg) } } } @@ -113,6 +106,30 @@ func PipelineConnection(users user.Service) PipelineConnectionFunc { } } +func compileMessage( + context interface{}, + recipient rule.Recipient, + target *user.User, +) (*Message, error) { + urn, err := compileTemplate(context, recipient.URN) + if err != nil { + return nil, err + } + + msgs := map[string]string{} + + for lang, tmpl := range recipient.Templates { + msg, err := compileTemplate(context, tmpl) + if err != nil { + return nil, err + } + + msgs[lang] = msg + } + + return &Message{Messages: msgs, Recipient: target.ID, URN: urn}, nil +} + // PipelineEventFunc constructs a Pipeline that by applying the provided rules // outputs Messages. type PipelineEventFunc func( @@ -166,29 +183,24 @@ func PipelineEvent( ParentOwner: parentOwner, } - for _, r := range rules { - if !r.Criteria.Match(change) { + for _, currentRule := range rules { + if !currentRule.Criteria.Match(change) { continue } - for _, recipient := range r.Recipients { + for _, recipient := range currentRule.Recipients { rs, err := recipientsEvent()(currentApp, context, recipient.Query) if err != nil { return nil, err } for _, r := range rs { - urn, err := compileTemplate(context, recipient.URN) - if err != nil { - return nil, err - } - - msg, err := compileTemplate(context, recipient.Templates[language.English.String()]) + msg, err := compileMessage(context, recipient, r) if err != nil { return nil, err } - ms = append(ms, &Message{Message: msg, Recipient: r.ID, URN: urn}) + ms = append(ms, msg) } } } @@ -261,12 +273,12 @@ func PipelineObject( ParentOwner: parentOwner, } - for _, r := range rules { - if !r.Criteria.Match(change) { + for _, currentRule := range rules { + if !currentRule.Criteria.Match(change) { continue } - for _, recipient := range r.Recipients { + for _, recipient := range currentRule.Recipients { rs, err := recipientsObject( connections, objects, @@ -277,17 +289,12 @@ func PipelineObject( } for _, r := range rs { - urn, err := compileTemplate(context, recipient.URN) + msg, err := compileMessage(context, recipient, r) if err != nil { return nil, err } - msg, err := compileTemplate(context, recipient.Templates[language.English.String()]) - if err != nil { - return nil, err - } - - ms = append(ms, &Message{Message: msg, Recipient: r.ID, URN: urn}) + ms = append(ms, msg) } } } @@ -349,29 +356,24 @@ func PipelineReaction( Reaction: r, } - for _, r := range rules { - if !r.Criteria.Match(change) { + for _, currentRule := range rules { + if !currentRule.Criteria.Match(change) { continue } - for _, recipient := range r.Recipients { + for _, recipient := range currentRule.Recipients { rs, err := recipientsReaction()(currentApp, context, recipient.Query) if err != nil { return nil, err } for _, r := range rs { - urn, err := compileTemplate(context, recipient.URN) - if err != nil { - return nil, err - } - - msg, err := compileTemplate(context, recipient.Templates[language.English.String()]) + msg, err := compileMessage(context, recipient, r) if err != nil { return nil, err } - ms = append(ms, &Message{Message: msg, Recipient: r.ID, URN: urn}) + ms = append(ms, msg) } } } diff --git a/core/pipieline_test.go b/core/pipieline_test.go index 1fdc0a7..6d6f8c2 100644 --- a/core/pipieline_test.go +++ b/core/pipieline_test.go @@ -6,12 +6,13 @@ import ( "reflect" "testing" - "github.com/tapglue/snaas/service/reaction" + "golang.org/x/text/language" "github.com/tapglue/snaas/service/app" "github.com/tapglue/snaas/service/connection" "github.com/tapglue/snaas/service/event" "github.com/tapglue/snaas/service/object" + "github.com/tapglue/snaas/service/reaction" "github.com/tapglue/snaas/service/rule" "github.com/tapglue/snaas/service/user" ) @@ -98,7 +99,9 @@ func TestPipelineConnectionCondFrom(t *testing.T) { want := Messages{ { - Message: fmt.Sprintf("%s accepted your friend request", target.Username), + Messages: map[string]string{ + language.English.String(): fmt.Sprintf("%s accepted your friend request", target.Username), + }, Recipient: origin.ID, URN: fmt.Sprintf("tapglue/users/%d", target.ID), }, @@ -176,7 +179,9 @@ func TestPipelineConnectionCondTo(t *testing.T) { want := Messages{ { - Message: fmt.Sprintf("%s sent you a friend request", origin.Username), + Messages: map[string]string{ + language.English.String(): fmt.Sprintf("%s sent you a friend request", origin.Username), + }, Recipient: target.ID, URN: fmt.Sprintf("tapglue/users/%d", origin.ID), }, @@ -256,7 +261,9 @@ func TestPipelineReactionCondParentOwner(t *testing.T) { want := Messages{ { - Message: fmt.Sprintf("%s liked your post", liker.Username), + Messages: map[string]string{ + language.English.String(): fmt.Sprintf("%s liked your post", liker.Username), + }, Recipient: postOwner.ID, URN: fmt.Sprintf("tapglue/users/%d", liker.ID), }, @@ -268,11 +275,6 @@ func TestPipelineReactionCondParentOwner(t *testing.T) { } if !reflect.DeepEqual(have, want) { - for i, m := range have { - fmt.Printf("[%d|%s] %v\n", m.Recipient, m.URN, m.Message[i]) - fmt.Printf("[%d|%s] %v\n\n", want[i].Recipient, want[i].URN, want[i].Message) - } - t.Errorf("have %#v, want %#v", have, want) } } @@ -344,7 +346,9 @@ func TestPipelineEventCondParentOwner(t *testing.T) { want := Messages{ { - Message: fmt.Sprintf("%s liked your post", liker.Username), + Messages: map[string]string{ + language.English.String(): fmt.Sprintf("%s liked your post", liker.Username), + }, Recipient: postOwner.ID, URN: fmt.Sprintf("tapglue/users/%d", liker.ID), }, @@ -356,11 +360,6 @@ func TestPipelineEventCondParentOwner(t *testing.T) { } if !reflect.DeepEqual(have, want) { - for i, m := range have { - fmt.Printf("[%d|%s] %s\n", m.Recipient, m.URN, m.Message) - fmt.Printf("[%d|%s] %s\n\n", want[i].Recipient, want[i].URN, want[i].Message) - } - t.Errorf("have %#v, want %#v", have, want) } } @@ -452,13 +451,17 @@ func TestPipelineObjectCondFriends(t *testing.T) { want := Messages{ { Recipient: friend2.ID, - Message: fmt.Sprintf("%s just added a review", postOwner.Username), - URN: fmt.Sprintf("tapglue/posts/%d", post.ID), + Messages: map[string]string{ + language.English.String(): fmt.Sprintf("%s just added a review", postOwner.Username), + }, + URN: fmt.Sprintf("tapglue/posts/%d", post.ID), }, { Recipient: friend1.ID, - Message: fmt.Sprintf("%s just added a review", postOwner.Username), - URN: fmt.Sprintf("tapglue/posts/%d", post.ID), + Messages: map[string]string{ + language.English.String(): fmt.Sprintf("%s just added a review", postOwner.Username), + }, + URN: fmt.Sprintf("tapglue/posts/%d", post.ID), }, } @@ -556,13 +559,17 @@ func TestPipelineObjectCondObjectOwner(t *testing.T) { want := Messages{ { Recipient: commenter2.ID, - Message: fmt.Sprintf("%s also commented on %ss post", commenter3.Username, postOwner.Username), - URN: fmt.Sprintf("tapglue/posts/%d/comments/%d", post.ID, comment3.ID), + Messages: map[string]string{ + language.English.String(): fmt.Sprintf("%s also commented on %ss post", commenter3.Username, postOwner.Username), + }, + URN: fmt.Sprintf("tapglue/posts/%d/comments/%d", post.ID, comment3.ID), }, { Recipient: commenter1.ID, - Message: fmt.Sprintf("%s also commented on %ss post", commenter3.Username, postOwner.Username), - URN: fmt.Sprintf("tapglue/posts/%d/comments/%d", post.ID, comment3.ID), + Messages: map[string]string{ + language.English.String(): fmt.Sprintf("%s also commented on %ss post", commenter3.Username, postOwner.Username), + }, + URN: fmt.Sprintf("tapglue/posts/%d/comments/%d", post.ID, comment3.ID), }, } @@ -636,8 +643,10 @@ func TestPipelineObjectCondOwner(t *testing.T) { want := Messages{ { Recipient: postOwner.ID, - Message: fmt.Sprintf("%s commented on your post", commenter.Username), - URN: fmt.Sprintf("tapglue/posts/%d/comments/%d", post.ID, comment.ID), + Messages: map[string]string{ + language.English.String(): fmt.Sprintf("%s commented on your post", commenter.Username), + }, + URN: fmt.Sprintf("tapglue/posts/%d/comments/%d", post.ID, comment.ID), }, } @@ -651,11 +660,6 @@ func TestPipelineObjectCondOwner(t *testing.T) { } if !reflect.DeepEqual(have, want) { - for i, m := range have { - fmt.Printf("[%d|%s] %s\n", m.Recipient, m.URN, m.Message) - fmt.Printf("[%d|%s] %s\n\n", want[i].Recipient, want[i].URN, want[i].Message) - } - t.Errorf("have %#v, want %#v", have, want) } }