package barertc import ( "fmt" "net/http" "code.nonshy.com/nonshy/website/pkg/config" "code.nonshy.com/nonshy/website/pkg/controller/api" "code.nonshy.com/nonshy/website/pkg/log" "code.nonshy.com/nonshy/website/pkg/mail" "code.nonshy.com/nonshy/website/pkg/models" ) // WebhookRequest is a JSON request wrapper around all webhook messages. type WebhookRequest struct { Action string APIKey string // Relevant body per request. Report WebhookRequestReport `json:",omitempty"` } // WebhookRequestReport is the body for 'report' webhook messages. type WebhookRequestReport struct { FromUsername string AboutUsername string Channel string Timestamp string Reason string Message string Comment string } // Report webhook controller. func Report() http.HandlerFunc { // Response JSON schema. type Response struct { OK bool `json:"OK"` Error string `json:"error,omitempty"` } return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { api.SendJSON(w, http.StatusNotAcceptable, Response{ Error: "POST method only", }) return } // Parse request payload. var req WebhookRequest if err := api.ParseJSON(r, &req); err != nil { api.SendJSON(w, http.StatusBadRequest, Response{ Error: fmt.Sprintf("Error with request payload: %s", err), }) return } // Validate the AdminAPIKey. if req.APIKey != config.Current.CronAPIKey { api.SendJSON(w, http.StatusForbidden, Response{ Error: "Invalid API Key", }) return } // Get the report out. report := req.Report if report.Comment == "" { report.Comment = "(no comment)" } log.Debug("Got chat report: %+v", report) // Create an admin Feedback model. fb := &models.Feedback{ Intent: "report", Subject: "report.chat", Message: fmt.Sprintf( "A message was reported on the chat room!\n\n"+ "* From username: [%s](/u/%s)\n"+ "* About username: [%s](/u/%s)\n"+ "* Channel: **%s**\n"+ "* Timestamp: %s\n"+ "* Classification: %s\n"+ "* User comment: %s\n\n"+ "- - - - -\n\n"+ "The reported message on chat was:\n\n%s", report.FromUsername, report.FromUsername, report.AboutUsername, report.AboutUsername, report.Channel, report.Timestamp, report.Reason, report.Comment, report.Message, ), } // Get the Reply-To user if possible. currentUser, err := models.FindUser(report.FromUsername) if err == nil { fb.UserID = currentUser.ID } else { currentUser = nil } // Save the feedback. if err := models.CreateFeedback(fb); err != nil { log.Error("Couldn't save feedback from BareRTC report endpoint: %s", err) } // Email the admins. if err := mail.Send(mail.Message{ To: config.Current.AdminEmail, Subject: "User Feedback: Chat Room Report", Template: "email/contact_admin.html", Data: map[string]interface{}{ "Title": "Chat Room Report", "Intent": fb.Intent, "Subject": fb.Subject, "Message": fb.Message, "CurrentUser": currentUser, "BaseURL": config.Current.BaseURL, "AdminURL": config.Current.BaseURL + "/admin/feedback", }, }); err != nil { log.Error("/v1/barertc/report page: couldn't send email: %s", err) } // Send success response. api.SendJSON(w, http.StatusOK, Response{ OK: true, }) }) }