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/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 } // Look up the AboutUser ID if possible. targetUser, err := models.FindUser(report.AboutUsername) if err == nil { fb.TableName = "users" fb.TableID = targetUser.ID } else { log.Error("BareRTC Chat Feedback: couldn't find user ID for AboutUsername=%s: %s", report.AboutUsername, err) } // Save the feedback. if err := models.CreateFeedback(fb); err != nil { log.Error("Couldn't save feedback from BareRTC report endpoint: %s", err) } // Send success response. api.SendJSON(w, http.StatusOK, Response{ OK: true, }) }) }