gocto

package module
v1.4.15 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 2, 2020 License: MIT Imports: 15 Imported by: 0

README

Sapphire

Sapphire is a bot framework built for discordgo

Join our Discord at discord.gg/ArwQrH4

Features:

  • Easy to configure, lot of configurations with sane defaults.
  • Abstract, We don't force you to use a specific database instead we let you express your database of choice to us.
  • Lightweight, Sapphire only depends on very minimal dependencies so you don't spend time and space pulling in dependencies.
  • Full featured, Sapphire ain't a toy, it's a complete framework for your bot.
  • Lot of tools! A lot of utilities to avoid reinventing the wheel such as a reaction paginator and many more.
  • Components can be disabled/enabled on the go at runtime.
  • Localization, Sapphire helps to translate your bot's responses easily.

Install

$ go get github.com/sapphire-cord/sapphire

Run the same command with -u once in a while, sapphire is constantly being updated.

Usage

package main

import (
  "github.com/sapphire-cord/sapphire"
  "github.com/bwmarrin/discordgo"
)

func main() {
  dg, _ := discordgo.New("token")
  bot := sapphire.New(dg)
  bot.SetPrefix("!")
  bot.LoadBuiltins() // Loads builtin commands.
  bot.Connect()
  bot.Wait() // Needed to keep the process running.
}

That's it! a basic bot will be launched with builtin commands such as help.

