telemetry reload + migration to server/v6 (#253)
This commit is contained in:
parent
c5428925e3
commit
0b79e3315b
27
Makefile
27
Makefile
|
@ -6,6 +6,8 @@ GOPATH ?= $(shell go env GOPATH)
|
|||
GO_TEST_FLAGS ?= -race
|
||||
GO_BUILD_FLAGS ?=
|
||||
MM_UTILITIES_DIR ?= ../mattermost-utilities
|
||||
DEFAULT_GOOS := $(shell go env GOOS)
|
||||
DEFAULT_GOARCH := $(shell go env GOARCH)
|
||||
|
||||
export GO111MODULE=on
|
||||
|
||||
|
@ -22,6 +24,13 @@ ifneq ($(wildcard build/custom.mk),)
|
|||
include build/custom.mk
|
||||
endif
|
||||
|
||||
ifneq ($(MM_DEBUG),)
|
||||
GO_BUILD_GCFLAGS = -gcflags "all=-N -l"
|
||||
else
|
||||
GO_BUILD_GCFLAGS =
|
||||
endif
|
||||
|
||||
|
||||
## Checks the code style, tests, builds and bundles the plugin.
|
||||
all: check-style test dist
|
||||
|
||||
|
@ -50,14 +59,24 @@ golangci-lint:
|
|||
@echo Running golangci-lint
|
||||
golangci-lint run ./...
|
||||
|
||||
## Builds the server, if it exists, including support for multiple architectures.
|
||||
## Builds the server, if it exists, for all supported architectures, unless MM_SERVICESETTINGS_ENABLEDEVELOPER is set
|
||||
.PHONY: server
|
||||
server:
|
||||
ifneq ($(HAS_SERVER),)
|
||||
ifneq ($(MM_DEBUG),)
|
||||
$(info DEBUG mode is on; to disable, unset MM_DEBUG)
|
||||
endif
|
||||
mkdir -p server/dist;
|
||||
cd server && env GOOS=linux GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -o dist/plugin-linux-amd64;
|
||||
cd server && env GOOS=darwin GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -o dist/plugin-darwin-amd64;
|
||||
cd server && env GOOS=windows GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -o dist/plugin-windows-amd64.exe;
|
||||
ifneq ($(MM_SERVICESETTINGS_ENABLEDEVELOPER),)
|
||||
@echo Building plugin only for $(DEFAULT_GOOS)-$(DEFAULT_GOARCH) because MM_SERVICESETTINGS_ENABLEDEVELOPER is enabled
|
||||
cd server && env CGO_ENABLED=0 $(GO) build $(GO_BUILD_FLAGS) $(GO_BUILD_GCFLAGS) -trimpath -o dist/plugin-$(DEFAULT_GOOS)-$(DEFAULT_GOARCH);
|
||||
else
|
||||
cd server && env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) $(GO_BUILD_GCFLAGS) -trimpath -o dist/plugin-linux-amd64;
|
||||
cd server && env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 $(GO) build $(GO_BUILD_FLAGS) $(GO_BUILD_GCFLAGS) -trimpath -o dist/plugin-linux-arm64;
|
||||
cd server && env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) $(GO_BUILD_GCFLAGS) -trimpath -o dist/plugin-darwin-amd64;
|
||||
cd server && env CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 $(GO) build $(GO_BUILD_FLAGS) $(GO_BUILD_GCFLAGS) -trimpath -o dist/plugin-darwin-arm64;
|
||||
cd server && env CGO_ENABLED=0 GOOS=windows GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) $(GO_BUILD_GCFLAGS) -trimpath -o dist/plugin-windows-amd64.exe;
|
||||
endif
|
||||
endif
|
||||
|
||||
## Ensures NPM dependencies are installed without having to run this all the time.
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
# If there's no MM_RUDDER_PLUGINS_PROD, add DEV data
|
||||
RUDDER_WRITE_KEY = 1d5bMvdrfWClLxgK1FvV3s4U1tg
|
||||
ifdef MM_RUDDER_PLUGINS_PROD
|
||||
RUDDER_WRITE_KEY = $(MM_RUDDER_PLUGINS_PROD)
|
||||
RUDDER_WRITE_KEY = $(MM_RUDDER_PLUGINS_PROD)
|
||||
endif
|
||||
LDFLAGS += -X "github.com/mattermost/mattermost-plugin-mscalendar/server/utils/telemetry.rudderWriteKey=$(RUDDER_WRITE_KEY)"
|
||||
LDFLAGS += -X "github.com/mattermost/mattermost-plugin-mscalendar/server/telemetry.rudderWriteKey=$(RUDDER_WRITE_KEY)"
|
||||
|
||||
# Build info
|
||||
BUILD_DATE = $(shell date -u)
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mholt/archiver/v3"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
@ -52,9 +52,9 @@ func deploy() error {
|
|||
if adminUsername != "" && adminPassword != "" {
|
||||
client := model.NewAPIv4Client(siteURL)
|
||||
log.Printf("Authenticating as %s against %s.", adminUsername, siteURL)
|
||||
_, resp := client.Login(adminUsername, adminPassword)
|
||||
if resp.Error != nil {
|
||||
return errors.Wrapf(resp.Error, "failed to login as %s", adminUsername)
|
||||
_, _, err := client.Login(adminUsername, adminPassword)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to login as %s", adminUsername)
|
||||
}
|
||||
|
||||
return uploadPlugin(client, pluginID, bundlePath)
|
||||
|
@ -83,15 +83,15 @@ func uploadPlugin(client *model.Client4, pluginID, bundlePath string) error {
|
|||
defer pluginBundle.Close()
|
||||
|
||||
log.Print("Uploading plugin via API.")
|
||||
_, resp := client.UploadPluginForced(pluginBundle)
|
||||
if resp.Error != nil {
|
||||
return errors.Wrap(resp.Error, "failed to upload plugin bundle")
|
||||
_, _, err = client.UploadPluginForced(pluginBundle)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to upload plugin bundle")
|
||||
}
|
||||
|
||||
log.Print("Enabling plugin.")
|
||||
_, resp = client.EnablePlugin(pluginID)
|
||||
if resp.Error != nil {
|
||||
return errors.Wrap(resp.Error, "Failed to enable plugin")
|
||||
_, err = client.EnablePlugin(pluginID)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to enable plugin")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -3,10 +3,9 @@ package main
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
@ -103,7 +102,7 @@ func dumpPluginVersion(manifest *model.Manifest) {
|
|||
// applyManifest propagates the plugin_id into the server and webapp folders, as necessary
|
||||
func applyManifest(manifest *model.Manifest) error {
|
||||
if manifest.HasServer() {
|
||||
if err := ioutil.WriteFile(
|
||||
if err := os.WriteFile(
|
||||
"server/manifest.go",
|
||||
[]byte(fmt.Sprintf(pluginIDGoFileTemplate, manifest.Id, manifest.Version)),
|
||||
0600,
|
||||
|
@ -113,7 +112,7 @@ func applyManifest(manifest *model.Manifest) error {
|
|||
}
|
||||
|
||||
if manifest.HasWebapp() {
|
||||
if err := ioutil.WriteFile(
|
||||
if err := os.WriteFile(
|
||||
"webapp/src/manifest.js",
|
||||
[]byte(fmt.Sprintf(pluginIDJSFileTemplate, manifest.Id, manifest.Version)),
|
||||
0600,
|
||||
|
|
88
go.mod
88
go.mod
|
@ -1,20 +1,90 @@
|
|||
module github.com/mattermost/mattermost-plugin-mscalendar
|
||||
|
||||
go 1.13
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/golang/mock v1.4.4
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/jarcoal/httpmock v1.0.4
|
||||
github.com/mattermost/mattermost-plugin-api v0.0.16
|
||||
github.com/mattermost/mattermost-server/v5 v5.3.2-0.20210621071817-df224571d8a1
|
||||
github.com/mholt/archiver/v3 v3.5.0
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/mattermost/mattermost-plugin-api v0.0.27
|
||||
github.com/mattermost/mattermost-server/v6 v6.3.0
|
||||
github.com/mholt/archiver/v3 v3.5.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/rudderlabs/analytics-go v3.3.1+incompatible
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/yaegashi/msgraph.go v0.0.0-20191104022859-3f9096c750b2
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/dyatlov/go-opengraph v0.0.0-20210112100619-dae8665a5b09 // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.3 // indirect
|
||||
github.com/go-sql-driver/mysql v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/hashicorp/go-hclog v1.0.0 // indirect
|
||||
github.com/hashicorp/go-plugin v1.4.3 // indirect
|
||||
github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
|
||||
github.com/klauspost/pgzip v1.2.5 // indirect
|
||||
github.com/lib/pq v1.10.4 // indirect
|
||||
github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404 // indirect
|
||||
github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d // indirect
|
||||
github.com/mattermost/logr/v2 v2.0.15 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.16 // indirect
|
||||
github.com/minio/sha256-simd v1.0.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/nwaples/rardecode v1.1.2 // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/pborman/uuid v1.2.1 // indirect
|
||||
github.com/pelletier/go-toml v1.9.4 // indirect
|
||||
github.com/philhofer/fwd v1.1.1 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.11 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rs/xid v1.3.0 // indirect
|
||||
github.com/segmentio/backo-go v0.0.0-20200129164019-23eae7c10bd3 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/tidwall/gjson v1.11.0 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/tinylib/msgp v1.1.6 // indirect
|
||||
github.com/ulikunitz/xz v0.5.10 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/wiggin77/merror v1.0.3 // indirect
|
||||
github.com/wiggin77/srslog v1.0.1 // indirect
|
||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
||||
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
|
||||
github.com/yuin/goldmark v1.4.4 // indirect
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 // indirect
|
||||
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 // indirect
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect
|
||||
google.golang.org/grpc v1.42.0 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/ini.v1 v1.64.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
"release_notes_url": "https://github.com/mattermost/mattermost-plugin-mscalendar/releases/tag/v1.2.1",
|
||||
"icon_path": "assets/profile.svg",
|
||||
"version": "1.2.1",
|
||||
"min_server_version": "5.37.0",
|
||||
"min_server_version": "6.3.0",
|
||||
"server": {
|
||||
"executables": {
|
||||
"darwin-amd64": "server/dist/plugin-darwin-amd64",
|
||||
"darwin-arm64": "server/dist/plugin-darwin-arm64",
|
||||
"linux-amd64": "server/dist/plugin-linux-amd64",
|
||||
"linux-arm64": "server/dist/plugin-linux-arm64",
|
||||
"windows-amd64": "server/dist/plugin-windows-amd64.exe"
|
||||
},
|
||||
"executable": ""
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/config"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/mscalendar"
|
||||
|
@ -26,8 +26,8 @@ func (api *api) preprocessAction(w http.ResponseWriter, req *http.Request) (msca
|
|||
return nil, nil, "", "", ""
|
||||
}
|
||||
|
||||
request := model.PostActionIntegrationRequestFromJson(req.Body)
|
||||
if request == nil {
|
||||
var request model.PostActionIntegrationRequest
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
utils.SlackAttachmentError(w, "Error: invalid request")
|
||||
return nil, nil, "", "", ""
|
||||
}
|
||||
|
@ -128,7 +128,9 @@ func (api *api) postActionRespond(w http.ResponseWriter, req *http.Request) {
|
|||
postResponse.EphemeralText = "Event has changed since this message. Please change your status directly on MS Calendar."
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(postResponse.ToJson())
|
||||
if err := json.NewEncoder(w).Encode(postResponse); err != nil {
|
||||
utils.SlackAttachmentError(w, "Error: unable to write response, "+err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func prettyOption(option string) string {
|
||||
|
@ -154,8 +156,8 @@ func (api *api) postActionConfirmStatusChange(w http.ResponseWriter, req *http.R
|
|||
response := model.PostActionIntegrationResponse{}
|
||||
post := &model.Post{}
|
||||
|
||||
request := model.PostActionIntegrationRequestFromJson(req.Body)
|
||||
if request == nil {
|
||||
var request model.PostActionIntegrationRequest
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
utils.SlackAttachmentError(w, "Invalid request.")
|
||||
return
|
||||
}
|
||||
|
@ -226,7 +228,9 @@ func (api *api) postActionConfirmStatusChange(w http.ResponseWriter, req *http.R
|
|||
|
||||
response.Update = post
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(response.ToJson())
|
||||
if err := json.NewEncoder(w).Encode(response); err != nil {
|
||||
utils.SlackAttachmentError(w, "Error: unable to write response, "+err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func getEventInfo(ctx map[string]interface{}) (string, error) {
|
||||
|
|
|
@ -9,8 +9,8 @@ import (
|
|||
|
||||
pluginapilicense "github.com/mattermost/mattermost-plugin-api"
|
||||
"github.com/mattermost/mattermost-plugin-api/experimental/command"
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v5/plugin"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/plugin"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/config"
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v5/plugin"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/plugin"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v5/plugin"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/plugin"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
model "github.com/mattermost/mattermost-server/v5/model"
|
||||
model "github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
// MockJobPluginAPI is a mock of JobPluginAPI interface.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
mattermostplugin "github.com/mattermost/mattermost-server/v5/plugin"
|
||||
mattermostplugin "github.com/mattermost/mattermost-server/v6/plugin"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/config"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/mscalendar"
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/config"
|
||||
|
@ -230,14 +230,14 @@ func (m *mscalendar) setUserStatuses(users []*store.User, calendarViews []*remot
|
|||
func (m *mscalendar) setStatusFromCalendarView(user *store.User, status *model.Status, res *remote.ViewCalendarResponse) (string, bool, error) {
|
||||
isStatusChanged := false
|
||||
currentStatus := status.Status
|
||||
if currentStatus == model.STATUS_OFFLINE && !user.Settings.GetConfirmation {
|
||||
if currentStatus == model.StatusOffline && !user.Settings.GetConfirmation {
|
||||
return "User offline and does not want status change confirmations. No status change", isStatusChanged, nil
|
||||
}
|
||||
|
||||
events := filterBusyEvents(res.Events)
|
||||
busyStatus := model.STATUS_DND
|
||||
busyStatus := model.StatusDnd
|
||||
if user.Settings.ReceiveNotificationsDuringMeeting {
|
||||
busyStatus = model.STATUS_AWAY
|
||||
busyStatus = model.StatusAway
|
||||
}
|
||||
|
||||
if len(user.ActiveEvents) == 0 && len(events) == 0 {
|
||||
|
@ -343,16 +343,16 @@ func (m *mscalendar) setStatusFromCalendarView(user *store.User, status *model.S
|
|||
// - events: the list of events that are triggering this status change
|
||||
// - isFree: whether the user is free or busy, to decide to which status to change
|
||||
func (m *mscalendar) setStatusOrAskUser(user *store.User, currentStatus *model.Status, events []*remote.Event, isFree bool) error {
|
||||
toSet := model.STATUS_ONLINE
|
||||
toSet := model.StatusOnline
|
||||
if isFree && user.LastStatus != "" {
|
||||
toSet = user.LastStatus
|
||||
user.LastStatus = ""
|
||||
}
|
||||
|
||||
if !isFree {
|
||||
toSet = model.STATUS_DND
|
||||
toSet = model.StatusDnd
|
||||
if user.Settings.ReceiveNotificationsDuringMeeting {
|
||||
toSet = model.STATUS_AWAY
|
||||
toSet = model.StatusAway
|
||||
}
|
||||
if !user.Settings.GetConfirmation {
|
||||
user.LastStatus = ""
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/config"
|
||||
|
|
|
@ -14,9 +14,9 @@ import (
|
|||
"github.com/mattermost/mattermost-plugin-mscalendar/server/remote/mock_remote"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/store"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/store/mock_store"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/telemetry"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/tracker"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils/bot/mock_bot"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils/telemetry"
|
||||
)
|
||||
|
||||
func TestProcessAllDailySummary(t *testing.T) {
|
||||
|
@ -183,7 +183,7 @@ Wednesday February 12
|
|||
Poster: poster,
|
||||
Remote: mockRemote,
|
||||
PluginAPI: mockPluginAPI,
|
||||
Tracker: tracker.New(telemetry.NewTracker(nil, "", "", "", "", "", true, logger)),
|
||||
Tracker: tracker.New(telemetry.NewTracker(nil, "", "", "", "", "", telemetry.TrackerConfig{}, nil)),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
model "github.com/mattermost/mattermost-server/v5/model"
|
||||
model "github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
// MockPluginAPI is a mock of PluginAPI interface.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
package mscalendar
|
||||
|
||||
import (
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/config"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/remote"
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/config"
|
||||
|
@ -340,7 +340,7 @@ func NewPostActionForEventResponse(eventID, response, url string) []*model.PostA
|
|||
|
||||
pa := &model.PostAction{
|
||||
Name: "Response",
|
||||
Type: model.POST_ACTION_TYPE_SELECT,
|
||||
Type: model.PostActionTypeSelect,
|
||||
Integration: &model.PostActionIntegration{
|
||||
URL: url,
|
||||
Context: context,
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/jarcoal/httpmock"
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/config"
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/store"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils/settingspanel"
|
||||
|
|
|
@ -3,7 +3,7 @@ package mscalendar
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils/settingspanel"
|
||||
)
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/remote"
|
||||
|
|
|
@ -6,16 +6,16 @@ import (
|
|||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/remote"
|
||||
)
|
||||
|
||||
var prettyStatuses = map[string]string{
|
||||
model.STATUS_ONLINE: "Online",
|
||||
model.STATUS_AWAY: "Away",
|
||||
model.STATUS_DND: "Do Not Disturb",
|
||||
model.STATUS_OFFLINE: "Offline",
|
||||
model.StatusOnline: "Online",
|
||||
model.StatusAway: "Away",
|
||||
model.StatusDnd: "Do Not Disturb",
|
||||
model.StatusOffline: "Offline",
|
||||
}
|
||||
|
||||
func RenderStatusChangeNotificationView(events []*remote.Event, status, url string) *model.SlackAttachment {
|
||||
|
@ -26,7 +26,7 @@ func RenderStatusChangeNotificationView(events []*remote.Event, status, url stri
|
|||
}
|
||||
|
||||
nEvents := len(events)
|
||||
if nEvents > 0 && status == model.STATUS_DND {
|
||||
if nEvents > 0 && status == model.StatusDnd {
|
||||
return statusChangeAttachments(events[nEvents-1], status, url)
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package mscalendar
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/config"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/store"
|
||||
|
|
|
@ -14,8 +14,9 @@ import (
|
|||
"text/template"
|
||||
|
||||
pluginapiclient "github.com/mattermost/mattermost-plugin-api"
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v5/plugin"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/plugin"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/api"
|
||||
|
@ -26,6 +27,7 @@ import (
|
|||
"github.com/mattermost/mattermost-plugin-mscalendar/server/remote"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/remote/msgraph"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/store"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/telemetry"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/tracker"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils/bot"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils/flow"
|
||||
|
@ -33,7 +35,6 @@ import (
|
|||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils/oauth2connect"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils/pluginapi"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils/settingspanel"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils/telemetry"
|
||||
)
|
||||
|
||||
type Env struct {
|
||||
|
@ -92,11 +93,30 @@ func (p *Plugin) OnActivate() error {
|
|||
return errors.Wrap(err, "failed to register command")
|
||||
}
|
||||
|
||||
// Telemetry client
|
||||
p.telemetryClient, err = telemetry.NewRudderClient()
|
||||
if err != nil {
|
||||
p.env.bot.Errorf("Cannot create telemetry client. err=%v", err)
|
||||
p.API.LogWarn("Telemetry client not started", "error", err.Error())
|
||||
}
|
||||
|
||||
// Get config values
|
||||
p.updateEnv(func(e *Env) {
|
||||
e.Dependencies.Tracker = tracker.New(
|
||||
telemetry.NewTracker(
|
||||
p.telemetryClient,
|
||||
p.API.GetDiagnosticId(),
|
||||
p.API.GetServerVersion(),
|
||||
e.PluginID,
|
||||
e.PluginVersion,
|
||||
config.TelemetryShortName,
|
||||
telemetry.NewTrackerConfig(p.API.GetConfig()),
|
||||
telemetry.NewLogger(p.API),
|
||||
),
|
||||
)
|
||||
e.bot = e.bot.WithConfig(stored.Config)
|
||||
e.Dependencies.Store = store.NewPluginStore(p.API, e.bot, e.Dependencies.Tracker)
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -159,11 +179,10 @@ func (p *Plugin) OnConfigurationChange() (err error) {
|
|||
|
||||
e.Dependencies.Logger = e.bot
|
||||
|
||||
diagnostics := false
|
||||
if p.API.GetConfig() != nil && p.API.GetConfig().LogSettings.EnableDiagnostics != nil {
|
||||
diagnostics = *p.API.GetConfig().LogSettings.EnableDiagnostics
|
||||
// reload tracker behavior looking to some key config changes
|
||||
if e.Dependencies.Tracker != nil {
|
||||
e.Dependencies.Tracker.ReloadConfig(p.API.GetConfig())
|
||||
}
|
||||
e.Dependencies.Tracker = tracker.New(telemetry.NewTracker(p.telemetryClient, p.API.GetDiagnosticId(), p.API.GetServerVersion(), e.PluginID, e.PluginVersion, config.TelemetryShortName, diagnostics, e.Logger))
|
||||
|
||||
e.Dependencies.Poster = e.bot
|
||||
e.Dependencies.Welcomer = mscalendarBot
|
||||
|
@ -300,14 +319,15 @@ func (p *Plugin) initEnv(e *Env, pluginURL string) error {
|
|||
e.Dependencies.PluginAPI = pluginapi.New(p.API)
|
||||
|
||||
if e.bot == nil {
|
||||
e.bot = bot.New(p.API, p.Helpers, pluginURL)
|
||||
e.bot = bot.New(p.API, pluginURL)
|
||||
err := e.bot.Ensure(
|
||||
&model.Bot{
|
||||
Username: config.BotUserName,
|
||||
DisplayName: config.BotDisplayName,
|
||||
Description: config.BotDescription,
|
||||
},
|
||||
"assets/profile.png")
|
||||
filepath.Join("assets", "profile.png"),
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to ensure bot account")
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
@ -74,7 +73,7 @@ func (c *client) call(method, path, contentType string, inBody io.Reader, out in
|
|||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
responseData, err = ioutil.ReadAll(resp.Body)
|
||||
responseData, err = io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ package msgraph
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
|
@ -38,7 +38,7 @@ func (r *impl) HandleWebhook(w http.ResponseWriter, req *http.Request) []*remote
|
|||
return nil
|
||||
}
|
||||
|
||||
rawData, err := ioutil.ReadAll(req.Body)
|
||||
rawData, err := io.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
r.logger.Infof("msgraph: failed to process webhook: `%v`.", err)
|
||||
|
|
|
@ -6,7 +6,7 @@ package store
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/plugin"
|
||||
"github.com/mattermost/mattermost-server/v6/plugin"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/tracker"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils/bot"
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
// Copyright (c) 2019-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License for license information.
|
||||
|
||||
// Copied from pluginapi/experimental/bot/logger to avoid upgrading min_server_version
|
||||
// remove this file once pluginapi can be updated to 0.1.3+ ( min_server_version is
|
||||
//
|
||||
// safe to point at 7.x)
|
||||
package telemetry
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
timed = "__since"
|
||||
elapsed = "Elapsed"
|
||||
|
||||
ErrorKey = "error"
|
||||
)
|
||||
|
||||
// LogLevel defines the level of log messages
|
||||
type LogLevel string
|
||||
|
||||
const (
|
||||
// LogLevelDebug denotes debug messages
|
||||
LogLevelDebug = "debug"
|
||||
// LogLevelInfo denotes info messages
|
||||
LogLevelInfo = "info"
|
||||
// LogLevelWarn denotes warn messages
|
||||
LogLevelWarn = "warn"
|
||||
// LogLevelError denotes error messages
|
||||
LogLevelError = "error"
|
||||
)
|
||||
|
||||
// LogContext defines the context for the logs.
|
||||
type LogContext map[string]interface{}
|
||||
|
||||
// Logger defines an object able to log messages.
|
||||
type Logger interface {
|
||||
// With adds a logContext to the logger.
|
||||
With(LogContext) Logger
|
||||
// WithError adds an Error to the logger.
|
||||
WithError(error) Logger
|
||||
// Context returns the current context
|
||||
Context() LogContext
|
||||
// Timed add a timed log context.
|
||||
Timed() Logger
|
||||
// Debugf logs a formatted string as a debug message.
|
||||
Debugf(format string, args ...interface{})
|
||||
// Errorf logs a formatted string as an error message.
|
||||
Errorf(format string, args ...interface{})
|
||||
// Infof logs a formatted string as an info message.
|
||||
Infof(format string, args ...interface{})
|
||||
// Warnf logs a formatted string as an warning message.
|
||||
Warnf(format string, args ...interface{})
|
||||
}
|
||||
|
||||
type LogAPI interface {
|
||||
LogError(message string, keyValuePairs ...interface{})
|
||||
LogWarn(message string, keyValuePairs ...interface{})
|
||||
LogInfo(message string, keyValuePairs ...interface{})
|
||||
LogDebug(message string, keyValuePairs ...interface{})
|
||||
}
|
||||
|
||||
type defaultLogger struct {
|
||||
logContext LogContext
|
||||
logAPI LogAPI
|
||||
}
|
||||
|
||||
func measure(lc LogContext) {
|
||||
if lc[timed] == nil {
|
||||
return
|
||||
}
|
||||
started := lc[timed].(time.Time)
|
||||
lc[elapsed] = time.Since(started).String()
|
||||
delete(lc, timed)
|
||||
}
|
||||
|
||||
func toKeyValuePairs(in map[string]interface{}) (out []interface{}) {
|
||||
for k, v := range in {
|
||||
out = append(out, k, v)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
/*
|
||||
New creates a new logger.
|
||||
|
||||
- api: LogAPI implementation
|
||||
*/
|
||||
func NewLogger(api LogAPI) Logger {
|
||||
l := &defaultLogger{
|
||||
logAPI: api,
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *defaultLogger) With(logContext LogContext) Logger {
|
||||
newLogger := *l
|
||||
if len(newLogger.logContext) == 0 {
|
||||
newLogger.logContext = map[string]interface{}{}
|
||||
}
|
||||
for k, v := range logContext {
|
||||
newLogger.logContext[k] = v
|
||||
}
|
||||
return &newLogger
|
||||
}
|
||||
|
||||
func (l *defaultLogger) WithError(err error) Logger {
|
||||
newLogger := *l
|
||||
if len(newLogger.logContext) == 0 {
|
||||
newLogger.logContext = map[string]interface{}{}
|
||||
}
|
||||
newLogger.logContext[ErrorKey] = err.Error()
|
||||
return &newLogger
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Context() LogContext {
|
||||
return l.logContext
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Timed() Logger {
|
||||
return l.With(LogContext{
|
||||
timed: time.Now(),
|
||||
})
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Debugf(format string, args ...interface{}) {
|
||||
measure(l.logContext)
|
||||
message := fmt.Sprintf(format, args...)
|
||||
l.logAPI.LogDebug(message, toKeyValuePairs(l.logContext)...)
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Errorf(format string, args ...interface{}) {
|
||||
measure(l.logContext)
|
||||
message := fmt.Sprintf(format, args...)
|
||||
l.logAPI.LogError(message, toKeyValuePairs(l.logContext)...)
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Infof(format string, args ...interface{}) {
|
||||
measure(l.logContext)
|
||||
message := fmt.Sprintf(format, args...)
|
||||
l.logAPI.LogInfo(message, toKeyValuePairs(l.logContext)...)
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Warnf(format string, args ...interface{}) {
|
||||
measure(l.logContext)
|
||||
message := fmt.Sprintf(format, args...)
|
||||
l.logAPI.LogWarn(message, toKeyValuePairs(l.logContext)...)
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package telemetry
|
||||
|
||||
import (
|
||||
rudder "github.com/rudderlabs/analytics-go"
|
||||
)
|
||||
|
||||
// rudderDataPlaneURL is set to the common Data Plane URL for all Mattermost Projects.
|
||||
// It can be set during build time. More info in the package documentation.
|
||||
var rudderDataPlaneURL = "https://pdat.matterlytics.com"
|
||||
|
||||
// rudderWriteKey is set during build time. More info in the package documentation.
|
||||
var rudderWriteKey string
|
||||
|
||||
// NewRudderClient creates a new telemetry client with Rudder using the default configuration.
|
||||
func NewRudderClient() (Client, error) {
|
||||
return NewRudderClientWithCredentials(rudderWriteKey, rudderDataPlaneURL)
|
||||
}
|
||||
|
||||
// NewRudderClientWithCredentials lets you create a Rudder client with your own credentials.
|
||||
func NewRudderClientWithCredentials(writeKey, dataPlaneURL string) (Client, error) {
|
||||
client, err := rudder.NewWithConfig(writeKey, dataPlaneURL, rudder.Config{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &rudderWrapper{client: client}, nil
|
||||
}
|
||||
|
||||
type rudderWrapper struct {
|
||||
client rudder.Client
|
||||
}
|
||||
|
||||
func (r *rudderWrapper) Enqueue(t Track) error {
|
||||
var context *rudder.Context
|
||||
if t.InstallationID != "" {
|
||||
context = &rudder.Context{Traits: map[string]interface{}{"installationId": t.InstallationID}}
|
||||
}
|
||||
|
||||
return r.client.Enqueue(rudder.Track{
|
||||
UserId: t.UserID,
|
||||
Event: t.Event,
|
||||
Context: context,
|
||||
Properties: t.Properties,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *rudderWrapper) Close() error {
|
||||
return r.client.Close()
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
package telemetry
|
||||
|
||||
import (
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type TrackerConfig struct {
|
||||
EnabledTracking bool
|
||||
EnabledLogging bool
|
||||
}
|
||||
|
||||
// NewTrackerConfig returns a new trackerConfig from the current values of the model.Config.
|
||||
func NewTrackerConfig(config *model.Config) TrackerConfig {
|
||||
var enabledTracking, enabledLogging bool
|
||||
if config == nil {
|
||||
return TrackerConfig{}
|
||||
}
|
||||
|
||||
if enableDiagnostics := config.LogSettings.EnableDiagnostics; enableDiagnostics != nil {
|
||||
enabledTracking = *enableDiagnostics
|
||||
}
|
||||
|
||||
if enableDeveloper := config.ServiceSettings.EnableDeveloper; enableDeveloper != nil {
|
||||
enabledLogging = *enableDeveloper
|
||||
}
|
||||
|
||||
return TrackerConfig{
|
||||
EnabledTracking: enabledTracking,
|
||||
EnabledLogging: enabledLogging,
|
||||
}
|
||||
}
|
||||
|
||||
// Tracker defines a telemetry tracker
|
||||
type Tracker interface {
|
||||
// TrackEvent registers an event through the configured telemetry client
|
||||
TrackEvent(event string, properties map[string]interface{}) error
|
||||
// TrackUserEvent registers an event through the configured telemetry client associated to a user
|
||||
TrackUserEvent(event string, userID string, properties map[string]interface{}) error
|
||||
// Reload Config re-evaluates tracker config to determine if tracking behavior should change
|
||||
ReloadConfig(config TrackerConfig)
|
||||
}
|
||||
|
||||
// Client defines a telemetry client
|
||||
type Client interface {
|
||||
// Enqueue adds a tracker event (Track) to be registered
|
||||
Enqueue(t Track) error
|
||||
// Close closes the client connection, flushing any event left on the queue
|
||||
Close() error
|
||||
}
|
||||
|
||||
// Track defines an event ready for the client to process
|
||||
type Track struct {
|
||||
UserID string
|
||||
Event string
|
||||
Properties map[string]interface{}
|
||||
InstallationID string
|
||||
}
|
||||
|
||||
type tracker struct {
|
||||
client Client
|
||||
diagnosticID string
|
||||
serverVersion string
|
||||
pluginID string
|
||||
pluginVersion string
|
||||
telemetryShortName string
|
||||
configLock sync.RWMutex
|
||||
config TrackerConfig
|
||||
logger Logger
|
||||
}
|
||||
|
||||
// NewTracker creates a default Tracker
|
||||
// - c Client: A telemetry client. If nil, the tracker will not track any event.
|
||||
// - diagnosticID: Server unique ID used for telemetry.
|
||||
// - severVersion: Mattermost server version.
|
||||
// - pluginID: The plugin ID.
|
||||
// - pluginVersion: The plugin version.
|
||||
// - telemetryShortName: Short name for the plugin to use in telemetry. Used to avoid dot separated names like `com.company.pluginName`.
|
||||
// If a empty string is provided, it will use the pluginID.
|
||||
// - config: Whether the system has enabled sending telemetry data. If false, the tracker will not track any event.
|
||||
// - l Logger: A logger to debug event tracking and some important changes (it won't log if nil is passed as logger).
|
||||
func NewTracker(
|
||||
c Client,
|
||||
diagnosticID,
|
||||
serverVersion,
|
||||
pluginID,
|
||||
pluginVersion,
|
||||
telemetryShortName string,
|
||||
config TrackerConfig,
|
||||
l Logger,
|
||||
) Tracker {
|
||||
if telemetryShortName == "" {
|
||||
telemetryShortName = pluginID
|
||||
}
|
||||
return &tracker{
|
||||
telemetryShortName: telemetryShortName,
|
||||
client: c,
|
||||
diagnosticID: diagnosticID,
|
||||
serverVersion: serverVersion,
|
||||
pluginID: pluginID,
|
||||
pluginVersion: pluginVersion,
|
||||
logger: l,
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tracker) ReloadConfig(config TrackerConfig) {
|
||||
t.configLock.Lock()
|
||||
defer t.configLock.Unlock()
|
||||
|
||||
if config.EnabledTracking != t.config.EnabledTracking {
|
||||
if config.EnabledTracking {
|
||||
t.debugf("Enabling plugin telemetry")
|
||||
} else {
|
||||
t.debugf("Disabling plugin telemetry")
|
||||
}
|
||||
}
|
||||
|
||||
t.config.EnabledTracking = config.EnabledTracking
|
||||
t.config.EnabledLogging = config.EnabledLogging
|
||||
}
|
||||
|
||||
// Note that config lock is handled by the caller.
|
||||
func (t *tracker) debugf(message string, args ...interface{}) {
|
||||
if t.logger == nil || !t.config.EnabledLogging {
|
||||
return
|
||||
}
|
||||
t.logger.Debugf(message, args...)
|
||||
}
|
||||
|
||||
func (t *tracker) TrackEvent(event string, properties map[string]interface{}) error {
|
||||
t.configLock.RLock()
|
||||
defer t.configLock.RUnlock()
|
||||
|
||||
event = t.telemetryShortName + "_" + event
|
||||
if !t.config.EnabledTracking || t.client == nil {
|
||||
t.debugf("Plugin telemetry event `%s` tracked, but not sent due to configuration", event)
|
||||
return nil
|
||||
}
|
||||
|
||||
if properties == nil {
|
||||
properties = map[string]interface{}{}
|
||||
}
|
||||
properties["PluginID"] = t.pluginID
|
||||
properties["PluginVersion"] = t.pluginVersion
|
||||
properties["ServerVersion"] = t.serverVersion
|
||||
|
||||
// if we are part of a cloud installation, add it's ID to the tracked event's context.
|
||||
installationID := os.Getenv("MM_CLOUD_INSTALLATION_ID")
|
||||
|
||||
err := t.client.Enqueue(Track{
|
||||
// We consider the server the "user" on the telemetry system. Any reference to the actual user is passed by properties.
|
||||
UserID: t.diagnosticID,
|
||||
Event: event,
|
||||
Properties: properties,
|
||||
InstallationID: installationID,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "cannot enqueue the track")
|
||||
}
|
||||
t.debugf("Tracked plugin telemetry event `%s`", event)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *tracker) TrackUserEvent(event, userID string, properties map[string]interface{}) error {
|
||||
if properties == nil {
|
||||
properties = map[string]interface{}{}
|
||||
}
|
||||
|
||||
properties["UserActualID"] = userID
|
||||
return t.TrackEvent(event, properties)
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
package tracker
|
||||
|
||||
import "github.com/mattermost/mattermost-plugin-mscalendar/server/utils/telemetry"
|
||||
import (
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/telemetry"
|
||||
)
|
||||
|
||||
const (
|
||||
welcomeFlowCompletionEvent = "welcomeFlowCompletion"
|
||||
|
@ -16,6 +20,7 @@ type Tracker interface {
|
|||
TrackUserDeauthenticated(userID string)
|
||||
TrackDailySummarySent(userID string)
|
||||
TrackAutomaticStatusUpdate(userID string, value bool, location string)
|
||||
ReloadConfig(config *model.Config)
|
||||
}
|
||||
|
||||
func New(t telemetry.Tracker) Tracker {
|
||||
|
@ -28,6 +33,12 @@ type tracker struct {
|
|||
tracker telemetry.Tracker
|
||||
}
|
||||
|
||||
func (t *tracker) ReloadConfig(config *model.Config) {
|
||||
if t.tracker != nil {
|
||||
t.tracker.ReloadConfig(telemetry.NewTrackerConfig(config))
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tracker) TrackWelcomeFlowCompletion(userID string) {
|
||||
t.tracker.TrackUserEvent(welcomeFlowCompletionEvent, userID, map[string]interface{}{})
|
||||
}
|
||||
|
|
|
@ -6,8 +6,9 @@ package bot
|
|||
import (
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v5/plugin"
|
||||
pluginapi "github.com/mattermost/mattermost-plugin-api"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/plugin"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils/flow"
|
||||
)
|
||||
|
@ -26,7 +27,6 @@ type Bot interface {
|
|||
|
||||
type bot struct {
|
||||
pluginAPI plugin.API
|
||||
pluginHelpers plugin.Helpers
|
||||
flow flow.Flow
|
||||
flowStore flow.Store
|
||||
logContext LogContext
|
||||
|
@ -36,11 +36,10 @@ type bot struct {
|
|||
Config
|
||||
}
|
||||
|
||||
func New(api plugin.API, helpers plugin.Helpers, pluginURL string) Bot {
|
||||
func New(api plugin.API, pluginURL string) Bot {
|
||||
return &bot{
|
||||
pluginAPI: api,
|
||||
pluginHelpers: helpers,
|
||||
pluginURL: pluginURL,
|
||||
pluginAPI: api,
|
||||
pluginURL: pluginURL,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,8 +53,8 @@ func (bot *bot) Ensure(stored *model.Bot, iconPath string) error {
|
|||
// Already done
|
||||
return nil
|
||||
}
|
||||
|
||||
botUserID, err := bot.pluginHelpers.EnsureBot(stored, plugin.ProfileImagePath(iconPath))
|
||||
client := pluginapi.NewClient(bot.pluginAPI, nil) // driver passed as nil, as we don't need it
|
||||
botUserID, err := client.Bot.EnsureBot(stored, pluginapi.ProfileImagePath(iconPath))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to ensure bot account")
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
model "github.com/mattermost/mattermost-server/v5/model"
|
||||
model "github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
// MockPoster is a mock of Poster interface.
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
type Poster interface {
|
||||
|
|
|
@ -3,7 +3,7 @@ package flow
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
type EmptyStep struct {
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
type Flow interface {
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
package flow
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils/httputils"
|
||||
|
@ -68,7 +69,11 @@ func (fh *fh) handleFlow(w http.ResponseWriter, r *http.Request) {
|
|||
response.Update = &post
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(response.ToJson())
|
||||
err = json.NewEncoder(w).Encode(response)
|
||||
if err != nil {
|
||||
utils.SlackAttachmentError(w, "Error encoding response, err="+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
fh.store.RemovePostID(mattermostUserID, property)
|
||||
fh.flow.StepDone(mattermostUserID, stepNumber, value)
|
||||
|
|
|
@ -5,7 +5,6 @@ package httputils
|
|||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
@ -15,7 +14,7 @@ import (
|
|||
)
|
||||
|
||||
func TestLimitReadCloser(t *testing.T) {
|
||||
inner := ioutil.NopCloser(strings.NewReader("01234567890"))
|
||||
inner := io.NopCloser(strings.NewReader("01234567890"))
|
||||
|
||||
totalRead := utils.ByteSize(0)
|
||||
r := &LimitReadCloser{
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"crypto/md5"
|
||||
"fmt"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
type hashedKeyStore struct {
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ package kvstore
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/plugin"
|
||||
"github.com/mattermost/mattermost-server/v6/plugin"
|
||||
)
|
||||
|
||||
// OneTimeStore is a KV store that deletes each record after the first load,
|
||||
|
|
|
@ -6,8 +6,8 @@ package kvstore
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v5/plugin"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/plugin"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ package pluginapi
|
|||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v5/plugin"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/plugin"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/store"
|
||||
)
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
type boolSetting struct {
|
||||
|
|
|
@ -3,7 +3,7 @@ package settingspanel
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
type emptySetting struct {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package settingspanel
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils/httputils"
|
||||
|
@ -34,9 +35,8 @@ func (sh *handler) handleAction(w http.ResponseWriter, r *http.Request) {
|
|||
utils.SlackAttachmentError(w, "Error: Not authorized")
|
||||
return
|
||||
}
|
||||
|
||||
request := model.PostActionIntegrationRequestFromJson(r.Body)
|
||||
if request == nil {
|
||||
var request model.PostActionIntegrationRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
|
||||
utils.SlackAttachmentError(w, "Error: invalid request")
|
||||
return
|
||||
}
|
||||
|
@ -69,5 +69,7 @@ func (sh *handler) handleAction(w http.ResponseWriter, r *http.Request) {
|
|||
response.Update = post
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(response.ToJson())
|
||||
if err := json.NewEncoder(w).Encode(response); err != nil {
|
||||
utils.SlackAttachmentError(w, "Error: unable to write response, "+err.Error())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
type optionSetting struct {
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
type readOnlySetting struct {
|
||||
|
|
|
@ -3,7 +3,7 @@ package settingspanel
|
|||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils/bot"
|
||||
"github.com/mattermost/mattermost-plugin-mscalendar/server/utils/kvstore"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package settingspanel
|
||||
|
||||
import "github.com/mattermost/mattermost-server/v5/model"
|
||||
import "github.com/mattermost/mattermost-server/v6/model"
|
||||
|
||||
func stringsToOptions(in []string) []*model.PostActionOptions {
|
||||
out := []*model.PostActionOptions{}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
func SlackAttachmentError(w http.ResponseWriter, errorMessage string) {
|
||||
|
@ -11,5 +12,5 @@ func SlackAttachmentError(w http.ResponseWriter, errorMessage string) {
|
|||
EphemeralText: errorMessage,
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(response.ToJson())
|
||||
_ = json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
package telemetry
|
||||
|
||||
import rudder "github.com/rudderlabs/analytics-go"
|
||||
|
||||
const rudderDataPlaneURL = "https://pdat.matterlytics.com"
|
||||
|
||||
var rudderWriteKey string
|
||||
|
||||
func NewRudderClient() (Client, error) {
|
||||
return NewRudderClientWithCredentials(rudderWriteKey, rudderDataPlaneURL)
|
||||
}
|
||||
|
||||
func NewRudderClientWithCredentials(writeKey, dataPlaneURL string) (Client, error) {
|
||||
client, err := rudder.NewWithConfig(writeKey, dataPlaneURL, rudder.Config{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &rudderWrapper{client: client}, nil
|
||||
}
|
||||
|
||||
type rudderWrapper struct {
|
||||
client rudder.Client
|
||||
}
|
||||
|
||||
func (r *rudderWrapper) Enqueue(t Track) error {
|
||||
err := r.client.Enqueue(rudder.Track{
|
||||
UserId: t.UserID,
|
||||
Event: t.Event,
|
||||
Properties: t.Properties,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *rudderWrapper) Close() error {
|
||||
err := r.client.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
package telemetry
|
||||
|
||||
import "github.com/mattermost/mattermost-plugin-mscalendar/server/utils/bot"
|
||||
|
||||
type Tracker interface {
|
||||
Track(event string, properties map[string]interface{})
|
||||
TrackUserEvent(event string, userID string, properties map[string]interface{})
|
||||
}
|
||||
|
||||
type Client interface {
|
||||
Enqueue(t Track) error
|
||||
Close() error
|
||||
}
|
||||
|
||||
type Track struct {
|
||||
Properties map[string]interface{}
|
||||
UserID string
|
||||
Event string
|
||||
}
|
||||
|
||||
type tracker struct {
|
||||
client Client
|
||||
logger bot.Logger
|
||||
serverVersion string
|
||||
pluginID string
|
||||
pluginVersion string
|
||||
telemetryShortName string
|
||||
diagnosticID string
|
||||
enabled bool
|
||||
}
|
||||
|
||||
func NewTracker(c Client, diagnosticID, serverVersion, pluginID, pluginVersion, telemetryShortName string, enableDiagnostics bool, logger bot.Logger) Tracker {
|
||||
return &tracker{
|
||||
telemetryShortName: telemetryShortName,
|
||||
client: c,
|
||||
diagnosticID: diagnosticID,
|
||||
serverVersion: serverVersion,
|
||||
pluginID: pluginID,
|
||||
pluginVersion: pluginVersion,
|
||||
enabled: enableDiagnostics,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tracker) Track(event string, properties map[string]interface{}) {
|
||||
if !t.enabled || t.client == nil {
|
||||
return
|
||||
}
|
||||
|
||||
event = t.telemetryShortName + "_" + event
|
||||
properties["PluginID"] = t.pluginID
|
||||
properties["PluginVersion"] = t.pluginVersion
|
||||
properties["ServerVersion"] = t.serverVersion
|
||||
|
||||
err := t.client.Enqueue(Track{
|
||||
UserID: t.diagnosticID,
|
||||
Event: event,
|
||||
Properties: properties,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.logger.Warnf("cannot enqueue telemetry event, err=%s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tracker) TrackUserEvent(event string, userID string, properties map[string]interface{}) {
|
||||
properties["UserActualID"] = userID
|
||||
t.Track(event, properties)
|
||||
}
|
Reference in New Issue