Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MM-55060 - Calls: Add PushTypeCalls for calls-specific push notifications #561

Merged
merged 7 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
github.com/mattermost/calls-recorder v0.4.2
github.com/mattermost/logr/v2 v2.0.16
github.com/mattermost/mattermost-plugin-calls/server/public v0.0.1
github.com/mattermost/mattermost/server/public v0.0.9-0.20230824163353-69c11cfe1403
github.com/mattermost/mattermost/server/public v0.0.10-0.20231109142142-8ffda2b73ea8
github.com/mattermost/rtcd v0.12.0
github.com/mattermost/squirrel v0.2.0
github.com/pion/interceptor v0.1.25
Expand Down Expand Up @@ -47,7 +47,6 @@ require (
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/uuid v1.4.0 // indirect
github.com/grafana/pyroscope-go/godeltaprof v0.1.4 // indirect
github.com/graph-gophers/graphql-go v1.5.1-0.20230110080634-edea822f558a // indirect
github.com/hashicorp/go-hclog v1.5.0 // indirect
github.com/hashicorp/go-plugin v1.4.10 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
Expand Down
13 changes: 2 additions & 11 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
Expand Down Expand Up @@ -184,7 +181,6 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
Expand Down Expand Up @@ -221,8 +217,6 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grafana/pyroscope-go/godeltaprof v0.1.4 h1:mDsJ3ngul7UfrHibGQpV66PbZ3q1T8glz/tK3bQKKEk=
github.com/grafana/pyroscope-go/godeltaprof v0.1.4/go.mod h1:1HSPtjU8vLG0jE9JrTdzjgFqdJ/VgN7fvxBNq3luJko=
github.com/graph-gophers/graphql-go v1.5.1-0.20230110080634-edea822f558a h1:i0+Se9S+2zL5CBxJouqn2Ej6UQMwH1c57ZB6DVnqck4=
github.com/graph-gophers/graphql-go v1.5.1-0.20230110080634-edea822f558a/go.mod h1:YtmJZDLbF1YYNrlNAuiO5zAStUWc3XZT07iGsVqe1Os=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
Expand Down Expand Up @@ -301,8 +295,8 @@ github.com/mattermost/ldap v3.0.4+incompatible h1:SOeNnz+JNR+foQ3yHkYqijb9MLPhXN
github.com/mattermost/ldap v3.0.4+incompatible/go.mod h1:b4reDCcGpBxJ4WX0f224KFY+OR0npin7or7EFpeIko4=
github.com/mattermost/logr/v2 v2.0.16 h1:jnePX4cPskC3WDFvUardh/xZfxNdsFXbEERJQ1kUEDE=
github.com/mattermost/logr/v2 v2.0.16/go.mod h1:1dm/YhTpozsqANXxo5Pi5zYLBsal2xY0pX+JZNbzYJY=
github.com/mattermost/mattermost/server/public v0.0.9-0.20230824163353-69c11cfe1403 h1:/rxsEaisu+Rb5mWfoIEnbFqscJeKVkspj+BWzchUAfs=
github.com/mattermost/mattermost/server/public v0.0.9-0.20230824163353-69c11cfe1403/go.mod h1:sgXQrYzs+IJy51mB8E8OBljagk2u3YwQRoYlBH5goiw=
github.com/mattermost/mattermost/server/public v0.0.10-0.20231109142142-8ffda2b73ea8 h1:tZhcvX1k526YLHeO8lQpFa8J2Ejr7sHEYdzst5xrIjA=
github.com/mattermost/mattermost/server/public v0.0.10-0.20231109142142-8ffda2b73ea8/go.mod h1:AMuKlAabVFnLvf5bXg+69EdvtLIfty4ahFossB34LM4=
github.com/mattermost/rtcd v0.12.0 h1:T/07JYExpwMmWq58QIp8KU08FWOzVmmatzLaEOIMP4A=
github.com/mattermost/rtcd v0.12.0/go.mod h1:s0J7u93n2e2YPATEWCiiJ19iQf2TTHJapXQR2POE8KA=
github.com/mattermost/squirrel v0.2.0 h1:8ZWeyf+MWQ2cL7hu9REZgLtz2IJi51qqZEovI3T3TT8=
Expand Down Expand Up @@ -353,7 +347,6 @@ github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
Expand Down Expand Up @@ -570,8 +563,6 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI=
go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
Expand Down
2 changes: 2 additions & 0 deletions server/activate.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ func (p *Plugin) OnActivate() error {
}()
}

p.loadPushProxyVersion()

