Coder Social home page Coder Social logo

shaned24 / crabbot-discord Goto Github PK

View Code? Open in Web Editor NEW
2.0 2.0 0.0 26 KB

A discord router interface for easily routing commands to handlers. Docs at https://shaned24.github.io/crabbot-discord/

Go 69.74% Dockerfile 2.82% Makefile 7.69% Shell 9.26% Mustache 10.49%
discord discord-bot golang routing

crabbot-discord's People

Contributors

shaned24 avatar

Stargazers

 avatar  avatar

Watchers

 avatar

crabbot-discord's Issues

Question about subroutines

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

Best way / place to pass in a dependency injection container to a handler?

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

Obtaining input within a handler?

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.