Documentation

Index

Constants

View Source
const (
	UsersCollection         = "users"
	ChannelCollection       = "channels"
	ChannelCheckCollection  = "check"
	ChannelMemberCollection = "members"
	DiscordGuildCollection  = "guilds"
	PrivateCollection       = "private"
	DMTemplateCollection    = "dm-templates"
)

These are names for Firestore collections. For preventing dumb typos!

Variables

View Source
var (
	// ErrDiscordTokenInvalid denotes that an OAuth token has expired or been revoked
	ErrDiscordTokenInvalid = errors.New("Discord token expired or revoked")

	// ErrDiscordTokenNotFound denotes that an OAuth token has been removed
	ErrDiscordTokenNotFound = errors.New("Discord token removed")

	// ErrYouTubeTokenInvalid denotes that an OAuth token has expired or been revoked
	ErrYouTubeTokenInvalid = errors.New("YouTube token expired or revoked")

	// ErrYouTubeInvalidGrant denotes an ephemeral invalid_grant error that can mean anything, really
	ErrYouTubeInvalidGrant = errors.New("generic invalid_grant error")

	// ErrYouTubeUserGone
	ErrYouTubeUserUnavailable = errors.New("YouTube user account closed or suspended")
)

Functions

func CheckChannelMembership

func CheckChannelMembership(
	ctx context.Context, fs *firestore.Client,
	options *CheckChannelMembershipOptions,
) (isMember bool, err error)

CheckChannelMembership checks a user's membership against a channel.

func DeleteUser

func DeleteUser(ctx context.Context, fs *firestore.Client, userID string) (err error)

DeleteUser removes all traces of a user.

func GetDiscordHTTPClient

func GetDiscordHTTPClient(ctx context.Context, fs *firestore.Client, userID string) (client *http.Client, err error)

GetDiscordHTTPClient creates a Discord HTTP client for a user.

func GetYouTubeService

func GetYouTubeService(ctx context.Context, fs *firestore.Client, userID string) (svc *youtube.Service, err error)

GetYouTubeService initializes a YouTube service for a user.

func GetYoutubeServerService

func GetYoutubeServerService(ctx context.Context, fs *firestore.Client) (svc *youtube.Service, err error)

GetYoutubeServerService initializes a YouTube service using the project API key.

func RefreshDiscordGuilds

func RefreshDiscordGuilds(ctx context.Context, fs *firestore.Client, dg *discordgo.Session) error

RefreshDiscordGuilds updates transient Discord guild data.

func RefreshYouTubeChannels

func RefreshYouTubeChannels(ctx context.Context, fs *firestore.Client, yt *youtube.Service) error

RefreshYouTubeChannels updates transient YouTube channel data.

func ReloadDiscordGuilds

func ReloadDiscordGuilds(
	ctx context.Context, fs *firestore.Client, userID string,
) (candidateChannels []*firestore.DocumentRef, err error)

ReloadDiscordGuilds reloads Discord guilds for a user and returns the new candidate channels. Results usually piped into CheckChannelMembership().

func RevokeYouTubeAccess

func RevokeYouTubeAccess(ctx context.Context, fs *firestore.Client, userID string) error

RevokeYouTubeAccess removes any and all YouTube stuff from a user ID.

func SetUserMemberships

func SetUserMemberships(
	ctx context.Context, fs *firestore.Client, userID string,
	verifiedMemberships map[string]time.Time,
) error

SetUserMemberships sets user memberships in the appropriate places across Firestore.

Types

type Channel

type Channel struct {
	ChannelID,
	ChannelTitle,
	Thumbnail string
}

Channel defines a YouTube channel whose membership we might check. fs: channels/{slug}

type ChannelCheck

type ChannelCheck struct {
	VideoID string
}

ChannelCheck defines channel membership check criteria. fs: channels/{slug}/check/check

type ChannelMember

type ChannelMember struct {
	DiscordID string
	Timestamp time.Time
}

ChannelMember defines channel membership. fs: channels/{slug}/members/{UserID}

type CheckChannelMembershipOptions

type CheckChannelMembershipOptions struct {
	UserID      string
	UserService *youtube.Service

	ChannelSlug              string
	ChannelMembershipVideoID string

	Logger *zerolog.Logger // optional logging context
}

CheckChannelMembershipOptions is the multiselect-y options struct for CheckChannelMembership

type DMTemplate

type DMTemplate struct {
	Name string
	Body string
}

DMTemplate is a message template that can be sent out (en masse). fs: dm-templates/[name]

type DMTemplateData

type DMTemplateData struct {
	User  *DiscordIdentity
	Extra map[string]interface{}
}

DMTemplateData is the data passed in a text/template.Execute() call with a DMTemplate.

type DiscordGuild

type DiscordGuild struct {
	ID                    string
	Name                  string
	LastMembershipRefresh time.Time `json:",omitempty"`
	AuditLogChannelID     string
	BCP47                 string            `json:",omitempty"`
	MembershipRoles       map[string]string // channelSlug -> roleID. Please never leave RoleID empty.
	APIOnly               bool              `json:",omitempty"` // denotes an API-only guild
}

DiscordGuild defines loaded Discord guild associations. fs: guilds/{guildID]

type DiscordIdentity

type DiscordIdentity struct {
	UserID            string
	Username          string
	Discriminator     string
	YoutubeChannelID  string                   // the user's linked Youtube Channel ID
	CandidateChannels []*firestore.DocumentRef // possibly relevant YouTube channels
	Memberships       []*firestore.DocumentRef // verified memberships
	LastRefreshed     time.Time                `json:",omitempty"`
}

DiscordIdentity is saved to Firestore in the `DiscordIdentityCollection` collection. fs: users/{UserID}

type EnforceMembershipsOptions

type EnforceMembershipsOptions struct {
	ReloadDiscordGuilds       bool
	OnlyChannelSlug           string
	RemoveInvalidDiscordToken bool // removes users with permanently invalid (revoked, de-scoped) tokens
	RemoveInvalidYouTubeToken bool // removes users with permanently invalid (revoked, de-scoped) tokens
	Apply                     bool // apply changes
	UserIDs                   []string

	// only refresh memberships that were validated before this time
	RefreshBefore time.Time

	// amount of worker threads to use (default is 1)
	NumWorkers uint
}

EnforceMembershipsOptions is the multiselect-y options struct for EnforceMemberships

type EnforceMembershipsResult

type EnforceMembershipsResult struct {
	UserCount uint

	// Number of users that have disconnected/removed their YouTube or Discord accounts outside of the main website UI.
	UsersDisconnected uint

	// Number of membership lapses during enforcement
	MembershipsLapsed uint

	// Number of memberships added during enforcement
	MembershipsAdded uint

	// Number of memberships re-confirmed during enforcement
	MembershipsReconfirmed uint
}

EnforceMembershipsResult contains metrics useful for monitoring/debugging/fun.

func EnforceMemberships

func EnforceMemberships(ctx context.Context, fs *firestore.Client, options *EnforceMembershipsOptions) (result EnforceMembershipsResult, err error)

EnforceMemberships checks all users' memberships against candidate channels.