if rtcdURL := cfg.getRTCDURL(); rtcdURL != "" && p.licenseChecker.RTCDAllowed() {
rtcdManager, err := p.newRTCDClientManager(rtcdURL)
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions server/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,7 @@ func (l *logger) IsLevelEnabled(_ logr.Level) bool {
func (l *logger) With(_ ...logr.Field) *mlog.Logger {
return nil
}

func (l *logger) Sugar(_ ...mlog.Field) mlog.Sugar {
return mlog.Sugar{}
}
3 changes: 3 additions & 0 deletions server/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ type Plugin struct {
// Database handle to the writer DB node
wDB *sql.DB
driverName string

// Push-proxy's version, refreshed when the plugin activates
pushProxyVersion string
}

func (p *Plugin) startSession(us *session, senderID string) {
Expand Down
17 changes: 15 additions & 2 deletions server/push_notifications.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"github.com/mattermost/mattermost/server/public/model"
)

const minPushProxyVersionWithCalls = "5.27.0"

func (p *Plugin) NotificationWillBePushed(notification *model.PushNotification, userID string) (*model.PushNotification, string) {
// We will use our own notifications if:
// 1. This is a call start post
Expand Down Expand Up @@ -38,6 +40,10 @@ func (p *Plugin) NotificationWillBePushed(notification *model.PushNotification,
}

func (p *Plugin) sendPushNotifications(channelID, createdPostID, threadID string, sender *model.User, config *model.Config) {
if err := p.canSendPushNotifications(config, p.API.GetLicense()); err != nil {
return
}

channel, appErr := p.API.GetChannel(channelID)
if appErr != nil {
p.LogError("failed to get channel", "error", appErr.Error())
Expand All @@ -54,14 +60,19 @@ func (p *Plugin) sendPushNotifications(channelID, createdPostID, threadID string
return
}

pushType := model.PushTypeMessage
if err := checkMinVersion(minPushProxyVersionWithCalls, p.pushProxyVersion); err == nil {
pushType = model.PushTypeCalls
}

for _, member := range members {
if member.Id == sender.Id {
continue
}

msg := &model.PushNotification{
Version: model.PushMessageV2,
Type: model.PushTypeMessage,
Type: pushType,
TeamId: channel.TeamId,
ChannelId: channelID,
PostId: createdPostID,
Expand All @@ -71,7 +82,9 @@ func (p *Plugin) sendPushNotifications(channelID, createdPostID, threadID string
Message: buildGenericPushNotificationMessage(),
}

// This is ugly.
// This is ugly because it's a little complicated. We need to special case IdLoaded notifications (don't expose
// any details of the push notification on the wire). Otherwise, we can send more information, unless the server
// has set GenericNoChannel.
if *config.EmailSettings.PushNotificationContents == model.IdLoadedNotification {
msg.IsIdLoaded = p.checkLicenseForIDLoaded()
} else {
Expand Down
80 changes: 80 additions & 0 deletions server/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ package main
import (
"bytes"
"compress/zlib"
"encoding/json"
"errors"
"fmt"
"github.com/mattermost/mattermost/server/public/model"
"io"
Expand Down Expand Up @@ -63,6 +65,76 @@ func (p *Plugin) getNotificationNameFormat(userID string) string {
return *config.TeamSettings.TeammateNameDisplay
}

func (p *Plugin) loadPushProxyVersion() {
config := p.API.GetConfig()
if err := p.canSendPushNotifications(config, p.API.GetLicense()); err != nil {
p.LogWarn(err.Error())
return
}

client := NewClient()
var err error
p.pushProxyVersion, err = getPushProxyVersion(client, config)
if err != nil {
p.LogError(err.Error())
}
}

// getPushProxyVersion will return the version if the push proxy is reachable and version >= 5.27.0
// which is when the "/version" endpoint was added. Otherwise it will return "" for lower versions and for
// failed attempts to get the version (which could mean only that the push proxy was unavailable temporarily)
func getPushProxyVersion(client *http.Client, config *model.Config) (string, error) {
if config == nil ||
config.EmailSettings.PushNotificationServer == nil ||
*config.EmailSettings.PushNotificationServer == "" {
return "", nil
}
serverURL := strings.TrimRight(*config.EmailSettings.PushNotificationServer, "/") + "/version"
req, err := http.NewRequest("GET", serverURL, nil)
if err != nil {
return "", fmt.Errorf("failed to build request, err: %w", err)
}

resp, err := client.Do(req)
if err != nil {
return "", fmt.Errorf("http request failed, err: %w", err)
}
defer resp.Body.Close()

if resp.StatusCode == http.StatusOK {
var respData = struct {
Version string
Hash string
}{}
if err := json.NewDecoder(resp.Body).Decode(&respData); err != nil {
return "", fmt.Errorf("failed to decode http response, err: %w", err)
}

return respData.Version, nil
}

// Must not be newer version of push proxy
return "", nil
}

func (p *Plugin) canSendPushNotifications(config *model.Config, license *model.License) error {
if config == nil ||
config.EmailSettings.SendPushNotifications == nil ||
!*config.EmailSettings.SendPushNotifications {
return nil
}

if config.EmailSettings.PushNotificationServer == nil {
return nil
}
pushServer := *config.EmailSettings.PushNotificationServer
if pushServer == model.MHPNS && (license == nil || !*license.Features.MHPNS) {
return errors.New("push notifications have been disabled. Update your license or go to System Console > Environment > Push Notification Server to use a different server")
}

return nil
}

func getChannelNameForNotification(channel *model.Channel, sender *model.User, users []*model.User, nameFormat, excludeID string) string {
switch channel.Type {
case model.ChannelTypeDirect:
Expand Down Expand Up @@ -176,3 +248,11 @@ func mapKeys[K comparable, V any](m map[K]V) []K {
}
return keys
}

// NewClient creates a SimpleClient intended for one-off requests, like getPushProxyVersion.
// If we end up needing something more long term, we should consider storing it.
func NewClient() *http.Client {
return &http.Client{
Timeout: 10 * time.Second,
}
}
Loading