shaned24 / crabbot-discord Goto Github PK
View Code? Open in Web Editor NEWA discord router interface for easily routing commands to handlers. Docs at https://shaned24.github.io/crabbot-discord/
A discord router interface for easily routing commands to handlers. Docs at https://shaned24.github.io/crabbot-discord/
Hey there,
I decided I wanted to learn Go and figured a good way would be to convert my Python discord bot over to Go. I spent some time looking over projects to try and get a feel for how things were structured and how people went about things when I came across first dg/exrouter, but then came across this library. I quite like how you went about things, so I figured I would give it a go. I picked apart some things and mixed it with some of my own I wanted to try and so far so good, it is working. I had a question though about the subroutines.
I looks like it is pretty similar to the "ping pong" example, minus this:
func (u *ExampleSubRoute) GetSubRoutes() []crabbot.Route {
return []crabbot.Route{
NewUser(),
}
}
You will have to forgive me, as I am still getting the hanf of Go's overall syntax and structure, but it looks like the subroutine in general is just loading another routine? If you don't mind, could you perhaps fill me in a little on what all is happening with it? I have a feeling I am just overlooking something. I am interested in finding out what the use case and benefit of it might be?
Library seems great though, I appreciate you making it!
Thanks,
-MH
Hey again,
I have been hard at work the last few days but am a bit stuck and I was hoping you might be able to assist with an opinion? I have a fairly good bit of things up and running and have been working on some custom command routes, but being that I am still not 100% on the best way to go about things in Go I was doing some more research as I kept running into issues trying to pass my config data / settings around to the places they needed to go (such as into the handlers so I could use data from my settings) so I started looking into some dependency injection frameworks and I settled on this one. . Mostly because it was the only one I could actually get to work properly, but either way.
I have it setup just like their example code in the repo, in package main
I have the following: There is a line labeled "This line", it passes the config data from within the DI container to the main application which is located at main/verifier
builder, err := di.NewBuilder()
if err != nil {
logrus.Fatal(err.Error())
}
err = builder.Add(services.Services...)
if err != nil {
logrus.Fatal(err.Error())
}
app := builder.Build()
defer app.Delete()
verifierRun, err := appContext.Verifier.VerifierRun(app.Get("configData").(*appconfig.MainSettings)) // <--- This line ---
if err != nil {
log.Println("error creating Bot session,", err)
}
Then I have package located at main/services
which contains the following, which is what creates and populates the DI container:
var Services = []di.Def{
{
Name: "configData",
Build: func(ctn di.Container) (interface{}, error) {
var cfg appconfig.MainSettings
config := cfg.GetConfig()
return config, nil
},
},
}
Then in my main/verifier
"meat and potatos" I have the following, which I am sure you can tell was heavily influenced by your examples, lol.
type Verifier struct {
}
type Config struct {
Settings *appconfig.MainSettings
Session *discordgo.Session
Routes []cmdroutes.Route
botId string
}
func (vc *Config) registerRoutes(session *discordgo.Session, Routes ...cmdroutes.Route) {
router := exrouter.New()
cmdroutes.RegisterRoutes(
router,
Routes...,
)
session.AddHandler(func(_ *discordgo.Session, m *discordgo.MessageCreate) {
log.Printf("Message %v", m.Content)
log.Printf("Message %v", m.Type)
_ = router.FindAndExecute(vc.Session, vc.Settings.System.CommandPrefix, session.State.User.ID, m.Message)
})
}
func (v *Verifier) VerifierRun(s *appconfig.MainSettings) (*Config, error) {
session, err := discordgo.New("Bot " + s.System.Token)
if err != nil {
fmt.Println("Error connecting to server: ", err)
return nil, err
}
settings := &Config{Settings: s,
Session: session,
Routes: []cmdroutes.Route{
cmdroutes.NewSubRoute(),
cmdroutes.NewUser(),
cmdroutes.NewDirectMessage(),
cmdroutes.NewPing(),
cmdroutes.NewListRoles()}}
var logLevel int
switch settings.Settings.System.ConsoleLogLevel {
case "DEBUG":
logLevel = discordgo.LogDebug
case "INFO":
logLevel = discordgo.LogInformational
case "WARNING":
logLevel = discordgo.LogWarning
case "ERROR":
logLevel = discordgo.LogError
default:
logLevel = discordgo.LogError
}
settings.Session.LogLevel = logLevel
settings.registerRoutes(settings.Session, settings.Routes...)
//--------- so on and so forth
}
So, the last route in the list there is the one I am currently working on, which looks like this:
type ListRoles struct {
ctn di.Container
}
func (p *ListRoles) Handle(ctx *exrouter.Context) {
guildObject, err := p.ctn.SafeGet("configData")
if err != nil {
log.Fatalf("Didn't work. : / ", err)
}
if guild, ok := guildObject.(*appconfig.MainSettings); ok {
log.Infof("GuildID: %s", guild.Discord.Guild)
} else {
log.Fatalf("Also didn't work. : \ ", err)
}
guildRoles, err := ctx.Ses.GuildRoles(p.ctn.Get("configData").(*appconfig.MainSettings).Discord.Guild)
if err != nil {
log.Print("Could not get list of current roles", err)
}
roleTable := p.renderMarkDownTable(guildRoles)
_, err = ctx.Reply(roleTable)
if err != nil {
log.Print("Something went wrong when handling listroles request", err)
}
}
I am not sure the best way to go about trying to get the DI container in there, though. As you will notice, I tried to see if I could simply add the containers interface into the ListRoles struct to see if I could get to it that way, but unfortunately all I was able to get out of it was this:
2019/05/26 10:49:35 Message !cmdlistroles
2019/05/26 10:49:35 Message 0
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x60 pc=0x71c61e]
Which came from the very first line of the Handle function.
I realize this got super long and I apologize about that, but what I am getting to is, what would be the best way to go about getting this data into the handlers so I can use it? There are going to be many in which I will need to access the data. Pretty much 95% of the ones I am going to make are all going to need it, so I am hoping to find the "proper" way of doing it, but also the most efficient since I am going to have to do it for pretty much all of the cmd routers.
If you might be able to point me in the right direction, I would greatly appreciate it!
Thanks again,
-MH
Is there a certain way to go about obtaining input from within a handler? Ex. A command is issued, the bot PM's me, asks me to input something, I do it, it replies back for more input, etc, etc
Here is how I would go about it in Python with the bot framework I was using:
async def wp_email_check(self, ctx):
def check(m):
return m.author == ctx.message.author
await ctx.send(text.email_capture_during_verification()) # -- This would send the text out "Please enter your email address"
email = await self.bot.wait_for('message', check=check) # -- Then this would start an async method which would listen for input
What is the proper way to go about getting input with this system?
Thanks,
-MH
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.