mmmorty

package module
v0.0.0-...-5ebfbd1 Latest Latest
Warning

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

Go to latest
Published: Jun 27, 2021 License: MIT Imports: 12 Imported by: 0

README

MMMorty!

Discord bot by me (aka Giant)

Much of this code was taken from: https://github.com/iopred/bruxism/blob/master/discord.go

Check that one out. It's a really good example.

Features

Mmmorty is rather Beta in the sense that it mainly has the features I felt like implementing rather than any requested features.

TLDR

Use @<botname> help to view the commands.

Picking things

@<botname> choose <option> or <option> (or ...) - asks Morty to pick something for you.

If you want to opt out of this feature, start the bot with the -pick=FALSE command line flag.

Quotes

Use @<botname> quote me to view one of the stored quotes.

Quotes are stored by calling @<botname> add quote <author> said <quote>. For example:

There are hardcoded constants for the maximum word count of a quote as well as how many quotes can be stored, but these can be easily changed in the Quote Plugin code. I may extract these into environment variables later.

Quotes with links (quotes containing the string "http") will be rejected.

If you want to opt out of this feature, start the bot with the -quote=FALSE command line flag.

Dictionary

Use @<botname> define <word> to get the definition of a word.

Words can be added by server staff with @<botname> add word <word> <definition> and deleted with @<botname> delete <word>.

Plot Twists

Plot twists work the same as Quotes except that they do not have an associated author. They are handy for users to submit ideas for arbitrary plot twists and prompts to help with storywriting. They are added with this:

@<botname> add plot twist <some twist>

To retrieve twists:

@<botname> plot twist

Twists are subject to the same restriction as quotes.

Setting Users' Colors With Roles

Use @<botname> color me <color> so mmmorty can set your color. This requires a bit of setup:

  1. Create a set of roles that have no extra permissions applied (same as default for @everyone), with each role's name and color set as desired.
  2. Call @<botname> manage color <color list>. For example, @<botname> manage color red yellow green blue purple
  3. Make sure mmmorty's role is listed above the colors so it has permission to add/remove them.

To stop managing colors, use @<botname> stop managing <color list>. This could be handy either when removing/renaming a role or elevating its permissions and invalidating its use as a color-only role.

Mmmorty will refuse to assign roles which have any permissions applied or that are above it in the permissions list. It is expected, and recommended, to have colored roles function separately from user permissions.

If you want to opt out of this feature, start the bot with the -color=FALSE command line flag.

Timed Sprints

This is the original reason I made this bot.

Use @<botname> start sprint at :XX for Y to start a timed "sprint"/"word war".

This feature is targetted more towards the WriMo community but might be useful for anyone looking for short bursts of productivity. Users can request to be pinged on these updates.

It should be easy to change the output strings in a fork branch to make use of the timer for other purposes.

How it works:

  1. Start a sprint. The :XX notation provides a timezone-agnostic time to start. Y is the number of minutes the sprint should last. The : is optional and at X and for Y are interchangeable.
  2. Users can use the join sprint and leave sprint commands to add/remove themselves from the list of users that get pinged at each interval. The user that starts the sprint is added automatically.
  3. Users receive three updates: the one-minute-before warning, the start notification, and the end notification.

Multiple simultaneous sprints can be run. Each one is given an ID number to help manage them. This feature is disabled by default, so you will need the -war=TRUE flag to enable it.

