166 lines
4.6 KiB
Go
166 lines
4.6 KiB
Go
|
package index
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"html/template"
|
||
|
"net/http"
|
||
|
"strconv"
|
||
|
|
||
|
"git.kirsle.net/apps/gosocial/pkg/config"
|
||
|
"git.kirsle.net/apps/gosocial/pkg/log"
|
||
|
"git.kirsle.net/apps/gosocial/pkg/mail"
|
||
|
"git.kirsle.net/apps/gosocial/pkg/markdown"
|
||
|
"git.kirsle.net/apps/gosocial/pkg/models"
|
||
|
"git.kirsle.net/apps/gosocial/pkg/session"
|
||
|
"git.kirsle.net/apps/gosocial/pkg/templates"
|
||
|
)
|
||
|
|
||
|
// Contact or report a problem.
|
||
|
func Contact() http.HandlerFunc {
|
||
|
tmpl := templates.Must("contact.html")
|
||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
// Query and form POST parameters.
|
||
|
var (
|
||
|
intent = r.FormValue("intent")
|
||
|
subject = r.FormValue("subject")
|
||
|
title = "Contact Us"
|
||
|
message = r.FormValue("message")
|
||
|
replyTo = r.FormValue("email")
|
||
|
tableID int
|
||
|
tableName string
|
||
|
tableLabel string // front-end user feedback about selected report item
|
||
|
messageRequired = true // unless we have a table ID to work with
|
||
|
success = "Thank you for your feedback! Your message has been delivered to the website administrators."
|
||
|
)
|
||
|
|
||
|
// For report intents: ID of the user, photo, message, etc.
|
||
|
tableID, _ = strconv.Atoi(r.FormValue("id"))
|
||
|
if tableID > 0 {
|
||
|
messageRequired = false
|
||
|
}
|
||
|
|
||
|
// In what context is the ID given?
|
||
|
if subject != "" && tableID > 0 {
|
||
|
switch subject {
|
||
|
case "report.user":
|
||
|
tableName = "users"
|
||
|
if user, err := models.GetUser(uint64(tableID)); err == nil {
|
||
|
tableLabel = fmt.Sprintf(`User account "%s"`, user.Username)
|
||
|
} else {
|
||
|
log.Error("/contact: couldn't produce table label for user %d: %s", tableID, err)
|
||
|
}
|
||
|
case "report.photo":
|
||
|
tableName = "photos"
|
||
|
|
||
|
// Find this photo and the user associated.
|
||
|
if pic, err := models.GetPhoto(uint64(tableID)); err == nil {
|
||
|
if user, err := models.GetUser(pic.UserID); err == nil {
|
||
|
tableLabel = fmt.Sprintf(`A profile photo of user account "%s"`, user.Username)
|
||
|
} else {
|
||
|
log.Error("/contact: couldn't produce table label for user %d: %s", tableID, err)
|
||
|
}
|
||
|
} else {
|
||
|
log.Error("/contact: couldn't produce table label for photo %d: %s", tableID, err)
|
||
|
}
|
||
|
case "report.message":
|
||
|
tableName = "messages"
|
||
|
tableLabel = "Direct Message conversation"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// On POST: take what we have now and email the admins.
|
||
|
if r.Method == http.MethodPost {
|
||
|
// Look up the current user, in case logged in.
|
||
|
currentUser, err := session.CurrentUser(r)
|
||
|
if err == nil {
|
||
|
replyTo = currentUser.Email
|
||
|
}
|
||
|
|
||
|
// Store feedback in the database.
|
||
|
fb := &models.Feedback{
|
||
|
Intent: intent,
|
||
|
Subject: subject,
|
||
|
Message: message,
|
||
|
TableName: tableName,
|
||
|
TableID: uint64(tableID),
|
||
|
}
|
||
|
|
||
|
if currentUser != nil && currentUser.ID > 0 {
|
||
|
fb.UserID = currentUser.ID
|
||
|
} else if replyTo != "" {
|
||
|
fb.ReplyTo = replyTo
|
||
|
}
|
||
|
|
||
|
if err := models.CreateFeedback(fb); err != nil {
|
||
|
session.FlashError(w, r, "Couldn't save feedback: %s", err)
|
||
|
templates.Redirect(w, r.URL.Path)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// Email the admins.
|
||
|
if err := mail.Send(mail.Message{
|
||
|
To: config.Current.AdminEmail,
|
||
|
Subject: "User Feedback: " + title,
|
||
|
Template: "email/contact_admin.html",
|
||
|
Data: map[string]interface{}{
|
||
|
"Title": title,
|
||
|
"Intent": intent,
|
||
|
"Subject": subject,
|
||
|
"Message": template.HTML(markdown.Render(message)),
|
||
|
"TableName": tableName,
|
||
|
"TableID": tableID,
|
||
|
"CurrentUser": currentUser,
|
||
|
"ReplyTo": replyTo,
|
||
|
"BaseURL": config.Current.BaseURL,
|
||
|
"AdminURL": config.Current.BaseURL + "/admin/feedback",
|
||
|
},
|
||
|
}); err != nil {
|
||
|
log.Error("/contact page: couldn't send email: %s", err)
|
||
|
}
|
||
|
|
||
|
session.Flash(w, r, success)
|
||
|
templates.Redirect(w, r.URL.Path)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// Default intent = contact
|
||
|
if intent == "report" {
|
||
|
title = "Report a Problem"
|
||
|
} else {
|
||
|
intent = "contact"
|
||
|
}
|
||
|
|
||
|
// Validate the subject.
|
||
|
if subject != "" {
|
||
|
var found bool
|
||
|
for _, group := range config.ContactUsChoices {
|
||
|
for _, opt := range group.Options {
|
||
|
if opt.Value == subject {
|
||
|
found = true
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if !found {
|
||
|
subject = ""
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var vars = map[string]interface{}{
|
||
|
"Intent": intent,
|
||
|
"TableID": tableID,
|
||
|
"TableLabel": tableLabel,
|
||
|
"Subject": subject,
|
||
|
"PageTitle": title,
|
||
|
"Subjects": config.ContactUsChoices,
|
||
|
"Message": message,
|
||
|
"MessageRequired": messageRequired,
|
||
|
}
|
||
|
if err := tmpl.Execute(w, r, vars); err != nil {
|
||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||
|
return
|
||
|
}
|
||
|
})
|
||
|
}
|