Group-like syntax commands
Hello :)
Following issue #157 and PR #168, we don't properly handle group-like syntax command (/command@botname), right?
It seems that even with MatchTypeCommand and MatchTypeCommandStartOnly we can't recognise the command because it's considered as a different one by data[e.Offset+1:e.Offset+e.Length] == h.pattern.
How would you do things differently? Search for pattern inclusion?
Best
I use this for the time being:
func (s *TelegramService) registerCommandHandler(command string, handler bot.HandlerFunc) {
commandText := "/" + command
commandTextPrefix := commandText + "@"
matchFunc := func(update *models.Update) bool {
if update.Message != nil {
for _, e := range update.Message.Entities {
if e.Offset == 0 {
part := update.Message.Text[e.Offset : e.Offset+e.Length]
if part == commandText || strings.HasPrefix(part, commandTextPrefix) {
return true
}
}
}
}
return false
}
s.bot.RegisterHandlerMatchFunc(matchFunc, handler)
}
(Note that it's somewhat sub optimal as we should really be checking only the first entity instead of checking every and compare offset to 0).
Yes, currently matching command in this format is not built into the library. But this can be easily implemented by creating your own matching function (MatchFunc) and registering a handler with this function via RegisterHandlerMatchFunc(matchFunc MatchFunc, f HandlerFunc, m ...Middleware).
For example:
...
b, err := bot.New(cfg.Token, opts...)
if err != nil {
return nil, err
}
b.RegisterHandlerMatchFunc(MatchCommandTestWithParams, CommandTest)
...
func MatchCommandTestWithParams(update *models.Update) bool {
if update.Message == nil {
return false
}
return strings.HasPrefix(update.Message.Text, "/test@")
}
func CommandTest(ctx context.Context, b *bot.Bot, update *models.Update) {
if update.Message == nil {
return
}
parts := strings.SplitAfter(update.Message.Text, "@")
commandPart := parts[0]
paramPart := parts[1]
partsText := fmt.Sprintf("Command: %s\nParameter: %s", commandPart, paramPart)
b.SendMessage(ctx, &bot.SendMessageParams{
ChatID: update.Message.Chat.ID,
Text: fmt.Sprintf("`%s` command received!\n\n%s", update.Message.Text, partsText),
})
}
Result:
To simplify, the /test command was hardcoded and the @ character was not dropped when dividing into a command and its parameters. It can be done, but that's not the goal. The goal is to demonstrate the general idea. That is not so difficult to make your own MatchFunc, which will be able to process commands in the format /command@param and any others.
And I think that a similar MatchFunc for commands with parameters would be very useful as part of the library.
@negasus