Setting Up

  1. Set up a bot with discord. A good guide for this is here.

  2. Connect with permissions (see: https://discordapi.com/permissions.html). Use these permission:

    • Manage Roles (if you want the color-changing feature)
    • Read Messages
    • Send Messages

    This means you should connect to https://discordapp.com/oauth2/authorize?client_id=<client id>&scope=bot&permissions=26843852868438528

  3. Run this bot. Use make to install mmmorty globally, and then run:

    mmmorty -discordtoken <token> -discordowneruserid <your user id>

Alternatively you can set environment variables for DISCORD_TOKEN and DISCORD_OWNER so you only need to call mmmorty to run the program.

Documentation

Index

Constants

View Source
const (
	// MessageTypeCreate is the message type for message creation.
	MessageTypeCreate MessageType = "create"
	// MessageTypeUpdate is the message type for message updates.
	MessageTypeUpdate = "update"
	// MessageTypeDelete is the message type for message deletion.
	MessageTypeDelete = "delete"
)
View Source
const DiscordServiceName string = "Discord"

DiscordServiceName is the service name for the Discord service.

View Source
const VersionString string = "0.11"

VersionString is the current version of the bot

Variables

View Source
var ErrAlreadyJoined = errors.New("already joined")

ErrAlreadyJoined is an error dispatched on Join if the bot is already joined to the request.

Functions

func CommandHelp

func CommandHelp(service Discord, command, arguments, help string) []string

CommandHelp is a helper message that creates help text for a command. eg. CommandHelp(service, "foo", "<bar>", "Foo bar baz") will return:

!foo <bar> - Foo bar baz

The string is automatatically styled in Discord.

func MatchesCommand

func MatchesCommand(service Discord, commandString string, message DiscordMessage) bool

MatchesCommand returns true if a message matches a command.

func MatchesCommandString

func MatchesCommandString(service Discord, commandString string, private bool, message string) bool

MatchesCommandString returns true if a message matches a command. Commands will be matched ignoring case with a prefix if they are not private messages.

func ParseCommand

func ParseCommand(service Discord, message DiscordMessage) (string, []string)

ParseCommand parses a message.

func ParseCommandString

func ParseCommandString(service Discord, message string) (string, []string)

ParseCommandString will strip all prefixes from a message string, and return that string, and a space separated tokenized version of that string.

Types

type Bot

type Bot struct {
	Services    map[string]*serviceEntry
	ImgurID     string
	ImgurAlbum  string
	MashableKey string
}

Bot enables registering of Services and Plugins.

func NewBot

func NewBot() *Bot

NewBot will create a new bot.

func (*Bot) MessageRecover

func (b *Bot) MessageRecover(discord Discord, channel string)

MessageRecover is the default panic handler

func (*Bot) Open

func (b *Bot) Open()

Open will open all the current services and begins listening.

func (*Bot) RegisterPlugin

func (b *Bot) RegisterPlugin(service Discord, plugin Plugin)

RegisterPlugin registers a plugin on a service.

func (*Bot) RegisterService

func (b *Bot) RegisterService(service Discord)

RegisterService registers a service with the bot.

func (*Bot) Save

func (b *Bot) Save()

Save will save the current plugin state for all plugins on all services.

type CommandHelpFunc

type CommandHelpFunc func(bot *Bot, service Discord, message DiscordMessage) (string, string)

CommandHelpFunc is the function signature for command help methods.

func NewCommandHelp

func NewCommandHelp(args, help string) CommandHelpFunc

NewCommandHelp creates a new Command Help function.

type CommandMessageFunc

type CommandMessageFunc func(bot *Bot, service Discord, message DiscordMessage, args string, parts []string)

CommandMessageFunc is the function signature for bot message commands.

type CommandPlugin

type CommandPlugin struct {
	// contains filtered or unexported fields
}

CommandPlugin is a plugin that can have commands registered and will handle messages matching that command by calling functions.

func NewCommandPlugin

func NewCommandPlugin() *CommandPlugin

NewCommandPlugin will create a new command plugin.

func (*CommandPlugin) AddCommand

func (p *CommandPlugin) AddCommand(commandString string, message CommandMessageFunc, help CommandHelpFunc)

AddCommand adds a command.

func (*CommandPlugin) Help

func (p *CommandPlugin) Help(bot *Bot, service Discord, message DiscordMessage, detailed bool) []string

Help returns a list of help strings that are printed when the user requests them.

func (*CommandPlugin) Load

func (p *CommandPlugin) Load(bot *Bot, service Discord, data []byte) error

Load will load plugin state from a byte array.

func (*CommandPlugin) Message

func (p *CommandPlugin) Message(bot *Bot, service Discord, message DiscordMessage)

Message handler. Iterates over the registered commands and executes them if the message matches.

func (*CommandPlugin) Name

func (p *CommandPlugin) Name() string

Name returns the name of the plugin.

func (*CommandPlugin) Save

func (p *CommandPlugin) Save() ([]byte, error)

Save will save plugin state to a byte array.

type Discord

type Discord struct {
	Shards int

	// The first session, used to send messages (and maintain backwards compatibility).
	Session             *discordgo.Session
	Sessions            []*discordgo.Session
	OwnerUserID         string
	ApplicationClientID string
	// contains filtered or unexported fields
}

Discord is a Service provider for Discord.

func NewDiscord

func NewDiscord(args ...interface{}) *Discord

NewDiscord creates a new discord service.

func (*Discord) BanUser

func (d *Discord) BanUser(channel, userID string, duration int) error

BanUser bans a user.

func (*Discord) Channel

func (d *Discord) Channel(channelID string) (channel *discordgo.Channel, err error)

Channel gets the Discord Channel for the given ID

func (*Discord) ChannelCount

func (d *Discord) ChannelCount() int

ChannelCount returns the number of channels the bot is in.

func (*Discord) CommandPrefix

func (d *Discord) CommandPrefix() string

CommandPrefix returns the command prefix for the service.

func (*Discord) DeleteMessage

func (d *Discord) DeleteMessage(channel, messageID string) error

DeleteMessage deletes a message.

func (*Discord) GetRoleByName

func (d *Discord) GetRoleByName(channel, roleName string) *discordgo.Role

GetRoleByName returns the Discord role for the given role name

func (*Discord) GetRoles

func (d *Discord) GetRoles(channel string) []*discordgo.Role

GetRoles gets the list of roles for the given guild

func (*Discord) Guild

func (d *Discord) Guild(guildID string) (guild *discordgo.Guild, err error)

Guild gets the Discord Guild for the given ID

func (*Discord) GuildLeave

func (d *Discord) GuildLeave(guildID string) (err error)

GuildLeave leaves a Guild. guildID : The ID of a Guild

func (*Discord) GuildMemberRoleAdd

func (d *Discord) GuildMemberRoleAdd(guild, user, role string) bool

GuildMemberRoleAdd gives a guild member a role

func (*Discord) GuildMemberRoleRemove

func (d *Discord) GuildMemberRoleRemove(guild, user, role string) bool

GuildMemberRoleRemove takes a guild member's role

func (*Discord) Guilds

func (d *Discord) Guilds() []*discordgo.Guild

Guilds gets the list of Discord Guilds the service has sessions for

func (*Discord) IsBotOwner

func (d *Discord) IsBotOwner(message DiscordMessage) bool

IsBotOwner returns whether or not a message sender was the owner of the bot.

func (*Discord) IsChannelOwner

func (d *Discord) IsChannelOwner(message DiscordMessage) bool

IsChannelOwner returns whether or not the sender of a message is a moderator.

func (*Discord) IsMe

func (d *Discord) IsMe(message DiscordMessage) bool

IsMe returns whether or not a message was sent by the bot.

func (*Discord) IsModerator

func (d *Discord) IsModerator(message DiscordMessage) bool

IsModerator returns whether or not the sender of a message is a moderator.

func (*Discord) IsPrivate

func (d *Discord) IsPrivate(message DiscordMessage) bool

IsPrivate returns whether or not a message was private.

func (*Discord) Join

func (d *Discord) Join(join string) error

Join accept an invite or return an error. If AlreadyJoinedError is return, @me has already accepted that invite.

func (*Discord) MessageHistory

func (d *Discord) MessageHistory(channel string) []*DiscordMessage

MessageHistory returns the message history for a channel.

func (*Discord) Name

func (d *Discord) Name() string

Name returns the name of the service.

func (*Discord) Nickname

func (d *Discord) Nickname(message DiscordMessage) string

Nickname gets the nickname of the speaker of a message

func (*Discord) NicknameForID

func (d *Discord) NicknameForID(userID, userName, channelID string) string

NicknameForID gets the nickname of the given user

func (*Discord) Open

func (d *Discord) Open() (<-chan *DiscordMessage, error)

Open opens the service and returns a channel which all messages will be sent on.

func (*Discord) PrivateMessage

func (d *Discord) PrivateMessage(userID, message string) error

PrivateMessage will send a private message to a user.

func (*Discord) SendAction

func (d *Discord) SendAction(channel, message string) error

SendAction sends an action.

func (*Discord) SendFile

func (d *Discord) SendFile(channel, name string, r io.Reader) error

SendFile sends a file.

func (*Discord) SendMessage

func (d *Discord) SendMessage(channel, message string) error

SendMessage sends a message.

func (*Discord) SupportsMessageHistory

func (d *Discord) SupportsMessageHistory() bool

SupportsMessageHistory returns if the service supports message history.

func (*Discord) SupportsMultiline

func (d *Discord) SupportsMultiline() bool

SupportsMultiline returns whether the service supports multiline messages.

func (*Discord) SupportsPrivateMessages

func (d *Discord) SupportsPrivateMessages() bool

SupportsPrivateMessages returns whether the service supports private messages.

func (*Discord) Typing

func (d *Discord) Typing(channel string) error

Typing sets that the bot is typing.

func (*Discord) UnbanUser

func (d *Discord) UnbanUser(channel, userID string) error

UnbanUser unbans a user.

func (*Discord) UserChannelPermissions

func (d *Discord) UserChannelPermissions(userID, channelID string) (apermissions int64, err error)

UserChannelPermissions gets the bits for the user's permissions

func (*Discord) UserColor

func (d *Discord) UserColor(userID, channelID string) int

UserColor gets the color of the given user

func (*Discord) UserID

func (d *Discord) UserID() string

UserID returns the bots user id.

func (*Discord) UserName

func (d *Discord) UserName() string

UserName returns the bots name.

func (*Discord) UserRoles

func (d *Discord) UserRoles(guild, memberID string) []string

UserRoles gets the list of roles of the given user

type DiscordMessage

type DiscordMessage struct {
	Discord          *Discord
	DiscordgoMessage *discordgo.Message
	MessageType      MessageType
	Nick             *string
	Content          *string
}

DiscordMessage is a Message wrapper around discordgo.Message.

func (DiscordMessage) Channel

func (m DiscordMessage) Channel() string

Channel returns the channel id for this message.

func (DiscordMessage) Message

func (m DiscordMessage) Message() string

Message returns the message content for this message.

func (DiscordMessage) MessageID

func (m DiscordMessage) MessageID() string

MessageID returns the message ID for this message.

func (DiscordMessage) RawMessage

func (m DiscordMessage) RawMessage() string

RawMessage returns the raw message content for this message.

func (DiscordMessage) Type

func (m DiscordMessage) Type() MessageType

Type returns the type of message.

func (DiscordMessage) UserAvatar

func (m DiscordMessage) UserAvatar() string

UserAvatar returns the avatar url for this message.

func (DiscordMessage) UserID

func (m DiscordMessage) UserID() string

UserID returns the user id for this message.

func (DiscordMessage) UserName

func (m DiscordMessage) UserName() string

UserName returns the user name for this message.

type HelpFunc

type HelpFunc func(*Bot, Discord, DiscordMessage, bool) []string

HelpFunc is the function signature for a help handler.

type LoadFunc

type LoadFunc func(*Bot, Discord, []byte) error

LoadFunc is the function signature for a load handler.

type MessageFunc

type MessageFunc func(*Bot, Discord, DiscordMessage)

MessageFunc is the function signature for a message handler.

type MessageType

type MessageType string

MessageType is a type used to determine the CRUD state of a message.

type Plugin

type Plugin interface {
	Name() string
	Load(*Bot, Discord, []byte) error
	Save() ([]byte, error)
	Help(*Bot, Discord, DiscordMessage, bool) []string
	Message(*Bot, Discord, DiscordMessage)
}

Plugin is a plugin interface, supports loading and saving to a byte array and has help and message handlers.

func NewHelpPlugin

func NewHelpPlugin() Plugin

NewHelpPlugin will create a new help plugin.

type SaveFunc

type SaveFunc func() ([]byte, error)

SaveFunc is the function signature for a save handler.

type StatsFunc

type StatsFunc func(*Bot, Discord, DiscordMessage) []string

StatsFunc is the function signature for a stats handler.

Jump to

Keyboard shortcuts

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