Repository: mattermost/mattermost-plugin-github
Pull request #649 (2023-03-03 12:42:45)

move debug gcflags to a new var and remove one block on server build
#### Summary
Simplify `make server` command by setting a new var for gcflags based on MM_DEBUG.

it was an opportunistic improvement while checking the current tooling.

#### Ticket Link
Nope



codecov-commenter: # [Codecov](https://codecov.io/gh/mattermost/mattermost-plugin-github/pull/649?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost) Report
Patch coverage has no change and project coverage change: **`+0.08`** :tada:
> Comparison is base [(`84b0428`)](https://codecov.io/gh/mattermost/mattermost-plugin-github/commit/84b042825fac5ec2f3ab5b2b78ea76138c2e0d9b?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost) 15.53% compared to head [(`1648978`)](https://codecov.io/gh/mattermost/mattermost-plugin-github/pull/649?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost) 15.62%.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master     #649      +/-   ##
==========================================
+ Coverage   15.53%   15.62%   +0.08%     
==========================================
  Files          15       15              
  Lines        5414     5447      +33     
==========================================
+ Hits          841      851      +10     
- Misses       4530     4553      +23     
  Partials       43       43              
```


| [Impacted Files](https://codecov.io/gh/mattermost/mattermost-plugin-github/pull/649?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost) | Coverage Δ | |
|---|---|---|
| [server/plugin/webhook.go](https://codecov.io/gh/mattermost/mattermost-plugin-github/pull/649?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost#diff-c2VydmVyL3BsdWdpbi93ZWJob29rLmdv) | `0.81% <0.00%> (-0.02%)` | :arrow_down: |
| [server/plugin/template.go](https://codecov.io/gh/mattermost/mattermost-plugin-github/pull/649?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost#diff-c2VydmVyL3BsdWdpbi90ZW1wbGF0ZS5nbw==) | `95.27% <0.00%> (+0.13%)` | :arrow_up: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/mattermost/mattermost-plugin-github/pull/649?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost).


Patch:
diff --git a/Makefile b/Makefile
index e696390..add646e 100644
--- a/Makefile
+++ b/Makefile
@@ -31,6 +31,12 @@ 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.
 .PHONY: all
 all: check-style test dist
@@ -59,30 +65,19 @@ endif
 .PHONY: server
 server:
 ifneq ($(HAS_SERVER),)
-	mkdir -p server/dist;
-ifeq ($(MM_DEBUG),)
-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) -trimpath -o dist/plugin-$(DEFAULT_GOOS)-$(DEFAULT_GOARCH);
-else
-	cd server && env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-linux-amd64;
-	cd server && env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-linux-arm64;
-	cd server && env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-darwin-amd64;
-	cd server && env CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-darwin-arm64;
-	cd server && env CGO_ENABLED=0 GOOS=windows GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -trimpath -o dist/plugin-windows-amd64.exe;
-endif
-else
+ifneq ($(MM_DEBUG),)
 	$(info DEBUG mode is on; to disable, unset MM_DEBUG)
+endif
+	mkdir -p server/dist;
 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) -gcflags "all=-N -l" -trimpath -o dist/plugin-$(DEFAULT_GOOS)-$(DEFAULT_GOARCH);
+	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) -gcflags "all=-N -l" -trimpath -o dist/plugin-linux-amd64;
-	cd server && env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 $(GO) build $(GO_BUILD_FLAGS) -gcflags "all=-N -l" -trimpath -o dist/plugin-linux-arm64;
-	cd server && env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -gcflags "all=-N -l" -trimpath -o dist/plugin-darwin-amd64;
-	cd server && env CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 $(GO) build $(GO_BUILD_FLAGS) -gcflags "all=-N -l" -trimpath -o dist/plugin-darwin-arm64;
-	cd server && env CGO_ENABLED=0 GOOS=windows GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -gcflags "all=-N -l" -trimpath -o dist/plugin-windows-amd64.exe;
-endif
+	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
 
diff --git a/build/custom.mk b/build/custom.mk
index 86bd34d..0efe683 100644
--- a/build/custom.mk
+++ b/build/custom.mk
@@ -1,6 +1,9 @@
 # Include custom targets and environment variables here
 
-ifndef MM_RUDDER_WRITE_KEY
-	MM_RUDDER_WRITE_KEY = 1d5bMvdrfWClLxgK1FvV3s4U1tg
+# 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)
 endif
-GO_BUILD_FLAGS += -ldflags '-X "github.com/mattermost/mattermost-plugin-api/experimental/telemetry.rudderWriteKey=$(MM_RUDDER_WRITE_KEY)"'
+
+GO_BUILD_FLAGS += -ldflags '-X "github.com/mattermost/mattermost-plugin-api/experimental/telemetry.rudderWriteKey=$(RUDDER_WRITE_KEY)"'
diff --git a/go.mod b/go.mod
index 4e53839..c2aac4f 100644
--- a/go.mod
+++ b/go.mod
@@ -6,7 +6,7 @@ require (
 	github.com/Masterminds/sprig/v3 v3.2.2
 	github.com/google/go-github/v41 v41.0.0
 	github.com/gorilla/mux v1.8.0
-	github.com/mattermost/mattermost-plugin-api v0.1.1
+	github.com/mattermost/mattermost-plugin-api v0.1.3-0.20230323124751-86c7be7ffbac
 	// mmgoget: github.com/mattermost/mattermost-server/v6@v7.5.0 is replaced by -> github.com/mattermost/mattermost-server/v6@21aec2741b
 	github.com/mattermost/mattermost-server/v6 v6.0.0-20221109191448-21aec2741bfe
 	github.com/microcosm-cc/bluemonday v1.0.19
@@ -79,9 +79,9 @@ require (
 	github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
 	github.com/yuin/goldmark v1.4.13 // indirect
 	golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 // indirect
-	golang.org/x/net v0.0.0-20220812174116-3211cb980234 // indirect
-	golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2 // indirect
-	golang.org/x/text v0.3.8 // indirect
+	golang.org/x/net v0.7.0 // indirect
+	golang.org/x/sys v0.5.0 // indirect
+	golang.org/x/text v0.7.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
 	google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1 // indirect
 	google.golang.org/grpc v1.48.0 // indirect
diff --git a/go.sum b/go.sum
index 414a70e..e4f2757 100644
--- a/go.sum
+++ b/go.sum
@@ -231,8 +231,8 @@ github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d h1:/RJ/UV7M5c7L2TQ
 github.com/mattermost/ldap v0.0.0-20201202150706-ee0e6284187d/go.mod h1:HLbgMEI5K131jpxGazJ97AxfPDt31osq36YS1oxFQPQ=
 github.com/mattermost/logr/v2 v2.0.15 h1:+WNbGcsc3dBao65eXlceB6dTILNJRIrvubnsTl3zBew=
 github.com/mattermost/logr/v2 v2.0.15/go.mod h1:mpPp935r5dIkFDo2y9Q87cQWhFR/4xXpNh0k/y8Hmwg=
-github.com/mattermost/mattermost-plugin-api v0.1.1 h1:bNnPbWCLWZpT/k2kjUxNnzCfUggU8WKs2ddz7hNjg1U=
-github.com/mattermost/mattermost-plugin-api v0.1.1/go.mod h1:9yZhtg0bBj3kqSTjXnjYBMZoTsWbe3ajdFMdl9/Jz34=
+github.com/mattermost/mattermost-plugin-api v0.1.3-0.20230323124751-86c7be7ffbac h1:fxdqYaw6wJfMSodMP0SNPm31r9kJ0NI8uQiWVpnj8F0=
+github.com/mattermost/mattermost-plugin-api v0.1.3-0.20230323124751-86c7be7ffbac/go.mod h1:EON5x6XoqubANT9zYLuL+m42SijzpK/dDOuu76PGbSc=
 github.com/mattermost/mattermost-server/v6 v6.0.0-20221109191448-21aec2741bfe h1:9P759/e7xB3IQYo+6Ju9qsj3YUxpnPRXl2x+XFFsRIM=
 github.com/mattermost/mattermost-server/v6 v6.0.0-20221109191448-21aec2741bfe/go.mod h1:Eu6nct2XZRPlHHW4MfZtjli5bY7G9QomKcor/lm+0Sw=
 github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
@@ -456,8 +456,8 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E=
-golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
+golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -517,8 +517,8 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2 h1:fqTvyMIIj+HRzMmnzr9NtpHP6uVpvB5fkHcgPDC4nu8=
-golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -527,8 +527,8 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
-golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
+golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
diff --git a/server/plugin/api.go b/server/plugin/api.go
index 13690f2..828d437 100644
--- a/server/plugin/api.go
+++ b/server/plugin/api.go
@@ -408,6 +408,9 @@ func (p *Plugin) completeConnectUserToGitHub(c *Context, w http.ResponseWriter,
 		return
 	}
 
+	// track the successful connection
+	p.TrackUserEvent("account_connected", c.UserID, nil)
+
 	userInfo := &GitHubUserInfo{
 		UserID:         state.UserID,
 		Token:          tok,
diff --git a/server/plugin/configuration.go b/server/plugin/configuration.go
index 7aca982..900275f 100644
--- a/server/plugin/configuration.go
+++ b/server/plugin/configuration.go
@@ -212,16 +212,11 @@ func (p *Plugin) OnConfigurationChange() error {
 	if err != nil {
 		return errors.Wrap(err, "failed to register command")
 	}
-
-	enableDiagnostics := false
-	if config := p.API.GetConfig(); config != nil {
-		if configValue := config.LogSettings.EnableDiagnostics; configValue != nil {
-			enableDiagnostics = *configValue
-		}
+	// Some config changes require reloading tracking config
+	if p.tracker != nil {
+		p.tracker.ReloadConfig(telemetry.NewTrackerConfig(p.API.GetConfig()))
 	}
 
-	p.tracker = telemetry.NewTracker(p.telemetryClient, p.API.GetDiagnosticId(), p.API.GetServerVersion(), Manifest.Id, Manifest.Version, "github", enableDiagnostics)
-
 	return nil
 }
 
diff --git a/server/plugin/flows.go b/server/plugin/flows.go
index d5c7454..c480401 100644
--- a/server/plugin/flows.go
+++ b/server/plugin/flows.go
@@ -12,7 +12,6 @@ import (
 	pluginapi "github.com/mattermost/mattermost-plugin-api"
 	"github.com/mattermost/mattermost-plugin-api/experimental/flow"
 
-	"github.com/mattermost/mattermost-plugin-api/experimental/telemetry"
 	"github.com/pkg/errors"
 
 	"github.com/mattermost/mattermost-server/v6/model"
@@ -23,6 +22,11 @@ type PingBroker interface {
 	SubscribePings() <-chan *github.PingEvent
 }
 
+type Tracker interface {
+	TrackEvent(event string, properties map[string]interface{})
+	TrackUserEvent(event, userID string, properties map[string]interface{})
+}
+
 type FlowManager struct {
 	client           *pluginapi.Client
 	pluginURL        string
@@ -32,7 +36,7 @@ type FlowManager struct {
 	getGitHubClient  func(ctx context.Context, userID string) (*github.Client, error)
 
 	pingBroker PingBroker
-	tracker    telemetry.Tracker
+	tracker    Tracker
 
 	setupFlow        *flow.Flow
 	oauthFlow        *flow.Flow
@@ -50,7 +54,7 @@ func (p *Plugin) NewFlowManager() *FlowManager {
 		getGitHubClient:  p.GetGitHubClient,
 
 		pingBroker: p.webhookBroker,
-		tracker:    p.tracker,
+		tracker:    p,
 	}
 
 	fm.setupFlow = fm.newFlow("setup").WithSteps(
@@ -223,14 +227,14 @@ func (fm *FlowManager) StartSetupWizard(userID string, delegatedFrom string) err
 }
 
 func (fm *FlowManager) trackStartSetupWizard(userID string, fromInvite bool) {
-	_ = fm.tracker.TrackUserEvent("setup_wizard_start", userID, map[string]interface{}{
+	fm.tracker.TrackUserEvent("setup_wizard_start", userID, map[string]interface{}{
 		"from_invite": fromInvite,
 		"time":        model.GetMillis(),
 	})
 }
 
 func (fm *FlowManager) trackCompleteSetupWizard(userID string) {
-	_ = fm.tracker.TrackUserEvent("setup_wizard_complete", userID, map[string]interface{}{
+	fm.tracker.TrackUserEvent("setup_wizard_complete", userID, map[string]interface{}{
 		"time": model.GetMillis(),
 	})
 }
@@ -249,13 +253,13 @@ func (fm *FlowManager) StartOauthWizard(userID string) error {
 }
 
 func (fm *FlowManager) trackStartOauthWizard(userID string) {
-	_ = fm.tracker.TrackUserEvent("oauth_wizard_start", userID, map[string]interface{}{
+	fm.tracker.TrackUserEvent("oauth_wizard_start", userID, map[string]interface{}{
 		"time": model.GetMillis(),
 	})
 }
 
 func (fm *FlowManager) trackCompleteOauthWizard(userID string) {
-	_ = fm.tracker.TrackUserEvent("oauth_wizard_complete", userID, map[string]interface{}{
+	fm.tracker.TrackUserEvent("oauth_wizard_complete", userID, map[string]interface{}{
 		"time": model.GetMillis(),
 	})
 }
@@ -591,13 +595,13 @@ func (fm *FlowManager) StartWebhookWizard(userID string) error {
 }
 
 func (fm *FlowManager) trackStartWebhookWizard(userID string) {
-	_ = fm.tracker.TrackUserEvent("webhook_wizard_start", userID, map[string]interface{}{
+	fm.tracker.TrackUserEvent("webhook_wizard_start", userID, map[string]interface{}{
 		"time": model.GetMillis(),
 	})
 }
 
 func (fm *FlowManager) trackCompleteWebhookWizard(userID string) {
-	_ = fm.tracker.TrackUserEvent("webhook_wizard_complete", userID, map[string]interface{}{
+	fm.tracker.TrackUserEvent("webhook_wizard_complete", userID, map[string]interface{}{
 		"time": model.GetMillis(),
 	})
 }
@@ -755,13 +759,13 @@ func (fm *FlowManager) StartAnnouncementWizard(userID string) error {
 }
 
 func (fm *FlowManager) trackStartAnnouncementWizard(userID string) {
-	_ = fm.tracker.TrackUserEvent("announcement_wizard_start", userID, map[string]interface{}{
+	fm.tracker.TrackUserEvent("announcement_wizard_start", userID, map[string]interface{}{
 		"time": model.GetMillis(),
 	})
 }
 
 func (fm *FlowManager) trackCompletAnnouncementWizard(userID string) {
-	_ = fm.tracker.TrackUserEvent("announcement_wizard_complete", userID, map[string]interface{}{
+	fm.tracker.TrackUserEvent("announcement_wizard_complete", userID, map[string]interface{}{
 		"time": model.GetMillis(),
 	})
 }
diff --git a/server/plugin/permalinks.go b/server/plugin/permalinks.go
index 84d97cc..e0cc3a0 100644
--- a/server/plugin/permalinks.go
+++ b/server/plugin/permalinks.go
@@ -3,6 +3,7 @@ package plugin
 import (
 	"context"
 	"encoding/hex"
+	"path"
 	"strings"
 	"time"
 
@@ -75,7 +76,7 @@ func (p *Plugin) getReplacements(msg string) []replacement {
 			case "commit":
 				r.permalinkInfo.commit = m[j]
 			case "path":
-				r.permalinkInfo.path = m[j]
+				r.permalinkInfo.path = strings.TrimPrefix(path.Join("/", m[j]), "/")
 			case "line":
 				r.permalinkInfo.line = m[j]
 			}
diff --git a/server/plugin/plugin.go b/server/plugin/plugin.go
index b239a70..4f0713a 100644
--- a/server/plugin/plugin.go
+++ b/server/plugin/plugin.go
@@ -237,11 +237,7 @@ func (p *Plugin) OnActivate() error {
 	}
 
 	p.initializeAPI()
-
-	p.telemetryClient, err = telemetry.NewRudderClient()
-	if err != nil {
-		p.API.LogWarn("Telemetry client not started", "error", err.Error())
-	}
+	p.initializeTelemetry()
 
 	p.webhookBroker = NewWebhookBroker(p.sendGitHubPingEvent)
 	p.oauthBroker = NewOAuthBroker(p.sendOAuthCompleteEvent)
@@ -274,7 +270,9 @@ func (p *Plugin) OnActivate() error {
 func (p *Plugin) OnDeactivate() error {
 	p.webhookBroker.Close()
 	p.oauthBroker.Close()
-
+	if err := p.telemetryClient.Close(); err != nil {
+		p.API.LogWarn("Telemetry client failed to close", "error", err.Error())
+	}
 	return nil
 }
 
diff --git a/server/plugin/telemetry.go b/server/plugin/telemetry.go
index 813951e..a094a7c 100644
--- a/server/plugin/telemetry.go
+++ b/server/plugin/telemetry.go
@@ -4,6 +4,8 @@ import (
 	"strings"
 
 	pluginapi "github.com/mattermost/mattermost-plugin-api"
+	"github.com/mattermost/mattermost-plugin-api/experimental/bot/logger"
+	"github.com/mattermost/mattermost-plugin-api/experimental/telemetry"
 	"github.com/pkg/errors"
 )
 
@@ -11,6 +13,20 @@ const (
 	keysPerPage = 1000
 )
 
+func (p *Plugin) TrackEvent(event string, properties map[string]interface{}) {
+	err := p.tracker.TrackEvent(event, properties)
+	if err != nil {
+		p.API.LogDebug("Error sending telemetry event", "event", event, "error", err.Error())
+	}
+}
+
+func (p *Plugin) TrackUserEvent(event, userID string, properties map[string]interface{}) {
+	err := p.tracker.TrackUserEvent(event, userID, properties)
+	if err != nil {
+		p.API.LogDebug("Error sending user telemetry event", "event", event, "error", err.Error())
+	}
+}
+
 func (p *Plugin) SendDailyTelemetry() {
 	config := p.getConfiguration()
 
@@ -19,7 +35,7 @@ func (p *Plugin) SendDailyTelemetry() {
 		p.API.LogWarn("Failed to get the number of connected users for telemetry", "error", err)
 	}
 
-	_ = p.tracker.TrackEvent("stats", map[string]interface{}{
+	p.TrackEvent("stats", map[string]interface{}{
 		"connected_user_count":          connectedUserCount,
 		"is_oauth_configured":           config.IsOAuthConfigured(),
 		"is_sass":                       config.IsSASS(),
@@ -53,3 +69,29 @@ func (p *Plugin) getConnectedUserCount() (int64, error) {
 
 	return count, nil
 }
+
+// Initialize telemetry setups the tracker/clients needed to send telemetry data.
+// The telemetry.NewTrackerConfig(...) param will take care of extract/parse the config to set rge right settings.
+// If you don't want the default behavior you still can pass a different telemetry.TrackerConfig data.
+func (p *Plugin) initializeTelemetry() {
+	var err error
+
+	// Telemetry client
+	p.telemetryClient, err = telemetry.NewRudderClient()
+	if err != nil {
+		p.API.LogWarn("Telemetry client not started", "error", err.Error())
+		return
+	}
+
+	// Get config values
+	p.tracker = telemetry.NewTracker(
+		p.telemetryClient,
+		p.API.GetDiagnosticId(),
+		p.API.GetServerVersion(),
+		Manifest.Id,
+		Manifest.Version,
+		"github",
+		telemetry.NewTrackerConfig(p.API.GetConfig()),
+		logger.New(p.API),
+	)
+}


Test patch:
diff --git a/server/plugin/permalinks_test.go b/server/plugin/permalinks_test.go
index 0927652..98b8135 100644
--- a/server/plugin/permalinks_test.go
+++ b/server/plugin/permalinks_test.go
@@ -48,7 +48,34 @@ func TestGetReplacements(t *testing.T) {
 					},
 				},
 			},
-		}, {
+		},
+		{
+			name:            "basic link with relative path",
+			input:           "start https://github.com/mattermost/mattermost-server/blob/cbb25838a61872b624ac512556d7bc932486a64c/../../../authentication.go#L15-L22 lorem ipsum",
+			numReplacements: 1,
+			replacements: []replacement{
+				{
+					index: 6,
+					word:  "https://github.com/mattermost/mattermost-server/blob/cbb25838a61872b624ac512556d7bc932486a64c/../../../authentication.go#L15-L22",
+					permalinkInfo: struct {
+						haswww string
+						commit string
+						user   string
+						repo   string
+						path   string
+						line   string
+					}{
+						haswww: "",
+						commit: "cbb25838a61872b624ac512556d7bc932486a64c",
+						line:   "L15-L22",
+						path:   "authentication.go",
+						user:   "mattermost",
+						repo:   "mattermost-server",
+					},
+				},
+			},
+		},
+		{
 			name:            "duplicate expansions",
 			input:           "start https://github.com/mattermost/mattermost-server/blob/cbb25838a61872b624ac512556d7bc932486a64c/app/authentication.go#L15-L22 lorem ipsum https://github.com/mattermost/mattermost-server/blob/cbb25838a61872b624ac512556d7bc932486a64c/app/authentication.go#L15-L22 lorem ipsum",
 			numReplacements: 2,