Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
VoiceChannel (*discord.Channel)&arg.Config{
Required: []arg.RequiredArg{
{
Name: "User",
Type: arg.User,
Description: "The user that shall be muted.",
},
},
Optional: []arg.OptionalArg{
{
Name: "Reason",
Type: arg.SimpleText,
Description: "The reason for the mute.",
},
},
Flags: []arg.Flag{
{
Name: "duration",
Aliases: []string{"d"},
Type: arg.SimpleDuration,
Description: "The duration to mute the user for.",
},
},
}&arg.Config{
Required: []arg.RequiredArg{
{
Name: "Number of Messages",
Type: &arg.Integer{Min: 1, Max: 100},
Description: "The number of messages to delete (max. 100).",
},
},
Flags: []arg.Flag{
{
Name: "user",
Aliases: []string{"u"},
Type: arg.Member,
Multi: true, // this allows multiple uses of the flag
Description: "The users to delete messages from.",
},
{
Name: "rm-pins",
Aliades: []string{"pin", "p"},
Type: arg.Switch, // Switch is special and can only be used for flags
Description: "Whether to delete pinned messages as well.",
},
},
}type Command interface {
CommandMeta
Invoke(*state.State, *Context) (interface{}, error)
}int16int32int64package ping
import (
"github.com/mavolin/adam/pkg/impl/command"
"github.com/mavolin/adam/pkg/plugin"
)
type Ping struct {
command.Meta
}
var _ plugin.Command = new(Ping) // compile time checkimport (
...
"github.com/diamondburned/ariakwa/v2/state"
"github.com/mavolin/adam/plg/plugin"
"time"
)
...
func (p *Ping) Invoke(_ *state.State, ctx *plugin.Context) (interface{}, error) {
t := time.Now()
msg, err := ctx.Reply("The ping to discord is `calculating...`")
if err != nil {
return nil, err
}
_, err := ctx.Editf(msg.ID, "The ping to discord is %d ms",
time.Since(now).Milliseconds())
return nil, err
}import (
...
"github.com/diamondburned/arikawa/v2/discord"
"github.com/mavolin/adam/pkg/plugin"
"github.com/mavolin/adam/pkg/impl/command"
)
var _ plugin.Command = new(Ping) // compile-time check
// New creates a new Ping command.
func New() *Ping {
return &Ping{
Meta: command.Meta{
Name: "ping",
ShortDescription: "Tells you the ping to Discord's servers.",
ChannelTypes: plugin.AllChannels,
BotPermissions: discord.SendMessagesPermission,
},
}
}
func (p *Ping) Invoke(_ *state.State, ctx *plugin.Context) (interface{}, error) {
...
}package mod
import (
"github.com/mavolin/adam/pkg/impl/module"
"github.com/mavolin/adam/pkg/plugin"
)
// New creates a new moderation module.
func New() plugin.Module {
return module.New(module.Meta{Name: "mod"}})
}package mod
import (
"github.com/mavolin/myBot/plugin/mod/ban"
"github.com/mavolin/myBot/plugin/mod/kick"
"github.com/mavolin/adam/pkg/impl/module"
"github.com/mavolin/adam/pkg/plugin"
)
// New creates a new moderation module.
func New() plugin.Module {
m := module.New(module.Meta{Name: "mod"}})
m.AddCommand(ban.New())
m.AddCommand(kick.New())
return m
}📁 myBot
┣ 📁 cmd
┃ ┗ 📁 mybot - your main package running the bot
┣ 📁 plugins
┃ ┣ 📁 mod - the mod (moderation) module
┃ ┃ ┣ 📁 ban - the ban command
┃ ┃ ┗ 📁 kick - the kick command
┃ ┗ 📁 ping - the ping command
┗ 📁 pkg
┗ 📁 repository
┣ 📁 mongo - mongo db driver
┗ 📁 postgres - postgres db driverpackage main
import (
"log"
"os"
"time"
"github.com/mavolin/adam/pkg/bot"
)
func main() {
bot, err := bot.New(bot.Options{
Token: os.Getenv("DISCORD_BOT_TOKEN"),
SettingsProvider: bot.NewStaticSettingsProvider(parsePrefixes()...),
EditAge: 45 * time.Seconds,
})
if err != nil {
log.Fatal(err)
}
}
func parsePrefixes() []string {
prefixes := os.Getenv("BOT_PREFIXES")
if len(prefixes) == 0 {
return nil
}
return strings.Split(prefixes, ",")
}package main
import (
"github.com/mavolin/myBot/plugin/ping"
"github.com/mavolin/myBot/plugin/mod"
"github.com/mavolin/adam/pkg/bot"
"github.com/mavolin/adam/pkg/impl/command/help"
"log"
)
func main() {
bot, err := bot.New(...)
if err != nil {
log.Fatal(err)
}
addPlugins(bot)
}
func addPlugins(b *bot.Bot) {
// to add a help command you can either create your own, or use adam's
// built-in one
b.AddCommand(help.New(help.Options{}))
}errors.InformationalErrorerrors.InternalErrorerrors.UserErrorerrors.UserInfoplugin.ArgumentErrorplugin.BotPermissionsErrorplugin.ChannelTypeErrorplugin.RestrictionErrorplugin.ThrottlingErrornonSilent := errors.NewWithStack("something broke")
silent := errors.Silent(nonSilentError)
nonSilentAgain := errors.WithStack(silent)package main
import (
"github.com/diamondburned/ariakwa/v2/discord"
"github.com/mavolin/adam/pkg/i18n"
"github.com/mavolin/disstate/v3/pkg/state"
i18nimpl "github.com/nicksnyder/go-i18n/v2/i18n"
)
type settingsRepository interface {
GuildSettings(discord.GuildID) (prefixes []string, lang string, err error)
}
func newSettingsProvider(
repo settingsRepository, bundle *i18nimpl.Bundle,
) bot.SettingsProvider {
return func (_ *state.Base, m *discord.Message) (
[]string, *i18n.Localizer, bool,
) {
prefixes, lang, err := repo.GuildSettings(m.GuildID)
if err != nil {
log.Println(err)
// allow execution regardless, and just use fallbacks
return nil, nil, true
}
return prefixes, i18n.NewLocalizer(lang, newI18nFunc(bundle, lang)), true
}
}
func newI18nFunc(b *i18nimpl.Bundle, lang string) i18n.Func {
l := i18nimpl.NewLocalizer(b, lang)
return func(
term i18n.Term, placeholders map[string]interface{}, plural interface{},
) (string, error) {
return l.Localize(&i18nimpl.LocalizeConfig{
MessageID: string(term),
TemplateData: placeholders,
PluralCount: plural,
})
}
}package main
import (
"github.com/mavolin/myBot/pkg/repository/memory"
"github.com/mavolin/adam/pkg/bot"
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language"
"os"
)
func main() {
repo := memory.New()
bundle := i18n.NewBundle(language.English)
bundle.LoadMessageFile("en-US.yaml")
bot, err := bot.New(bot.Options{
Token: os.Getenv("DISCORD_BOT_TOKEN"),
SettingsProvider: newSettingsProvider(repo, bundle),
})
}import (
"github.com/getsentry/sentry-go"
"github.com/mavolin/adam/pkg/errors"
log "github.com/sirupsen/logrus"
)
func changeLogging() {
errors.Log = func(err error, ctx *plugin.Context) {
log.WithFields(log.Fields{
"err": err,
"cmd_id": ctx.InvokedCommand.ID,
}).
Error("internal error in command")
sentry.CaptureException(err)
}
}bot, err := bot.New(bot.Options{
Token: os.Getenv("DISCORD_BOT_TOKEN"),
ErrorHandler: func(err error, s *state.State, ctx *plugin.Context) {
if errors.Is(err, bot.ErrUnknownCommand) {
return
}
bot.DefaultErrorHandler(err, s, ctx)
},
})import (
"github.com/diamondburned/arikawa/v2/discord"
"github.com/mavolin/adam/pkg/impl/restriction"
)
var ensignID discord.RoleID = 1234567890987
restriction.Any(
restriction.UserPermissions(discord.PermissionAdministrator),
restriction.All(
restriction.Roles(ensignID),
restriction.BotOwner,
),
)import (
"github.com/diamondburned/arikawa/discord"
"github.com/mavolin/adam/pkg/impl/restriction"
"github.com/mavolin/adam/pkg/plugin"
)
var ErrRestriction = plugin.NewRestrictionError("You need to be a moderator or " +
"have the kick permissions to use this command.")
restriction.Anyf(ErrRestriction,
restriction.Permissions(discord.PermissionManageGuild),
restriction.Permissions(discord.Kick),
)package sum
import "github.com/mavolin/adam/pkg/i18n"
var (
shortDescription = i18n.NewFallbackConfig(
"plugin.sum.short_description", "Add numbers together")
argsNumbersName = i18n.NewFallbackConfig(
"plugin.sum.args.numbers.name", "Numbers")
argsNumbersDescription = i18n.NewFallbackConfig(
"plugin.sum.arg.numbers.description",
"The numbers that shall be added.")
)
var (
errorNotEnoughNumbers = i18n.NewFallbackConfig(
"plugin.sum.error.not_enough_numbers", // term
"I need at least 2 numbers to calculate a sum!") // fallback
result = i18n.NewFallbackConfig(
"plugin.sum.result", "The sum is {{.sum}}.")
)
// The recommended way to fill placeholders is by using data structs.
// All exported fields will by put into snake_case and given to the Localizer
// as placeholders.
// If you want to use custom names, use the `i18n:"my_custom_name"` struct tag.
type resultPlaceholders struct {
Sum int
}package sum
import (
"github.com/mavolin/adam/pkg/i18n"
"github.com/mavolin/adam/pkg/impl/arg"
)
type Sum struct {
command.Meta
}
func New() *Sum {
return &Sum{
Meta: command.LocalizedMeta{
Name: "sum",
ShortDescription: shortDescription,
Args: &arg.LocalizedConfig{
RequiredArgs: []arg.LocalizedRequiredArg{
{
Name: argsNumbersName,
Type: arg.Integer,
Description: argsNumbersDescription,
},
},
Variadic: true,
},
},
}
}
func (s *Say) (_ *state.State, ctx *plugin.Context) (interface{}, error) {
nums := ctx.Args.Ints(0)
if len(nums) >= 1 {
return nil, errors.NewUserErrorl(errorNotEnoughNumbers)
}
var sum int
for _, num := range nums {
sum += num
}
return result.WithPlaceholders(resultPlaceholders{
Sum: sum,
}, nil
}