mirror of
https://github.com/knadh/listmonk.git
synced 2024-09-20 07:16:33 +08:00
Compare commits
6 commits
ec17932a0e
...
8d8534fa19
Author | SHA1 | Date | |
---|---|---|---|
8d8534fa19 | |||
550cd3e1f8 | |||
dccbdf90f3 | |||
681f3073c6 | |||
d24a3e787f | |||
23a4a7a492 |
|
@ -48,7 +48,7 @@ __________________
|
|||
|
||||
|
||||
## Developers
|
||||
listmonk is a free and open source software licensed under AGPLv3. If you are interested in contributing, refer to the [developer setup](https://listmonk.app/docs/developer-setup). The backend is written in Go and the frontend is Vue with Buefy for UI.
|
||||
listmonk is free and open source software licensed under AGPLv3. If you are interested in contributing, refer to the [developer setup](https://listmonk.app/docs/developer-setup). The backend is written in Go and the frontend is Vue with Buefy for UI.
|
||||
|
||||
|
||||
## License
|
||||
|
|
|
@ -196,6 +196,11 @@ func initHTTPHandlers(e *echo.Echo, app *App) {
|
|||
"subUUID"))
|
||||
e.POST("/subscription/wipe/:subUUID", validateUUID(subscriberExists(handleWipeSubscriberData),
|
||||
"subUUID"))
|
||||
|
||||
// one-click unsubscribe from list
|
||||
e.POST("/unsubscribe/:subUUID/:listUUID", unsubscribeList)
|
||||
e.GET("/unsubscribe/:subUUID/:listUUID", noIndex(validateUUID(subscriberExists(handleListSubscriptionPage), "subUUID", "listUUID")))
|
||||
|
||||
e.GET("/link/:linkUUID/:campUUID/:subUUID", noIndex(validateUUID(handleLinkRedirect,
|
||||
"linkUUID", "campUUID", "subUUID")))
|
||||
e.GET("/campaign/:campUUID/:subUUID", noIndex(validateUUID(handleViewCampaignMessage,
|
||||
|
|
|
@ -730,3 +730,60 @@ func processSubForm(c echo.Context) (bool, error) {
|
|||
|
||||
return hasOptin, nil
|
||||
}
|
||||
|
||||
func unsubscribeList(c echo.Context) error {
|
||||
var (
|
||||
app = c.Get("app").(*App)
|
||||
subUUID = c.Param("subUUID")
|
||||
listUUID = c.Param("listUUID")
|
||||
)
|
||||
|
||||
// Get the subscriber ID from the UUID.
|
||||
sub, err := app.core.GetSubscriber(0, subUUID, "")
|
||||
if err != nil {
|
||||
return c.String(http.StatusInternalServerError, "Error processing request")
|
||||
}
|
||||
|
||||
// Unsubscribe from the list.
|
||||
if err := app.core.UnsubscribeLists([]int{sub.ID}, nil, []string{listUUID}); err != nil {
|
||||
return c.String(http.StatusInternalServerError, "Error processing request")
|
||||
}
|
||||
|
||||
return c.String(http.StatusOK, "You have been unsubscribed successfully")
|
||||
}
|
||||
|
||||
func handleListSubscriptionPage(c echo.Context) error {
|
||||
var (
|
||||
app = c.Get("app").(*App)
|
||||
subUUID = c.Param("subUUID")
|
||||
listUUID = c.Param("listUUID")
|
||||
)
|
||||
|
||||
// Get the subscriber ID from the UUID.
|
||||
sub, err := app.core.GetSubscriber(0, subUUID, "")
|
||||
if err != nil {
|
||||
return c.Render(http.StatusInternalServerError, tplMessage,
|
||||
makeMsgTpl(app.i18n.T("public.errorTitle"), "", app.i18n.Ts("public.errorProcessingRequest")))
|
||||
}
|
||||
|
||||
// Check if the subscriber is already unsubscribed from the list
|
||||
subscription, err := app.core.GetSubscriptions(0, listUUID, true)
|
||||
if err != nil {
|
||||
return c.Render(http.StatusInternalServerError, tplMessage,
|
||||
makeMsgTpl(app.i18n.T("public.errorTitle"), "", app.i18n.T("public.errorProcessingRequest")))
|
||||
}
|
||||
|
||||
if len(subscription) > 0 && subscription[0].SubscriptionStatus.String == models.SubscriptionStatusUnsubscribed {
|
||||
return c.Render(http.StatusOK, tplMessage,
|
||||
makeMsgTpl(app.i18n.T("public.unsubbedTitle"), "", app.i18n.T("public.unsubbedAlreadyInfo")))
|
||||
}
|
||||
|
||||
// Unsubscribe from the list.
|
||||
if err := app.core.UnsubscribeLists([]int{sub.ID}, nil, []string{listUUID}); err != nil {
|
||||
return c.Render(http.StatusInternalServerError, tplMessage,
|
||||
makeMsgTpl(app.i18n.T("public.errorTitle"), "", app.i18n.T("public.errorProcessingRequest")))
|
||||
}
|
||||
|
||||
return c.Render(http.StatusOK, tplMessage,
|
||||
makeMsgTpl(app.i18n.T("public.unsubbedTitle"), "", app.i18n.T("public.unsubbedInfo")))
|
||||
}
|
||||
|
|
|
@ -92,6 +92,7 @@ func handleQuerySubscribers(c echo.Context) error {
|
|||
subStatus = c.FormValue("subscription_status")
|
||||
orderBy = c.FormValue("order_by")
|
||||
order = c.FormValue("order")
|
||||
noLists = c.FormValue("no_lists") == "true"
|
||||
out models.PageResults
|
||||
)
|
||||
|
||||
|
@ -101,7 +102,7 @@ func handleQuerySubscribers(c echo.Context) error {
|
|||
return echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("globals.messages.invalidID"))
|
||||
}
|
||||
|
||||
res, total, err := app.core.QuerySubscribers(query, listIDs, subStatus, order, orderBy, pg.Offset, pg.Limit)
|
||||
res, total, err := app.core.QuerySubscribers(query, listIDs, subStatus, order, orderBy, pg.Offset, pg.Limit, noLists)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ Retrieve all subscribers.
|
|||
| order | string | | Sorting order: ASC for ascending, DESC for descending. |
|
||||
| page | number | | Page number for paginated results. |
|
||||
| per_page | number | | Results per page. Set as 'all' for all results. |
|
||||
| no_lists | bool | | The lists to which the subscriber is registered are not displayed. |
|
||||
|
||||
##### Example Request
|
||||
|
||||
|
|
|
@ -353,6 +353,7 @@
|
|||
"public.unsubHelp": "Do you want to unsubscribe from this mailing list?",
|
||||
"public.unsubTitle": "Unsubscribe",
|
||||
"public.unsubbedInfo": "You have unsubscribed successfully.",
|
||||
"public.unsubbedAlreadyInfo": "You have already unsubscribed successfully.",
|
||||
"public.unsubbedTitle": "Unsubscribed",
|
||||
"public.unsubscribeTitle": "Unsubscribe from mailing list",
|
||||
"settings.appearance.adminHelp": "Custom CSS to apply to the admin UI.",
|
||||
|
|
|
@ -352,6 +352,7 @@
|
|||
"public.unsubHelp": "Deseja cancelar a inscrição desta lista de e-mail?",
|
||||
"public.unsubTitle": "Cancelar inscrição",
|
||||
"public.unsubbedInfo": "Você cancelou a inscrição com sucesso.",
|
||||
"public.unsubbedAlreadyInfo": "Você já cancelou a inscrição com sucesso.",
|
||||
"public.unsubbedTitle": "Inscrição cancelada",
|
||||
"public.unsubscribeTitle": "Cancelar inscrição na lista de e-mails",
|
||||
"settings.appearance.adminHelp": "CSS customizado para aplicar na admin UI.",
|
||||
|
|
|
@ -66,7 +66,7 @@ func (c *Core) GetSubscribersByEmail(emails []string) (models.Subscribers, error
|
|||
}
|
||||
|
||||
// QuerySubscribers queries and returns paginated subscrribers based on the given params including the total count.
|
||||
func (c *Core) QuerySubscribers(query string, listIDs []int, subStatus string, order, orderBy string, offset, limit int) (models.Subscribers, int, error) {
|
||||
func (c *Core) QuerySubscribers(query string, listIDs []int, subStatus string, order, orderBy string, offset, limit int, noLists bool) (models.Subscribers, int, error) {
|
||||
// There's an arbitrary query condition.
|
||||
cond := ""
|
||||
if query != "" {
|
||||
|
@ -117,12 +117,13 @@ func (c *Core) QuerySubscribers(query string, listIDs []int, subStatus string, o
|
|||
}
|
||||
|
||||
// Lazy load lists for each subscriber.
|
||||
if !noLists {
|
||||
if err := out.LoadLists(c.q.GetSubscriberListsLazy); err != nil {
|
||||
c.log.Printf("error fetching subscriber lists: %v", err)
|
||||
return nil, 0, echo.NewHTTPError(http.StatusInternalServerError,
|
||||
c.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.subscribers}", "error", pqErrMsg(err)))
|
||||
}
|
||||
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue