Back to

Package common

Latest Go to latest

The highest tagged major version is .

Published: Nov 13, 2019 | License: MIT | Module:


this package provides core functinality to yagpdb, important security stuff here



const CoreServerConfDBSchema = "" /* 237 byte string literal not displayed */


var (
	ErrNotFound    = errors.New("Not found")
	CacheKeyPrefix = "cache_"

	Cache *ccache.Cache
var (
	VERSION = "unknown"

	GORM *gorm.DB
	PQ   *sql.DB

	RedisPool *basicredispool.Pool

	BotSession *discordgo.Session
	BotUser    *discordgo.User

	RedisPoolSize = 10

	Statsd *statsd.Client

	Testing = os.Getenv("YAGPDB_TESTING") != ""

	CurrentRunCounter int64

	NodeID string
var (
	ConfClientID     = config.RegisterOption("yagpdb.clientid", "Client ID of the discord application", nil)
	ConfClientSecret = config.RegisterOption("yagpdb.clientsecret", "Client Secret of the discord application", nil)
	ConfBotToken     = config.RegisterOption("yagpdb.bottoken", "Token of the bot user", nil)
	ConfHost         = config.RegisterOption("", "Host without the protocol, example:, used by the webserver", nil)
	ConfEmail        = config.RegisterOption("", "Email used when fetching lets encrypt certificate", "")

	ConfPQHost     = config.RegisterOption("yagpdb.pqhost", "Postgres host", "localhost")
	ConfPQUsername = config.RegisterOption("yagpdb.pqusername", "Postgres user", "postgres")
	ConfPQPassword = config.RegisterOption("yagpdb.pqpassword", "Postgres passoword", "")
	ConfPQDB       = config.RegisterOption("yagpdb.pqdb", "Postgres database", "yagpdb")
	ConfRedis      = config.RegisterOption("yagpdb.redis", "Redis address", "localhost:6379")

	ConfMaxCCR            = config.RegisterOption("yagpdb.max_ccr", "Maximum number of concurrent outgoing requests to discord", 25)
	ConfDisableKeepalives = config.RegisterOption("yagpdb.disable_keepalives", "" /* 134 byte string literal not displayed */, false)

	ConfDogStatsdAddress = config.RegisterOption("yagpdb.dogstatsdaddress", "dogstatsd address", "")

	BotOwners []int64
var (
	PluginCategoryCore       = &PluginCategory{Name: "Core", Order: 0}
	PluginCategoryModeration = &PluginCategory{Name: "Moderation", Order: 10}
	PluginCategoryMisc       = &PluginCategory{Name: "Misc", Order: 20}
	PluginCategoryFeeds      = &PluginCategory{Name: "Feeds", Order: 30}
var Adjectives = []string{ /* 1345 elements not displayed */

var AllInviteSources = append([]*InviteSource{DiscordInviteSource}, ThirdpartyDiscordSites...)
var CoreServerConfigCache = rcache.NewInt(coreServerConfigCacheFetcher, time.Minute)
var DiscordInviteSource = &InviteSource{
	Name:  "Discord",
	Regex: regexp.MustCompile(`(?i)(discord\.gg|discordapp\.com\/invite)(?:\/#)?\/([a-zA-Z0-9-]+)`),
var (
	ErrMaxLockAttemptsExceeded = errors.New("Max lock attempts exceeded")
var LinkRegex = regexp.MustCompile(`(http(s)?:\/\/)?(www\.)?[-a-zA-Z0-9@:%_\+~#=]{1,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)`)
var (
	Plugins []Plugin
var StringPerms = map[int]string{
	discordgo.PermissionReadMessages:       "Read Messages",
	discordgo.PermissionSendMessages:       "Send Messages",
	discordgo.PermissionSendTTSMessages:    "Send TTS Messages",
	discordgo.PermissionManageMessages:     "Manage Messages",
	discordgo.PermissionEmbedLinks:         "Embed Links",
	discordgo.PermissionAttachFiles:        "Attach Files",
	discordgo.PermissionReadMessageHistory: "Read Message History",
	discordgo.PermissionMentionEveryone:    "Mention Everyone",
	discordgo.PermissionVoiceConnect:       "Voice Connect",
	discordgo.PermissionVoiceSpeak:         "Voice Speak",
	discordgo.PermissionVoiceMuteMembers:   "Voice Mute Members",
	discordgo.PermissionVoiceDeafenMembers: "Voice Deafen Members",
	discordgo.PermissionVoiceMoveMembers:   "Voice Move Members",
	discordgo.PermissionVoiceUseVAD:        "Voice Use VAD",

	discordgo.PermissionCreateInstantInvite: "Create Instant Invite",
	discordgo.PermissionKickMembers:         "Kick Members",
	discordgo.PermissionBanMembers:          "Ban Members",
	discordgo.PermissionManageRoles:         "Manage Roles",
	discordgo.PermissionManageChannels:      "Manage Channels",
	discordgo.PermissionManageServer:        "Manage Server",
	discordgo.PermissionManageWebhooks:      "Manage Webhooks",
var ThirdpartyDiscordSites = []*InviteSource{
	&InviteSource{Name: "", Regex: regexp.MustCompile(`(?i)discord\.me\/.+`)},
	&InviteSource{Name: "", Regex: regexp.MustCompile(`(?i)invite\.gg\/.+`)},
	&InviteSource{Name: "", Regex: regexp.MustCompile(`(?i)discord\.io\/.+`)},
	&InviteSource{Name: "", Regex: regexp.MustCompile(`(?i)discord\.li\/.+`)},
	&InviteSource{Name: "", Regex: regexp.MustCompile(`(?i)disboard\.org\/server\/join\/.+`)},
	&InviteSource{Name: "", Regex: regexp.MustCompile(`(?i)discordy\.com\/server\.php`)},

func AddCPLogEntry

func AddCPLogEntry(user *discordgo.User, guild int64, args ...interface{})

func AddLogHook

func AddLogHook(hook logrus.Hook)

func AddRole

func AddRole(member *discordgo.Member, role int64, guildID int64) error

func AddRoleDS

func AddRoleDS(ms *dstate.MemberState, role int64) error

func BlockingLockRedisKey

func BlockingLockRedisKey(key string, maxTryDuration time.Duration, maxLockDur int) error

BlockingLockRedisKey blocks until it suceeded to lock the key

func BotIsOnGuild

func BotIsOnGuild(guildID int64) (bool, error)

func ConnectDatadog

func ConnectDatadog()

func ContainsInt64Slice

func ContainsInt64Slice(slice []int64, search int64) bool

func ContainsInt64SliceOneOf

func ContainsInt64SliceOneOf(slice []int64, search []int64) bool

ContainsInt64SliceOneOf returns true if slice contains one of search

func ContainsIntSlice

func ContainsIntSlice(slice []int, search int) bool

func ContainsStringSlice

func ContainsStringSlice(strs []string, search string) bool

func ContainsStringSliceFold

func ContainsStringSliceFold(strs []string, search string) bool

func ContextCoreConf

func ContextCoreConf(ctx context.Context) *models.CoreConfig

func CoreConfigSave

func CoreConfigSave(ctx context.Context, m *models.CoreConfig) error

func CutStringShort

func CutStringShort(s string, l int) string

CutStringShort stops a strinng at "l"-3 if it's longer than "l" and adds "..."

func DelayedMessageDelete

func DelayedMessageDelete(session *discordgo.Session, delay time.Duration, cID, mID int64)

DelayedMessageDelete Deletes a message after delay

func DiscordError

func DiscordError(err error) (code int, msg string)

DiscordError extracts the errorcode discord sent us

func ErrPQIsUniqueViolation

func ErrPQIsUniqueViolation(err error) bool

func ErrWithCaller

func ErrWithCaller(err error) error

func EscapeEveryoneHere

func EscapeEveryoneHere(s string, escapeEveryone, escapeHere bool) string

EscapeSpecialMentionsConditional Escapes an everyone mention, adding a zero width space between the '@' and rest

func EscapeSpecialMentions

func EscapeSpecialMentions(in string) string

EscapeSpecialMentions Escapes an everyone mention, adding a zero width space between the '@' and rest

func EscapeSpecialMentionsConditional

func EscapeSpecialMentionsConditional(s string, allowEveryone, allowHere bool, allowRoles []int64) string

EscapeSpecialMentionsConditional Escapes an everyone mention, adding a zero width space between the '@' and rest

func FallbackEmbed

func FallbackEmbed(embed *discordgo.MessageEmbed) string

func GenLocalIncrID

func GenLocalIncrID(guildID int64, key string) (int64, error)

GenLocalIncrID creates a new or incremements a existing local id incrememter used to have per guild id's

GenLocalIncrID is deprecated and GenLocalIncrIDPQ should be used instead

func GenLocalIncrIDPQ

func GenLocalIncrIDPQ(tx *sql.Tx, guildID int64, key string) (int64, error)

GenLocalIncrIDPQ creates a new or incremements a existing local id incrememter used to have per guild id's

GenLocalIncrIDPQ differs from GenLocalIncrID in that it uses postgres instead of redis

func GetActiveNodes

func GetActiveNodes() ([]string, error)

func GetBotToken

func GetBotToken() string

func GetCacheData

func GetCacheData(key string) (data []byte, err error)

Items in the cache expire after 1 min

func GetCacheDataJson

func GetCacheDataJson(key string, dest interface{}) error

func GetCoreServerConfCached

func GetCoreServerConfCached(guildID int64) *models.CoreConfig

func GetFixedPrefixLogger

func GetFixedPrefixLogger(prefix string) *logrus.Logger

func GetGuild

func GetGuild(guildID int64) (guild *discordgo.Guild, err error)

GetGuild returns the guild from guildid either from cache or api

func GetGuildChannels

func GetGuildChannels(guildID int64) (channels []*discordgo.Channel, err error)

GetGuildChannels returns the guilds channels either from cache or api

func GetJoinedServerCount

func GetJoinedServerCount() (int64, error)

func GetPluginLogger

func GetPluginLogger(plugin Plugin) *logrus.Logger

func GetRedisJson

func GetRedisJson(key string, out interface{}) error

GetRedisJson executes a get redis command and unmarshals the value into out

func HumanizeDuration

func HumanizeDuration(precision DurationFormatPrecision, in time.Duration) string

func HumanizePermissions

func HumanizePermissions(perms int64) (res []string)

func HumanizeTime

func HumanizeTime(precision DurationFormatPrecision, in time.Time) string

func Init

func Init() error

Initalizes all database connections, config loading and so on

func InitSchemas

func InitSchemas(name string, schemas ...string)

func InitTest

func InitTest()

func IsDiscordErr

func IsDiscordErr(err error, codes bool

IsDiscordErr returns true if this was a discord error and one of the codes matches

func IsNumber

func IsNumber(v interface{}) bool

func IsOwner

func IsOwner(userID int64) bool

func KeyGuild

func KeyGuild(guildID int64) string

func KeyGuildChannels

func KeyGuildChannels(guildID int64) string

func LoadConfig

func LoadConfig() (err error)

func LogIgnoreError

func LogIgnoreError(err error, msg string, data logrus.Fields)

func MultipleCmds

func MultipleCmds(cmds ...radix.CmdAction) error

func MustParseInt

func MustParseInt(s string) int64

func RandomAdjective

func RandomAdjective() string

func RegisterPlugin

func RegisterPlugin(plugin Plugin)

RegisterPlugin registers a plugin, should be called when the bot is starting up

func RemoveRole

func RemoveRole(member *discordgo.Member, role int64, guildID int64) error

func RemoveRoleDS

func RemoveRoleDS(ms *dstate.MemberState, role int64) error

func ReplaceServerInvites

func ReplaceServerInvites(msg string, guildID int64, replacement string) string

func RetrySendMessage

func RetrySendMessage(channel int64, msg interface{}, maxTries int) error

func SendEmbedWithFallback

func SendEmbedWithFallback(s *discordgo.Session, channelID int64, embed *discordgo.MessageEmbed) (*discordgo.Message, error)

func SendOwnerAlert

func SendOwnerAlert(msgf string, args ...interface{})

func SendTempMessage

func SendTempMessage(session *discordgo.Session, duration time.Duration, cID int64, msg string)

SendTempMessage sends a message that gets deleted after duration

func SetCacheData

func SetCacheData(key string, expire int, data []byte) error

Stores an entry in the cache and sets it to expire after expire

func SetCacheDataJson

func SetCacheDataJson(key string, expire int, data interface{}) error

Helper methods

func SetCacheDataJsonSimple

func SetCacheDataJsonSimple(key string, data interface{}) error

func SetCacheDataSimple

func SetCacheDataSimple(key string, data []byte) error

Stores an entry in the cache and sets it to expire after a minute

func SetLogFormatter

func SetLogFormatter(formatter logrus.Formatter)

func SetLoggingLevel

func SetLoggingLevel(level logrus.Level)

func SetRedisJson

func SetRedisJson(key string, value interface{}) error

SetRedisJson marshals the value and runs a set redis command for key

func SqlTX

func SqlTX(f func(tx *sql.Tx) error) error

helper for creating transactions

func TryLockRedisKey

func TryLockRedisKey(key string, maxDur int) (bool, error)

Locks the lock and if succeded sets it to expire after maxdur So that if someting went wrong its not locked forever

func UnlockRedisKey

func UnlockRedisKey(key string)

type CPLogEntry

type CPLogEntry struct {
	Timestamp int64  `json:"ts"`
	Action    string `json:"action"`

	TimestampString string `json:"-"`

func GetCPLogEntries

func GetCPLogEntries(guild int64) ([]*CPLogEntry, error)

type ContextHook

type ContextHook struct{}

func (ContextHook) Fire

func (hook ContextHook) Fire(entry *logrus.Entry) error

func (ContextHook) Levels

func (hook ContextHook) Levels() []logrus.Level

type ContextKey

type ContextKey int
const (
	ContextKeyRedis ContextKey = iota

type DurationFormatPrecision

type DurationFormatPrecision int
const (
	DurationPrecisionSeconds DurationFormatPrecision = iota

func (DurationFormatPrecision) FromSeconds

func (d DurationFormatPrecision) FromSeconds(in int64) int64

func (DurationFormatPrecision) String

func (d DurationFormatPrecision) String() string

type GORMLogger

type GORMLogger struct {

func (*GORMLogger) Print

func (g *GORMLogger) Print(v ...interface{})

type GuildWithConnected

type GuildWithConnected struct {
	Connected bool

func GetGuildsWithConnected

func GetGuildsWithConnected(in []*discordgo.UserGuild) ([]*GuildWithConnected, error)

GetGuildsWithConnected Returns a wrapped guild with connected set

type InviteSource

type InviteSource struct {
	Name  string
	Regex *regexp.Regexp

func ContainsInvite

func ContainsInvite(s string, checkDiscordSource, checkThirdPartySources bool) *InviteSource

type LoggedExecutedCommand

type LoggedExecutedCommand struct {

	UserID    string
	ChannelID string
	GuildID   string

	// Name of command that was triggered
	Command string
	// Raw command with arguments passed
	RawCommand string
	// If command returned any error this will be no-empty
	Error string

	TimeStamp    time.Time
	ResponseTime int64

func (LoggedExecutedCommand) TableName

func (l LoggedExecutedCommand) TableName() string

type LoggingTransport

type LoggingTransport struct {
	Inner http.RoundTripper

func (*LoggingTransport) RoundTrip

func (t *LoggingTransport) RoundTrip(request *http.Request) (*http.Response, error)

type Plugin

type Plugin interface {
	PluginInfo() *PluginInfo

Plugin represents a plugin, all plugins needs to implement this at a bare minimum

type PluginCategory

type PluginCategory struct {
	Name  string
	Order int

type PluginInfo

type PluginInfo struct {
	Name     string // Human readable name of the plugin
	SysName  string // snake_case version of the name in lower case
	Category *PluginCategory

type PrefixedLogFormatter

type PrefixedLogFormatter struct {
	Inner  logrus.Formatter
	Prefix string

func (*PrefixedLogFormatter) Format

func (p *PrefixedLogFormatter) Format(entry *logrus.Entry) ([]byte, error)

type STDLogProxy

type STDLogProxy struct{}

func (*STDLogProxy) Write

func (p *STDLogProxy) Write(b []byte) (n int, err error)

type SmallModel

type SmallModel struct {
	ID        uint `gorm:"primary_key"`
	CreatedAt time.Time
	UpdatedAt time.Time

Package Files

Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to identifier