From 6748cfc19b687300c711f0d50c595c323087f1b7 Mon Sep 17 00:00:00 2001 From: Girish M Date: Mon, 25 Sep 2023 11:28:19 +0530 Subject: [PATCH] notification feature --- server/http.go | 2 ++ server/message.go | 2 ++ server/misc.go | 9 +++++++++ server/projects.go | 1 + server/responses.go | 1 + server/timeEntries.go | 9 ++++++--- server/uiActions.go | 40 +++++++++++++++++++++++++++++++++++++++- 7 files changed, 60 insertions(+), 4 deletions(-) diff --git a/server/http.go b/server/http.go index a59b26a..e4591b0 100644 --- a/server/http.go +++ b/server/http.go @@ -45,6 +45,8 @@ func (p *Plugin) ServeHTTP(_ *plugin.Context, w http.ResponseWriter, r *http.Req SaveWP(p.MattermostPlugin, r) case "/delWP": DeleteWorkPackage(p.MattermostPlugin, w, r) + case "/subscribe": + NotificationSubscribe(p.MattermostPlugin, w, r) case "/notifyChannel": NotifyChannel(p.MattermostPlugin, w, r) case "/bye": diff --git a/server/message.go b/server/message.go index e441aa9..2398b6e 100644 --- a/server/message.go +++ b/server/message.go @@ -50,6 +50,7 @@ var messages = struct { WPFetchFailMsg string CnfWPLogMsg string UnknownStatusCode string + SubscribeMsg string }{ OpAuthFailMsg: "OpenProject authentication failed. Please try again.", ProjectSelMsg: "*Please select a project*", @@ -84,4 +85,5 @@ var messages = struct { WPFetchFailMsg: "**That didn't work :pensive: Couldn't fetch work packages from OP**", CnfWPLogMsg: "**Confirm work package deletion?**", UnknownStatusCode: "**Unknown status code - error occurred** :pensive:", + SubscribeMsg: "**Subscribed to OpenProject notifications :sunglasses: **", } diff --git a/server/misc.go b/server/misc.go index 8c91bf4..71e73d4 100644 --- a/server/misc.go +++ b/server/misc.go @@ -336,6 +336,15 @@ func GetAttachmentJSON(pluginURL string) string { } } }, + { + "name": "Subscribe to notifications", + "integration": { + "url": "` + pluginURL + `/subscribe", + "context": { + "action": "" + } + } + }, { "name": "Bye :wave:", "integration": { diff --git a/server/projects.go b/server/projects.go index 962ad0e..c6fe83e 100644 --- a/server/projects.go +++ b/server/projects.go @@ -29,6 +29,7 @@ type Links struct { Versions Categories `json:"versions"` Projects Categories `json:"projects"` Status Self `json:"status"` + User Self `json:"user"` } type CreateWorkPackage struct { diff --git a/server/responses.go b/server/responses.go index ad62e15..1a2f034 100644 --- a/server/responses.go +++ b/server/responses.go @@ -39,6 +39,7 @@ type Action struct { type Attachment struct { Actions []Action `json:"actions"` + Links Links `json:"_links"` } type OptAttachments struct { diff --git a/server/timeEntries.go b/server/timeEntries.go index c53dc10..7d434c6 100644 --- a/server/timeEntries.go +++ b/server/timeEntries.go @@ -141,9 +141,12 @@ type EmbeddedTimeEntry struct { } type LinksTimeEntry struct { - Self Self `json:"self"` - Validate Self `json:"validate"` - Commit Self `json:"commit"` + Self Self `json:"self"` + Validate Self `json:"validate"` + Commit Self `json:"commit"` + Project Self `json:"project"` + User Self `json:"user"` + WorkPackage Self `json:"workPackage"` } type TimeEntries struct { diff --git a/server/uiActions.go b/server/uiActions.go index 09834d8..2e62988 100644 --- a/server/uiActions.go +++ b/server/uiActions.go @@ -54,6 +54,8 @@ var customFieldForBillableHours string var timeEntriesSchema map[string]interface{} +var subscribedChannelID string + func OpAuth(p plugin.MattermostPlugin, r *http.Request, pluginURL string) { body, _ := io.ReadAll(r.Body) var jsonBody map[string]interface{} @@ -714,12 +716,48 @@ func showTimeLogSel(p plugin.MattermostPlugin, w http.ResponseWriter, channelID _, _ = p.API.UpdatePost(post) } +func NotificationSubscribe(p plugin.MattermostPlugin, w http.ResponseWriter, r *http.Request) { + body, _ := io.ReadAll(r.Body) + var jsonBody map[string]interface{} + _ = json.Unmarshal(body, &jsonBody) + subscribedChannelID = jsonBody["channel_id"].(string) + user, _ := p.API.GetUserByUsername(opBot) + post := getUpdatePostMsg(user.Id, subscribedChannelID, messages.SubscribeMsg) + _, _ = p.API.UpdatePost(post) + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + _, _ = w.Write(body) + _ = respHTTP.Write(w) +} + func NotifyChannel(p plugin.MattermostPlugin, w http.ResponseWriter, r *http.Request) { body, _ := io.ReadAll(r.Body) + p.API.LogDebug("Request body from OpenProject Webhooks: ", string(body)) defer r.Body.Close() var opJSONRes Notification + user, _ := p.API.GetUserByUsername(opBot) _ = json.Unmarshal(body, &opJSONRes) - p.API.LogDebug("Request body from OpenProject Webhooks: ", opJSONRes) + if subscribedChannelID == "" { + p.API.LogDebug("Not subscribed to OpenProject notification webhook") + } else { + notificationType := strings.Split(opJSONRes.Action, ":")[0] + var post *model.Post + notificationMsg := "**OpenProject notification** " + switch notificationType { + case "time_entry": + notificationMsg += opJSONRes.Action + " by " + opJSONRes.TimeEntry.Links.User.Title + " for " + opJSONRes.TimeEntry.Links.WorkPackage.Title + " in " + opJSONRes.TimeEntry.Links.Project.Title + case "project": + notificationMsg += opJSONRes.Action + " : " + opJSONRes.Project.Links.Self.Title + case "work_package": + notificationMsg += opJSONRes.Action + " : " + opJSONRes.WorkPackage.Links.Self.Title + case "attachment": + notificationMsg += opJSONRes.Action + " : " + opJSONRes.Attachment.Links.Self.Title + default: + notificationMsg += opJSONRes.Action + } + post = getUpdatePostMsg(user.Id, subscribedChannelID, notificationMsg) + _, _ = p.API.UpdatePost(post) + } w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(200) _, _ = w.Write(body)