Read our guide for lot of more cool things you can do! (Don't be afraid our guides are easy to follow and we are open for questions.)

See also the documentation after the guides for even more possibilies!

Contributing

Sapphire is still in it's early stages of development and there is a lot of things that can be done, we welcome contributions on everything, typo-fixes, grammar-fixes, detail improvement, new guides and contributions on the code are all welcome.

Here is a little personal TODO for myself but you can help me with if you wish so.

  • Use mutexes where needed.
  • Improve the arguments API.
  • Add proper logging support.
  • Add a permission check system for commands.

It is incomplete but fairly usable.

License

MIT

Documentation

Index

Constants

View Source
const (
	EmbedLimitTitle       = 256
	EmbedLimitDescription = 2048
	EmbedLimitFieldValue  = 1024
	EmbedLimitFieldName   = 256
	EmbedLimitField       = 25
	EmbedLimitFooter      = 2048
	EmbedLimit            = 4000
)
View Source
const (
	EmojiLeft  = "◀️"
	EmojiRight = "▶️"
	EmojiFirst = "⏪"
	EmojiLast  = "⏩"
	EmojiStop  = "⏹️"
)
View Source
const COLOR = 0x7F139E
View Source
const VERSION = "0.0.1"

Variables

View Source
var ChannelMentionRegex = regexp.MustCompile("^(?:<#)?(\\d{17,19})>?$")

The Regexp used for matching channel mentions.

View Source
var English = NewLanguage("en-US").
	Set("LOCALE_NO_KEY", "No localization found for the key \"%s\" Please report this to the developers.").
	Set("COMMAND_ERROR", "Something went wrong, please try again later.").
	Set("COMMAND_PING", "Pong!").
	Set("COMMAND_PING_PONG", "Pong!\nHTTP API: **%s**\nGateway: **%s**").
	Set("COMMAND_ENABLE_ALREADY", "That command is already enabled!").
	Set("COMMAND_DISABLE_ALREADY", "That command is already disabled!").
	Set("COMMAND_ENABLE_SUCCESS", "Successfully enabled the command **%s**").
	Set("COMMAND_DISABLE_SUCCESS", "Successfully disabled the command **%s**").
	Set("COMMAND_NOT_FOUND", "Command '%s' not found.").
	Set("COMMAND_INVITE", "To invite me to your server: <%s>").
	Set("COMMAND_OWNER_ONLY", "This command is for the bot owner only!").
	Set("COMMAND_GUILD_ONLY", "This command can only be used in a server!").
	Set("COMMAND_COOLDOWN", "You can use this command again in %d seconds.").
	Set("COMMAND_DISABLED", "This command has been disabled globally by the bot owner.").
	Set("COMMAND_MISSING_PERMS", "You are missing %s permission(s) to run this command.")
View Source
var HumanizeUsageRegex = regexp.MustCompile("(<|\\[)(\\w+):[^.]+?(\\.\\.\\.)?(>|\\])")
View Source
var MentionRegex = regexp.MustCompile("^(?:<@!?)?(\\d{17,19})>?$")

The Regexp used for matching user mentions.

Functions

func CommandHandlerMonitor

func CommandHandlerMonitor(bot *Bot, ctx *MonitorContext)

func Escape

func Escape(input string) string

func HumanizeUsage

func HumanizeUsage(usage string) string

Types

type Argument

type Argument struct {
	Value interface{}
	// contains filtered or unexported fields
}

Argument represents an argument, it has methods to grab the right type.

func ParseArgument

func ParseArgument(ctx *CommandContext, tag *UsageTag, raw string) (*Argument, error)

Parses the raw argument as specified in tag in context of ctx

func (*Argument) AsBool

func (arg *Argument) AsBool() bool

func (*Argument) AsChannel

func (arg *Argument) AsChannel() *discordgo.Channel

func (*Argument) AsFloat

func (arg *Argument) AsFloat() float64

func (*Argument) AsGuild

func (arg *Argument) AsGuild() *discordgo.Guild

func (*Argument) AsInt

func (arg *Argument) AsInt() int

func (*Argument) AsInt64

func (arg *Argument) AsInt64() int64

func (*Argument) AsMember

func (arg *Argument) AsMember() *discordgo.Member

func (*Argument) AsMessage

func (arg *Argument) AsMessage() *discordgo.Message

func (*Argument) AsRole

func (arg *Argument) AsRole() *discordgo.Role

func (*Argument) AsString

func (arg *Argument) AsString() string

Returns the argument as a string.

func (*Argument) AsUser

func (arg *Argument) AsUser() *discordgo.User

func (*Argument) IsProvided

func (arg *Argument) IsProvided() bool

IsProvided checks if this argument is provided, for optional arguments you must use this before casting.

type Bot

type Bot struct {
	Session     *discordgo.Session  // The discordgo session.
	Prefix      PrefixHandler       // The handler called to get the prefix. (default: !)
	Language    LocaleHandler       // The handler called to get the language (default: en-US)
	Commands    map[string]*Command // Map of commands.
	CommandsRan int                 // Commands ran.
	Monitors    map[string]*Monitor // Map of monitors.

	CommandCooldowns map[int64]map[string]time.Time
	CommandEdits     map[int64]int64
	OwnerID          int64                // Bot owner's ID (default: fetched from application info)
	InvitePerms      int                  // Permissions bits to use for the invite link. (default: 3072)
	Languages        map[string]*Language // Map of languages.
	DefaultLocale    *Language            // Default locale to fallback. (default: en-US)
	CommandTyping    bool                 // Wether to start typing when a command is being ran. (default: true)
	ErrorHandler     ErrorHandler         // The handler to catch panics in monitors (which includes commands).
	ListHandler      ListHandler
	MentionPrefix    bool // Wether to allow @mention of the bot to be used as a prefix too. (default: true)

	Application *discordgo.Application // The bot's application.
	Uptime      time.Time              // The time the bot hit ready event.
	Color       int                    // The color used in builtin commands's embeds.
	// contains filtered or unexported fields
}

func New

func New(s *discordgo.Session) *Bot

New creates a new sapphire bot, pass in a discordgo instance configured with your token.

func (*Bot) AddCommand

func (bot *Bot) AddCommand(cmd *Command) *Bot

func (*Bot) AddLanguage

func (bot *Bot) AddLanguage(lang *Language) *Bot

AddLanguage adds the specified language.

func (*Bot) AddMonitor

func (bot *Bot) AddMonitor(m *Monitor) *Bot

func (*Bot) CheckCooldown

func (bot *Bot) CheckCooldown(userID int64, command string, cooldownSec int) (bool, int)

func (*Bot) Connect

func (bot *Bot) Connect() error

func (*Bot) GetCommand

func (bot *Bot) GetCommand(name string) *Command

func (*Bot) LoadBuiltins

func (bot *Bot) LoadBuiltins() *Bot

func (*Bot) MustConnect

func (bot *Bot) MustConnect()

MustConnect is like Connect but panics if there is an error.

func (*Bot) SetDefaultLocale

func (bot *Bot) SetDefaultLocale(locale string) *Bot

func (*Bot) SetErrorHandler

func (bot *Bot) SetErrorHandler(fn ErrorHandler) *Bot

func (*Bot) SetInvitePerms

func (bot *Bot) SetInvitePerms(bits int) *Bot

func (*Bot) SetListHandler

func (bot *Bot) SetListHandler(list ListHandler) *Bot

func (*Bot) SetLocaleHandler

func (bot *Bot) SetLocaleHandler(handler LocaleHandler) *Bot

func (*Bot) SetMentionPrefix

func (bot *Bot) SetMentionPrefix(toggle bool) *Bot

func (*Bot) SetPrefix

func (bot *Bot) SetPrefix(prefix string) *Bot

func (*Bot) SetPrefixHandler

func (bot *Bot) SetPrefixHandler(prefix PrefixHandler) *Bot

func (*Bot) Wait

func (bot *Bot) Wait()

type Command

type Command struct {
	Name                string         // The command's name. (default: required)
	Aliases             []string       // Aliases that point to this command. (default: [])
	Run                 CommandHandler // The handler that actually runs the command. (default: required)
	Enabled             bool           // Wether this command is enabled. (default: true)
	Description         string         // The command's brief description. (default: "No Description Provided.")
	Category            string         // The category this command belongs to. (default: required)
	OwnerOnly           bool           // Wether this command can only be used by the owner. (default: false)
	GuildOnly           bool           // Wether this command can only be ran on a guild. (default: false)
	UsageString         string         // Usage string for this command. (default: "")
	Usage               []*UsageTag    // Parsed usage tags for this command.
	Cooldown            int            // Command cooldown in seconds. (default: 0)
	Editable            bool           // Wether this command's response will be editable. (default: true)
	RequiredPermissions int            // Permissions the user needs to run this command. (default: 0)
	DeleteAfter         bool           // Deletes command when ran (default: false)
	BotPermissions      int            // Permissions the bot needs to perform this command. (default: 0)
	Override            bool           // Override message editting (default: true)
	AvailableTags       string         // Shows available tags in help command (default: none)
}

func NewCommand

func NewCommand(name string, category string, run CommandHandler) *Command

func (*Command) AddAliases

func (c *Command) AddAliases(aliases ...string) *Command

func (*Command) Delete

func (c *Command) Delete() *Command

func (*Command) Disable

func (c *Command) Disable() *Command

func (*Command) Enable

func (c *Command) Enable() *Command

func (*Command) NoOverride

func (c *Command) NoOverride(status bool) *Command

func (*Command) SetCooldown

func (c *Command) SetCooldown(cooldown int) *Command

func (*Command) SetDescription

func (c *Command) SetDescription(description string) *Command

func (*Command) SetEditable

func (c *Command) SetEditable(toggle bool) *Command

func (*Command) SetGuildOnly

func (c *Command) SetGuildOnly(toggle bool) *Command

func (*Command) SetOwnerOnly

func (c *Command) SetOwnerOnly(toggle bool) *Command

func (*Command) SetPermission

func (c *Command) SetPermission(permbit int) *Command

func (*Command) SetUsage

func (c *Command) SetUsage(usage string) *Command

type CommandContext

type CommandContext struct {
	Command     *Command           // The currently executing command.
	Message     *discordgo.Message // The message of this command.
	Session     *discordgo.Session // The discordgo session.
	Bot         *Bot               // The sapphire Bot.
	Channel     *discordgo.Channel // The channel this command was ran on.
	Author      *discordgo.User    // Alias of Context.Message.Author
	Args        []*Argument        // List of arguments.
	Prefix      string             // The prefix used to invoke this command.
	Guild       *discordgo.Guild   // The guild this command was ran on.
	Flags       map[string]string  // Map of flags passed to the command. e.g --flag=yo
	Locale      *Language          // The current language.
	RawArgs     []string           // The raw args that may not match the usage string.
	InvokedName string             // The name this command was invoked as, this includes the used alias.
}

func (*CommandContext) Arg

func (ctx *CommandContext) Arg(idx int) *Argument

func (*CommandContext) BuildEmbed

func (ctx *CommandContext) BuildEmbed(embed *Embed) (*discordgo.Message, error)

BuildEmbed calls ReplyEmbed(embed.Build())

func (*CommandContext) BuildEmbedNoEdit

func (ctx *CommandContext) BuildEmbedNoEdit(embed *Embed) (*discordgo.Message, error)

BuildEmbedNoEdit calls ReplyEmbedNoEdit(embed.Build())

func (*CommandContext) CodeBlock

func (ctx *CommandContext) CodeBlock(lang, content string, args ...interface{}) (*discordgo.Message, error)

func (*CommandContext) Edit

func (ctx *CommandContext) Edit(msg *discordgo.Message, content string, args ...interface{}) (*discordgo.Message, error)

Edit edits msg's content It will call Sprintf() on the content if atleast one vararg is passed.

func (*CommandContext) EditLocale

func (ctx *CommandContext) EditLocale(msg *discordgo.Message, key string, args ...interface{}) (*discordgo.Message, error)

EditLocale edits msg with a localized key

func (*CommandContext) Error

func (ctx *CommandContext) Error(err interface{}, args ...interface{})

func (*CommandContext) FetchUser

func (ctx *CommandContext) FetchUser(id int64) (*discordgo.User, error)

FetchUser searches the cache for the given user id and if not found, attempts to fetch it from the API.

func (*CommandContext) Flag

func (ctx *CommandContext) Flag(flag string) string

func (*CommandContext) GetFirstMentionedUser

func (ctx *CommandContext) GetFirstMentionedUser() *discordgo.User

GetFirstMentionedUser returns the first user mentioned in the message.

func (*CommandContext) HasArgs

func (ctx *CommandContext) HasArgs() bool

func (*CommandContext) HasFlag

func (ctx *CommandContext) HasFlag(flag string) bool

func (*CommandContext) JoinedArgs

func (ctx *CommandContext) JoinedArgs(sliced ...int) string

func (*CommandContext) Member

func (ctx *CommandContext) Member(id int64) *discordgo.Member

Member gets a member by id from the current guild, returns nil if not found.

func (*CommandContext) ParseArgs

func (ctx *CommandContext) ParseArgs() bool

func (*CommandContext) React

func (ctx *CommandContext) React(emoji string) error

func (*CommandContext) Reply

func (ctx *CommandContext) Reply(content string, args ...interface{}) (*discordgo.Message, error)

Reply replies with a string. It will call Sprintf() on the content if atleast one vararg is passed.

func (*CommandContext) ReplyEmbed

func (ctx *CommandContext) ReplyEmbed(embed *discordgo.MessageEmbed) (*discordgo.Message, error)

ReplyEmbed replies with an embed.

func (*CommandContext) ReplyEmbedNoEdit

func (ctx *CommandContext) ReplyEmbedNoEdit(embed *discordgo.MessageEmbed) (*discordgo.Message, error)

ReplyEmbedNoEdits replies with an embed but not considering the editable option of the command.

func (*CommandContext) ReplyLocale

func (ctx *CommandContext) ReplyLocale(key string, args ...interface{}) (*discordgo.Message, error)

ReplyLocale sends a localized key for the current context's locale.

func (*CommandContext) ReplyNoEdit

func (ctx *CommandContext) ReplyNoEdit(content string, args ...interface{}) (*discordgo.Message, error)

ReplyNoEdit replies with content but does not consider editable option of the command.

func (*CommandContext) SendFile

func (ctx *CommandContext) SendFile(name string, file io.Reader, content string, args ...interface{}) (*discordgo.Message, error)

SendFile sends a file with name

func (*CommandContext) User

func (ctx *CommandContext) User(id int64) *discordgo.User

User gets a user by id, returns nil if not found.

type CommandError

type CommandError struct {
	Err     interface{}     // The value passed to panic()
	Context *CommandContext // The context of the command, use this to e.g get the command's name etc.
	Line    int
	File    string
}

func (*CommandError) Error

func (err *CommandError) Error() string

type CommandHandler

type CommandHandler func(ctx *CommandContext)

type Embed

type Embed struct {
	*discordgo.MessageEmbed
}

Embed ...

func NewEmbed

func NewEmbed() *Embed

func (*Embed) AddField

func (e *Embed) AddField(name, value string, args ...interface{}) *Embed

func (*Embed) AddInlineField

func (e *Embed) AddInlineField(name, value string, args ...interface{}) *Embed

func (*Embed) Build

func (e *Embed) Build() *discordgo.MessageEmbed

func (*Embed) InlineAllFields

func (e *Embed) InlineAllFields() *Embed

func (*Embed) SetAuthor

func (e *Embed) SetAuthor(args ...string) *Embed

func (*Embed) SetColor

func (e *Embed) SetColor(clr int) *Embed

func (*Embed) SetDescription

func (e *Embed) SetDescription(description string) *Embed

func (*Embed) SetFooter

func (e *Embed) SetFooter(args ...string) *Embed

func (*Embed) SetImage

func (e *Embed) SetImage(args ...string) *Embed

func (*Embed) SetThumbnail

func (e *Embed) SetThumbnail(args ...string) *Embed

func (*Embed) SetTitle

func (e *Embed) SetTitle(name string) *Embed

func (*Embed) SetURL

func (e *Embed) SetURL(URL string) *Embed

func (*Embed) Truncate

func (e *Embed) Truncate() *Embed

func (*Embed) TruncateDescription

func (e *Embed) TruncateDescription() *Embed

func (*Embed) TruncateFields

func (e *Embed) TruncateFields() *Embed

func (*Embed) TruncateFooter

func (e *Embed) TruncateFooter() *Embed

func (*Embed) TruncateTitle

func (e *Embed) TruncateTitle() *Embed

type ErrorHandler

type ErrorHandler func(b *Bot, err interface{})

type Language

type Language struct {
	Name string
	Keys map[string]string
}

func NewLanguage

func NewLanguage(name string) *Language

func (*Language) Get

func (l *Language) Get(key string, args ...interface{}) string

func (*Language) GetDefault

func (l *Language) GetDefault(key string, def string, args ...interface{}) string

func (*Language) Merge

func (l *Language) Merge(other *Language) *Language

func (*Language) Set

func (l *Language) Set(key string, value string) *Language

type ListHandler

type ListHandler func(b *Bot, m *discordgo.Message) bool

type LocaleHandler

type LocaleHandler func(b *Bot, m *discordgo.Message, dm bool) string

type Monitor

type Monitor struct {
	Name           string
	Enabled        bool
	Run            MonitorHandler
	GuildOnly      bool
	IgnoreWebhooks bool
	IgnoreBots     bool
	IgnoreSelf     bool
	IgnoreEdits    bool
}

func NewMonitor

func NewMonitor(name string, monitor MonitorHandler) *Monitor

func (*Monitor) AllowBots

func (m *Monitor) AllowBots() *Monitor

func (*Monitor) AllowEdits

func (m *Monitor) AllowEdits() *Monitor

func (*Monitor) AllowSelf

func (m *Monitor) AllowSelf() *Monitor

func (*Monitor) AllowWebhooks

func (m *Monitor) AllowWebhooks() *Monitor

func (*Monitor) SetGuildOnly

func (m *Monitor) SetGuildOnly(toggle bool) *Monitor

type MonitorContext

type MonitorContext struct {
	Message *discordgo.Message
	Channel *discordgo.Channel
	Session *discordgo.Session
	Author  *discordgo.User
	Monitor *Monitor
	Guild   *discordgo.Guild
	Bot     *Bot
}

type MonitorHandler

type MonitorHandler func(bot *Bot, ctx *MonitorContext)

type Paginator

type Paginator struct {
	Running   bool
	Session   *discordgo.Session
	ChannelID int64
	Template  func() *Embed
	Pages     []*discordgo.MessageEmbed

	Message  *discordgo.Message
	AuthorID int64
	StopChan chan bool
	Extra    string
	Timeout  time.Duration
	// contains filtered or unexported fields
}

func NewPaginator

func NewPaginator(session *discordgo.Session, channel, author int64) *Paginator

func NewPaginatorForContext

func NewPaginatorForContext(ctx *CommandContext) *Paginator

func (*Paginator) AddPage

func (p *Paginator) AddPage(fn func(em *Embed) *Embed)

func (*Paginator) AddPageString

func (p *Paginator) AddPageString(str string)

func (*Paginator) Delete

func (p *Paginator) Delete()

func (*Paginator) GetIndex

func (p *Paginator) GetIndex() int

func (*Paginator) Goto

func (p *Paginator) Goto(index int)

Switches pages, index is assumed to be a valid index. (can panic if it's not) Edits the current message to the given page and updates the index.

func (*Paginator) NextPage

func (p *Paginator) NextPage()

Switches to next page, this is safer than raw Goto as it compares indices and switch to first page if we are already on last one.

func (*Paginator) PreviousPage

func (p *Paginator) PreviousPage()

Switches to the previous page, this is safer than raw Goto as it compares indices and switch to last page if we are already on the first one.

func (*Paginator) Run

func (p *Paginator) Run()

func (*Paginator) SetExtra

func (p *Paginator) SetExtra(extra string)

func (*Paginator) SetFooter

func (p *Paginator) SetFooter()

Sets the footers of all pages to their page number out of total pages. Called by Run to initialize.

func (*Paginator) SetTemplate

func (p *Paginator) SetTemplate(em func() *Embed)

func (*Paginator) Stop

func (p *Paginator) Stop()

Stops the paginator by sending the signal to the Stop Channel.

type Permissions

type Permissions int

func PermissionsForMember

func PermissionsForMember(guild *discordgo.Guild, member *discordgo.Member) Permissions

func PermissionsForRole

func PermissionsForRole(role *discordgo.Role) Permissions

func (Permissions) Has

func (perms Permissions) Has(bits int) bool

type PrefixHandler

type PrefixHandler func(b *Bot, m *discordgo.Message, dm bool) string

type UsageTag

type UsageTag struct {
	Name     string
	Type     string
	Rest     bool
	Required bool
}

func ParseUsage

func ParseUsage(usage string) ([]*UsageTag, error)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL