BareRTC user profile webhook

face-detect
Noah Petherbridge 2023-10-07 13:24:07 -07:00
parent 95212970ff
commit eb571e1933
3 changed files with 113 additions and 2 deletions

View File

@ -3,6 +3,7 @@ package barertc
import (
"fmt"
"net/http"
"strings"
"code.nonshy.com/nonshy/website/pkg/config"
"code.nonshy.com/nonshy/website/pkg/controller/api"
@ -17,6 +18,9 @@ type WebhookRequest struct {
// Relevant body per request.
Report WebhookRequestReport `json:",omitempty"`
// Optional params per request.
Username string `json:",omitempty"` // e.g. for profile webhook
}
// WebhookRequestReport is the body for 'report' webhook messages.
@ -35,8 +39,8 @@ func Report() http.HandlerFunc {
// Response JSON schema.
type Response struct {
OK bool `json:"OK"`
Error string `json:"error,omitempty"`
OK bool
Error string `json:",omitempty"`
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@ -124,3 +128,101 @@ func Report() http.HandlerFunc {
})
})
}
// Profile webhook controller to fetch more profile details for a user.
func Profile() http.HandlerFunc {
// Response JSON schema.
type ProfileField struct {
Name string
Value string
}
type Response struct {
OK bool
Error string `json:",omitempty"`
ProfileFields []ProfileField
}
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 Reply-To user if possible.
currentUser, err := models.FindUser(req.Username)
if err != nil {
api.SendJSON(w, http.StatusForbidden, Response{
Error: "Username Not Found",
})
return
}
// Populate their profile fields.
var maritalStatus = currentUser.GetProfileFieldOr("marital_status", "n/a")
if relationshipType := currentUser.GetProfileField("relationship_type"); relationshipType != "" {
maritalStatus += fmt.Sprintf(" (%s)", relationshipType)
}
var gender = currentUser.GetProfileFieldOr("gender", "n/a")
if pronouns := currentUser.GetProfileField("pronouns"); pronouns != "" {
gender += fmt.Sprintf(" (%s)", pronouns)
}
var resp = Response{
OK: true,
ProfileFields: []ProfileField{
{
Name: "Age",
Value: currentUser.GetDisplayAge(),
},
{
Name: "Gender",
Value: gender,
},
{
Name: "City",
Value: currentUser.GetProfileFieldOr("city", "n/a"),
},
{
Name: "Job",
Value: currentUser.GetProfileFieldOr("job", "n/a"),
},
{
Name: "Marital status",
Value: maritalStatus,
},
{
Name: "Orientation",
Value: currentUser.GetProfileFieldOr("orientation", "n/a"),
},
{
Name: "Here for",
Value: strings.Join(strings.Split(currentUser.GetProfileFieldOr("here_for", "n/a"), ","), ", "),
},
},
}
// Send success response.
api.SendJSON(w, http.StatusOK, resp)
})
}

View File

@ -528,6 +528,14 @@ func (u *User) GetProfileField(name string) string {
return ""
}
// GetProfileFieldOr returns a default string (like "n/a") if the profile field is not set.
func (u *User) GetProfileFieldOr(name, or string) string {
if value := u.GetProfileField(name); value != "" {
return value
}
return or
}
// GetDisplayAge returns the user's age dependent on their hide-my-age setting.
func (u *User) GetDisplayAge() string {
if !u.Birthdate.IsZero() && u.GetProfileField("hide_age") != "true" {

View File

@ -104,6 +104,7 @@ func New() http.Handler {
mux.Handle("/v1/notifications/delete", middleware.LoginRequired(api.ClearNotification()))
mux.Handle("/v1/comment-photos/remove-orphaned", api.RemoveOrphanedCommentPhotos())
mux.Handle("/v1/barertc/report", barertc.Report())
mux.Handle("/v1/barertc/profile", barertc.Profile())
// Static files.
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(config.StaticPath))))