Ad-Hoc support for chat commands
This commit is contained in:
parent
a0180eff75
commit
b0c5302c82
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/zelenin/go-tdlib/client"
|
"github.com/zelenin/go-tdlib/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const unknownCommand string = "Unknown command"
|
||||||
const notEnoughArguments string = "Not enough arguments"
|
const notEnoughArguments string = "Not enough arguments"
|
||||||
const TelegramNotInitialized string = "Telegram connection is not initialized yet"
|
const TelegramNotInitialized string = "Telegram connection is not initialized yet"
|
||||||
const TelegramAuthDone string = "Authorization is done already"
|
const TelegramAuthDone string = "Authorization is done already"
|
||||||
|
@ -272,7 +273,7 @@ func (c *Client) ProcessTransportCommand(cmdline string, resource string) string
|
||||||
cmd, args := parseCommand(cmdline)
|
cmd, args := parseCommand(cmdline)
|
||||||
command, ok := transportCommands[cmd]
|
command, ok := transportCommands[cmd]
|
||||||
if !ok {
|
if !ok {
|
||||||
return "Unknown command"
|
return unknownCommand
|
||||||
}
|
}
|
||||||
if len(args) < command.RequiredArgs {
|
if len(args) < command.RequiredArgs {
|
||||||
return notEnoughArguments
|
return notEnoughArguments
|
||||||
|
@ -498,6 +499,14 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd, args := parseCommand(cmdline)
|
cmd, args := parseCommand(cmdline)
|
||||||
|
command, ok := chatCommands[cmd]
|
||||||
|
if !ok {
|
||||||
|
return unknownCommand, false
|
||||||
|
}
|
||||||
|
if len(args) < command.RequiredArgs {
|
||||||
|
return notEnoughArguments, true
|
||||||
|
}
|
||||||
|
|
||||||
switch cmd {
|
switch cmd {
|
||||||
// delete message
|
// delete message
|
||||||
case "d":
|
case "d":
|
||||||
|
@ -542,9 +551,6 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
if c.me == nil {
|
if c.me == nil {
|
||||||
return "@me is not initialized", true
|
return "@me is not initialized", true
|
||||||
}
|
}
|
||||||
if len(args) < 1 {
|
|
||||||
return "Not enough arguments", true
|
|
||||||
}
|
|
||||||
|
|
||||||
messages, err := c.getLastMessages(chatID, "", c.me.Id, 1)
|
messages, err := c.getLastMessages(chatID, "", c.me.Id, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -575,10 +581,6 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
}
|
}
|
||||||
// send without sound
|
// send without sound
|
||||||
case "silent":
|
case "silent":
|
||||||
if len(args) < 1 {
|
|
||||||
return "Not enough arguments", true
|
|
||||||
}
|
|
||||||
|
|
||||||
content := c.PrepareOutgoingMessageContent(rawCmdArguments(cmdline, 0))
|
content := c.PrepareOutgoingMessageContent(rawCmdArguments(cmdline, 0))
|
||||||
|
|
||||||
if content != nil {
|
if content != nil {
|
||||||
|
@ -597,10 +599,6 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
}
|
}
|
||||||
// schedule a message to timestamp or to going online
|
// schedule a message to timestamp or to going online
|
||||||
case "schedule":
|
case "schedule":
|
||||||
if len(args) < 2 {
|
|
||||||
return "Not enough arguments", true
|
|
||||||
}
|
|
||||||
|
|
||||||
var state client.MessageSchedulingState
|
var state client.MessageSchedulingState
|
||||||
var result string
|
var result string
|
||||||
due := args[0]
|
due := args[0]
|
||||||
|
@ -677,10 +675,6 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
}
|
}
|
||||||
// forward a message to chat
|
// forward a message to chat
|
||||||
case "forward":
|
case "forward":
|
||||||
if len(args) < 2 {
|
|
||||||
return notEnoughArguments, true
|
|
||||||
}
|
|
||||||
|
|
||||||
messageId, err := strconv.ParseInt(args[0], 10, 64)
|
messageId, err := strconv.ParseInt(args[0], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "Cannot parse message ID", true
|
return "Cannot parse message ID", true
|
||||||
|
@ -742,10 +736,6 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
}
|
}
|
||||||
// create group chat with current user
|
// create group chat with current user
|
||||||
case "group":
|
case "group":
|
||||||
if len(args) < 1 {
|
|
||||||
return notEnoughArguments, true
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := c.client.CreateNewBasicGroupChat(&client.CreateNewBasicGroupChatRequest{
|
_, err := c.client.CreateNewBasicGroupChat(&client.CreateNewBasicGroupChatRequest{
|
||||||
UserIds: []int64{chatID},
|
UserIds: []int64{chatID},
|
||||||
Title: args[0],
|
Title: args[0],
|
||||||
|
@ -773,10 +763,6 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
}
|
}
|
||||||
// invite @username to current groupchat
|
// invite @username to current groupchat
|
||||||
case "invite":
|
case "invite":
|
||||||
if len(args) < 1 {
|
|
||||||
return notEnoughArguments, true
|
|
||||||
}
|
|
||||||
|
|
||||||
contact, _, err := c.GetContactByUsername(args[0])
|
contact, _, err := c.GetContactByUsername(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error(), true
|
return err.Error(), true
|
||||||
|
@ -801,10 +787,6 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
return link.InviteLink, true
|
return link.InviteLink, true
|
||||||
// kick @username from current group chat
|
// kick @username from current group chat
|
||||||
case "kick":
|
case "kick":
|
||||||
if len(args) < 1 {
|
|
||||||
return notEnoughArguments, true
|
|
||||||
}
|
|
||||||
|
|
||||||
contact, _, err := c.GetContactByUsername(args[0])
|
contact, _, err := c.GetContactByUsername(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error(), true
|
return err.Error(), true
|
||||||
|
@ -820,10 +802,6 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
}
|
}
|
||||||
// mute @username [n hours]
|
// mute @username [n hours]
|
||||||
case "mute":
|
case "mute":
|
||||||
if len(args) < 1 {
|
|
||||||
return notEnoughArguments, true
|
|
||||||
}
|
|
||||||
|
|
||||||
contact, _, err := c.GetContactByUsername(args[0])
|
contact, _, err := c.GetContactByUsername(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error(), true
|
return err.Error(), true
|
||||||
|
@ -851,10 +829,6 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
}
|
}
|
||||||
// unmute @username
|
// unmute @username
|
||||||
case "unmute":
|
case "unmute":
|
||||||
if len(args) < 1 {
|
|
||||||
return notEnoughArguments, true
|
|
||||||
}
|
|
||||||
|
|
||||||
contact, _, err := c.GetContactByUsername(args[0])
|
contact, _, err := c.GetContactByUsername(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error(), true
|
return err.Error(), true
|
||||||
|
@ -874,10 +848,6 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
}
|
}
|
||||||
// ban @username from current chat [for N hours]
|
// ban @username from current chat [for N hours]
|
||||||
case "ban":
|
case "ban":
|
||||||
if len(args) < 1 {
|
|
||||||
return notEnoughArguments, true
|
|
||||||
}
|
|
||||||
|
|
||||||
contact, _, err := c.GetContactByUsername(args[0])
|
contact, _, err := c.GetContactByUsername(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error(), true
|
return err.Error(), true
|
||||||
|
@ -903,10 +873,6 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
}
|
}
|
||||||
// unban @username
|
// unban @username
|
||||||
case "unban":
|
case "unban":
|
||||||
if len(args) < 1 {
|
|
||||||
return notEnoughArguments, true
|
|
||||||
}
|
|
||||||
|
|
||||||
contact, _, err := c.GetContactByUsername(args[0])
|
contact, _, err := c.GetContactByUsername(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error(), true
|
return err.Error(), true
|
||||||
|
@ -922,10 +888,6 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
}
|
}
|
||||||
// promote @username to admin
|
// promote @username to admin
|
||||||
case "promote":
|
case "promote":
|
||||||
if len(args) < 1 {
|
|
||||||
return notEnoughArguments, true
|
|
||||||
}
|
|
||||||
|
|
||||||
contact, _, err := c.GetContactByUsername(args[0])
|
contact, _, err := c.GetContactByUsername(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error(), true
|
return err.Error(), true
|
||||||
|
@ -1133,10 +1095,6 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) cmdAdd(args []string) string {
|
func (c *Client) cmdAdd(args []string) string {
|
||||||
if len(args) < 1 {
|
|
||||||
return notEnoughArguments
|
|
||||||
}
|
|
||||||
|
|
||||||
chat, err := c.client.SearchPublicChat(&client.SearchPublicChatRequest{
|
chat, err := c.client.SearchPublicChat(&client.SearchPublicChatRequest{
|
||||||
Username: args[0],
|
Username: args[0],
|
||||||
})
|
})
|
||||||
|
@ -1153,10 +1111,6 @@ func (c *Client) cmdAdd(args []string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) cmdJoin(args []string) string {
|
func (c *Client) cmdJoin(args []string) string {
|
||||||
if len(args) < 1 {
|
|
||||||
return notEnoughArguments
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.HasPrefix(args[0], "@") {
|
if strings.HasPrefix(args[0], "@") {
|
||||||
chat, err := c.client.SearchPublicChat(&client.SearchPublicChatRequest{
|
chat, err := c.client.SearchPublicChat(&client.SearchPublicChatRequest{
|
||||||
Username: args[0],
|
Username: args[0],
|
||||||
|
@ -1186,10 +1140,6 @@ func (c *Client) cmdJoin(args []string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) cmdSupergroup(args []string, cmdline string) string {
|
func (c *Client) cmdSupergroup(args []string, cmdline string) string {
|
||||||
if len(args) < 1 {
|
|
||||||
return notEnoughArguments
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := c.client.CreateNewSupergroupChat(&client.CreateNewSupergroupChatRequest{
|
_, err := c.client.CreateNewSupergroupChat(&client.CreateNewSupergroupChatRequest{
|
||||||
Title: args[0],
|
Title: args[0],
|
||||||
Description: rawCmdArguments(cmdline, 1),
|
Description: rawCmdArguments(cmdline, 1),
|
||||||
|
@ -1202,10 +1152,6 @@ func (c *Client) cmdSupergroup(args []string, cmdline string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) cmdChannel(args []string, cmdline string) string {
|
func (c *Client) cmdChannel(args []string, cmdline string) string {
|
||||||
if len(args) < 1 {
|
|
||||||
return notEnoughArguments
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := c.client.CreateNewSupergroupChat(&client.CreateNewSupergroupChatRequest{
|
_, err := c.client.CreateNewSupergroupChat(&client.CreateNewSupergroupChatRequest{
|
||||||
Title: args[0],
|
Title: args[0],
|
||||||
Description: rawCmdArguments(cmdline, 1),
|
Description: rawCmdArguments(cmdline, 1),
|
||||||
|
|
174
xmpp/handlers.go
174
xmpp/handlers.go
|
@ -490,23 +490,30 @@ func handleGetDiscoInfo(s xmpp.Sender, iq *stanza.IQ, di *stanza.DiscoInfo) {
|
||||||
|
|
||||||
disco := answer.DiscoInfo()
|
disco := answer.DiscoInfo()
|
||||||
_, ok := toToID(iq.To)
|
_, ok := toToID(iq.To)
|
||||||
if ok {
|
if di.Node == "" {
|
||||||
disco.AddIdentity("", "account", "registered")
|
if ok {
|
||||||
disco.AddFeatures(stanza.NSMsgChatMarkers)
|
disco.AddIdentity("", "account", "registered")
|
||||||
disco.AddFeatures(stanza.NSMsgReceipts)
|
disco.AddFeatures(stanza.NSMsgChatMarkers)
|
||||||
} else {
|
disco.AddFeatures(stanza.NSMsgReceipts)
|
||||||
if di.Node == "" {
|
} else {
|
||||||
disco.AddIdentity("Telegram Gateway", "gateway", "telegram")
|
disco.AddIdentity("Telegram Gateway", "gateway", "telegram")
|
||||||
disco.AddFeatures("jabber:iq:register")
|
disco.AddFeatures("jabber:iq:register")
|
||||||
disco.AddFeatures(NSCommand)
|
}
|
||||||
|
disco.AddFeatures(NSCommand)
|
||||||
|
} else {
|
||||||
|
var cmdType telegram.CommandType
|
||||||
|
if ok {
|
||||||
|
cmdType = telegram.CommandTypeChat
|
||||||
} else {
|
} else {
|
||||||
for name, command := range telegram.GetCommands(telegram.CommandTypeTransport) {
|
cmdType = telegram.CommandTypeTransport
|
||||||
if di.Node == name {
|
}
|
||||||
answer.Payload = di
|
|
||||||
di.AddIdentity(telegram.CommandToHelpString(name, command), "automation", "command-node")
|
for name, command := range telegram.GetCommands(cmdType) {
|
||||||
di.AddFeatures(NSCommand, "jabber:x:data")
|
if di.Node == name {
|
||||||
break
|
answer.Payload = di
|
||||||
}
|
di.AddIdentity(telegram.CommandToHelpString(name, command), "automation", "command-node")
|
||||||
|
di.AddFeatures(NSCommand, "jabber:x:data")
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -539,16 +546,22 @@ func handleGetDiscoItems(s xmpp.Sender, iq *stanza.IQ, di *stanza.DiscoItems) {
|
||||||
log.Debugf("discoItems: %#v", di)
|
log.Debugf("discoItems: %#v", di)
|
||||||
|
|
||||||
_, ok := toToID(iq.To)
|
_, ok := toToID(iq.To)
|
||||||
if !ok {
|
if di.Node == NSCommand {
|
||||||
commands := telegram.GetCommands(telegram.CommandTypeTransport)
|
answer.Payload = di
|
||||||
if di.Node == NSCommand {
|
|
||||||
answer.Payload = di
|
var cmdType telegram.CommandType
|
||||||
for name, command := range commands {
|
if ok {
|
||||||
di.AddItem(iq.To, name, telegram.CommandToHelpString(name, command))
|
cmdType = telegram.CommandTypeChat
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
answer.Payload = answer.DiscoItems()
|
cmdType = telegram.CommandTypeTransport
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commands := telegram.GetCommands(cmdType)
|
||||||
|
for name, command := range commands {
|
||||||
|
di.AddItem(iq.To, name, telegram.CommandToHelpString(name, command))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
answer.Payload = answer.DiscoItems()
|
||||||
}
|
}
|
||||||
|
|
||||||
component, ok := s.(*xmpp.Component)
|
component, ok := s.(*xmpp.Component)
|
||||||
|
@ -706,66 +719,70 @@ func handleSetQueryCommand(s xmpp.Sender, iq *stanza.IQ, command *stanza.Command
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, toOk := toToID(iq.To)
|
toId, toOk := toToID(iq.To)
|
||||||
|
|
||||||
var cmdString string
|
var cmdString string
|
||||||
if !toOk {
|
var cmdType telegram.CommandType
|
||||||
form, formOk := command.CommandElement.(*stanza.Form)
|
form, formOk := command.CommandElement.(*stanza.Form)
|
||||||
if formOk {
|
if toOk {
|
||||||
// just for the case the client messed the order somehow
|
cmdType = telegram.CommandTypeChat
|
||||||
sort.Slice(form.Fields, func(i int, j int) bool {
|
} else {
|
||||||
iField := form.Fields[i]
|
cmdType = telegram.CommandTypeTransport
|
||||||
jField := form.Fields[j]
|
}
|
||||||
if iField != nil && jField != nil {
|
if formOk {
|
||||||
ii, iErr := strconv.ParseInt(iField.Var, 10, 64)
|
// just for the case the client messed the order somehow
|
||||||
ji, jErr := strconv.ParseInt(jField.Var, 10, 64)
|
sort.Slice(form.Fields, func(i int, j int) bool {
|
||||||
return iErr == nil && jErr == nil && ii < ji
|
iField := form.Fields[i]
|
||||||
}
|
jField := form.Fields[j]
|
||||||
return false
|
if iField != nil && jField != nil {
|
||||||
})
|
ii, iErr := strconv.ParseInt(iField.Var, 10, 64)
|
||||||
|
ji, jErr := strconv.ParseInt(jField.Var, 10, 64)
|
||||||
var cmd strings.Builder
|
return iErr == nil && jErr == nil && ii < ji
|
||||||
cmd.WriteString("/")
|
|
||||||
cmd.WriteString(command.Node)
|
|
||||||
for _, field := range form.Fields {
|
|
||||||
cmd.WriteString(" ")
|
|
||||||
if len(field.ValuesList) > 0 {
|
|
||||||
cmd.WriteString(field.ValuesList[0])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
cmdString = cmd.String()
|
var cmd strings.Builder
|
||||||
} else {
|
cmd.WriteString("/")
|
||||||
if command.Action == "" || command.Action == stanza.CommandActionExecute {
|
cmd.WriteString(command.Node)
|
||||||
cmd, ok := telegram.GetCommand(telegram.CommandTypeTransport, command.Node)
|
for _, field := range form.Fields {
|
||||||
if ok && cmd.RequiredArgs > 0 {
|
cmd.WriteString(" ")
|
||||||
var fields []*stanza.Field
|
if len(field.ValuesList) > 0 {
|
||||||
for i, arg := range cmd.Arguments {
|
cmd.WriteString(field.ValuesList[0])
|
||||||
fields = append(fields, &stanza.Field{
|
}
|
||||||
Var: strconv.FormatInt(int64(i), 10),
|
}
|
||||||
Label: arg,
|
|
||||||
})
|
cmdString = cmd.String()
|
||||||
}
|
} else {
|
||||||
answer.Payload = &stanza.Command{
|
if command.Action == "" || command.Action == stanza.CommandActionExecute {
|
||||||
SessionId: command.Node,
|
cmd, ok := telegram.GetCommand(cmdType, command.Node)
|
||||||
Node: command.Node,
|
if ok && len(cmd.Arguments) > 0 {
|
||||||
Status: stanza.CommandStatusExecuting,
|
var fields []*stanza.Field
|
||||||
CommandElement: &stanza.Form{
|
for i, arg := range cmd.Arguments {
|
||||||
Type: stanza.FormTypeForm,
|
fields = append(fields, &stanza.Field{
|
||||||
Title: command.Node,
|
Var: strconv.FormatInt(int64(i), 10),
|
||||||
Instructions: []string{cmd.Description},
|
Label: arg,
|
||||||
Fields: fields,
|
})
|
||||||
},
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cmdString = "/" + command.Node
|
|
||||||
}
|
}
|
||||||
} else if command.Action == stanza.CommandActionCancel {
|
|
||||||
answer.Payload = &stanza.Command{
|
answer.Payload = &stanza.Command{
|
||||||
SessionId: command.Node,
|
SessionId: command.Node,
|
||||||
Node: command.Node,
|
Node: command.Node,
|
||||||
Status: stanza.CommandStatusCancelled,
|
Status: stanza.CommandStatusExecuting,
|
||||||
|
CommandElement: &stanza.Form{
|
||||||
|
Type: stanza.FormTypeForm,
|
||||||
|
Title: command.Node,
|
||||||
|
Instructions: []string{cmd.Description},
|
||||||
|
Fields: fields,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
cmdString = "/" + command.Node
|
||||||
|
}
|
||||||
|
} else if command.Action == stanza.CommandActionCancel {
|
||||||
|
answer.Payload = &stanza.Command{
|
||||||
|
SessionId: command.Node,
|
||||||
|
Node: command.Node,
|
||||||
|
Status: stanza.CommandStatusCancelled,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -776,7 +793,12 @@ func handleSetQueryCommand(s xmpp.Sender, iq *stanza.IQ, command *stanza.Command
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
response := session.ProcessTransportCommand(cmdString, resource)
|
var response string
|
||||||
|
if toOk {
|
||||||
|
response, _ = session.ProcessChatCommand(toId, cmdString)
|
||||||
|
} else {
|
||||||
|
response = session.ProcessTransportCommand(cmdString, resource)
|
||||||
|
}
|
||||||
|
|
||||||
answer.Payload = &stanza.Command{
|
answer.Payload = &stanza.Command{
|
||||||
SessionId: command.Node,
|
SessionId: command.Node,
|
||||||
|
|
Loading…
Reference in a new issue