mirror of
https://github.com/knadh/listmonk.git
synced 2025-12-06 00:10:03 +01:00
137 lines
3.8 KiB
Go
137 lines
3.8 KiB
Go
package models
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"strings"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
"github.com/jmoiron/sqlx/types"
|
|
"github.com/lib/pq"
|
|
null "gopkg.in/volatiletech/null.v6"
|
|
)
|
|
|
|
const (
|
|
SubscriberStatusEnabled = "enabled"
|
|
SubscriberStatusDisabled = "disabled"
|
|
SubscriberStatusBlockListed = "blocklisted"
|
|
|
|
SubscriptionStatusUnconfirmed = "unconfirmed"
|
|
SubscriptionStatusConfirmed = "confirmed"
|
|
SubscriptionStatusUnsubscribed = "unsubscribed"
|
|
)
|
|
|
|
// Subscribers represents a slice of Subscriber.
|
|
type Subscribers []Subscriber
|
|
|
|
// Subscriber represents an e-mail subscriber.
|
|
type Subscriber struct {
|
|
Base
|
|
|
|
UUID string `db:"uuid" json:"uuid"`
|
|
Email string `db:"email" json:"email" form:"email"`
|
|
Name string `db:"name" json:"name" form:"name"`
|
|
Attribs JSON `db:"attribs" json:"attribs"`
|
|
Status string `db:"status" json:"status"`
|
|
Lists types.JSONText `db:"lists" json:"lists"`
|
|
}
|
|
|
|
type subLists struct {
|
|
SubscriberID int `db:"subscriber_id"`
|
|
Lists types.JSONText `db:"lists"`
|
|
}
|
|
|
|
// GetIDs returns the list of subscriber IDs.
|
|
func (subs Subscribers) GetIDs() []int {
|
|
IDs := make([]int, len(subs))
|
|
for i, c := range subs {
|
|
IDs[i] = c.ID
|
|
}
|
|
|
|
return IDs
|
|
}
|
|
|
|
// LoadLists lazy loads the lists for all the subscribers
|
|
// in the Subscribers slice and attaches them to their []Lists property.
|
|
func (subs Subscribers) LoadLists(stmt *sqlx.Stmt) error {
|
|
var sl []subLists
|
|
err := stmt.Select(&sl, pq.Array(subs.GetIDs()))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(subs) != len(sl) {
|
|
return errors.New("campaign stats count does not match")
|
|
}
|
|
|
|
for i, s := range sl {
|
|
if s.SubscriberID == subs[i].ID {
|
|
subs[i].Lists = s.Lists
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// FirstName splits the name by spaces and returns the first chunk
|
|
// of the name that's greater than 2 characters in length, assuming
|
|
// that it is the subscriber's first name.
|
|
func (s Subscriber) FirstName() string {
|
|
for _, s := range strings.Split(s.Name, " ") {
|
|
if len(s) > 2 {
|
|
return s
|
|
}
|
|
}
|
|
|
|
return s.Name
|
|
}
|
|
|
|
// LastName splits the name by spaces and returns the last chunk
|
|
// of the name that's greater than 2 characters in length, assuming
|
|
// that it is the subscriber's last name.
|
|
func (s Subscriber) LastName() string {
|
|
chunks := strings.Split(s.Name, " ")
|
|
for i := len(chunks) - 1; i >= 0; i-- {
|
|
chunk := chunks[i]
|
|
if len(chunk) > 2 {
|
|
return chunk
|
|
}
|
|
}
|
|
|
|
return s.Name
|
|
}
|
|
|
|
// Subscription represents a list attached to a subscriber.
|
|
type Subscription struct {
|
|
List
|
|
SubscriptionStatus null.String `db:"subscription_status" json:"subscription_status"`
|
|
SubscriptionCreatedAt null.String `db:"subscription_created_at" json:"subscription_created_at"`
|
|
Meta json.RawMessage `db:"meta" json:"meta"`
|
|
}
|
|
|
|
// SubscriberExport represents a subscriber record that is exported to raw data.
|
|
type SubscriberExport struct {
|
|
Base
|
|
|
|
UUID string `db:"uuid" json:"uuid"`
|
|
Email string `db:"email" json:"email"`
|
|
Name string `db:"name" json:"name"`
|
|
Attribs string `db:"attribs" json:"attribs"`
|
|
Status string `db:"status" json:"status"`
|
|
}
|
|
|
|
// SubscriberExportProfile represents a subscriber's collated data in JSON for export.
|
|
type SubscriberExportProfile struct {
|
|
Email string `db:"email" json:"-"`
|
|
Profile json.RawMessage `db:"profile" json:"profile,omitempty"`
|
|
Subscriptions json.RawMessage `db:"subscriptions" json:"subscriptions,omitempty"`
|
|
CampaignViews json.RawMessage `db:"campaign_views" json:"campaign_views,omitempty"`
|
|
LinkClicks json.RawMessage `db:"link_clicks" json:"link_clicks,omitempty"`
|
|
}
|
|
|
|
// SubscriberActivity represents a subscriber's campaign views and link clicks for the Activity tab.
|
|
type SubscriberActivity struct {
|
|
CampaignViews json.RawMessage `db:"campaign_views" json:"campaign_views"`
|
|
LinkClicks json.RawMessage `db:"link_clicks" json:"link_clicks"`
|
|
}
|