Add /forward command

This commit is contained in:
Bohdan Horbeshko 2022-03-12 12:25:53 -05:00
parent c6556eb6b8
commit 022a12ce31
3 changed files with 85 additions and 49 deletions

View file

@ -59,6 +59,7 @@ var chatCommands = map[string]command{
"s": command{"edited message", "edit your last message"}, "s": command{"edited message", "edit your last message"},
"silent": command{"message", "send a message without sound"}, "silent": command{"message", "send a message without sound"},
"schedule": command{"{online | 2006-01-02T15:04:05 | 15:04:05} message", "schedules a message either to timestamp or to whenever the user goes online"}, "schedule": command{"{online | 2006-01-02T15:04:05 | 15:04:05} message", "schedules a message either to timestamp or to whenever the user goes online"},
"forward": command{"message_id target_chat", "forwards a message"},
"add": command{"@username", "add @username to your chat list"}, "add": command{"@username", "add @username to your chat list"},
"join": command{"https://t.me/invite_link", "join to chat via invite link"}, "join": command{"https://t.me/invite_link", "join to chat via invite link"},
"group": command{"title", "create groupchat «title» with current user"}, "group": command{"title", "create groupchat «title» with current user"},
@ -575,6 +576,36 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
} else { } else {
return "Message processing error", true return "Message processing error", true
} }
// forward a message to chat
case "forward":
if len(args) < 2 {
return notEnoughArguments, true
}
messageId, err := strconv.ParseInt(args[0], 10, 64)
if err != nil {
return "Cannot parse message ID", true
}
targetChatParts := strings.Split(args[1], "@") // full JIDs are supported too
targetChatId, err := strconv.ParseInt(targetChatParts[0], 10, 64)
if err != nil {
return "Cannot parse target chat ID", true
}
messages, err := c.client.ForwardMessages(&client.ForwardMessagesRequest{
ChatId: targetChatId,
FromChatId: chatID,
MessageIds: []int64{messageId},
})
if err != nil {
return err.Error(), true
}
if messages != nil && messages.Messages != nil {
for _, message := range messages.Messages {
c.ProcessIncomingMessage(targetChatId, message)
}
}
// add @contact // add @contact
case "add": case "add":
if len(args) < 1 { if len(args) < 1 {

View file

@ -192,55 +192,7 @@ func (c *Client) updateNewMessage(update *client.UpdateNewMessage) {
"chat_id": chatId, "chat_id": chatId,
}).Warn("New message from chat") }).Warn("New message from chat")
var text string c.ProcessIncomingMessage(chatId, update.Message)
content := update.Message.Content
if content != nil && content.MessageContentType() == client.TypeMessageChatChangePhoto {
chat, err := c.client.GetChat(&client.GetChatRequest{
ChatId: chatId,
})
if err == nil {
c.cache.SetChat(chatId, chat)
go c.ProcessStatusUpdate(chatId, "", "", gateway.SPImmed(true))
text = "<Chat photo has changed>"
}
} else {
text = c.messageToText(update.Message, false)
file := c.contentToFile(content)
// download file (if one)
if file != nil {
newFile, err := c.DownloadFile(file.Id, 1, true)
if err == nil {
file = newFile
}
}
// OTR support (I do not know why would you need it, seriously)
if !(strings.HasPrefix(text, "?OTR") || c.Session.RawMessages) {
var prefix strings.Builder
prefix.WriteString(c.messageToPrefix(update.Message, c.formatFile(file)))
if text != "" {
// \n if it is groupchat and message is not empty
if chatId < 0 {
prefix.WriteString("\n")
} else if chatId > 0 {
prefix.WriteString(" | ")
}
prefix.WriteString(text)
}
text = prefix.String()
}
}
// mark message as read
c.client.ViewMessages(&client.ViewMessagesRequest{
ChatId: chatId,
MessageIds: []int64{update.Message.Id},
ForceRead: true,
})
// forward message to XMPP
gateway.SendMessage(c.jid, strconv.FormatInt(chatId, 10), text, c.xmpp)
}() }()
} }

View file

@ -694,6 +694,59 @@ func (c *Client) messageToPrefix(message *client.Message, fileString string) str
return strings.Join(prefix, " | ") return strings.Join(prefix, " | ")
} }
// ProcessIncomingMessage transfers a message to XMPP side and marks it as read on Telegram side
func (c *Client) ProcessIncomingMessage(chatId int64, message *client.Message) {
var text string
content := message.Content
if content != nil && content.MessageContentType() == client.TypeMessageChatChangePhoto {
chat, err := c.client.GetChat(&client.GetChatRequest{
ChatId: chatId,
})
if err == nil {
c.cache.SetChat(chatId, chat)
go c.ProcessStatusUpdate(chatId, "", "", gateway.SPImmed(true))
text = "<Chat photo has changed>"
}
} else {
text = c.messageToText(message, false)
file := c.contentToFile(content)
// download file (if one)
if file != nil {
newFile, err := c.DownloadFile(file.Id, 1, true)
if err == nil {
file = newFile
}
}
// OTR support (I do not know why would you need it, seriously)
if !(strings.HasPrefix(text, "?OTR") || c.Session.RawMessages) {
var prefix strings.Builder
prefix.WriteString(c.messageToPrefix(message, c.formatFile(file)))
if text != "" {
// \n if it is groupchat and message is not empty
if chatId < 0 {
prefix.WriteString("\n")
} else if chatId > 0 {
prefix.WriteString(" | ")
}
prefix.WriteString(text)
}
text = prefix.String()
}
}
// mark message as read
c.client.ViewMessages(&client.ViewMessagesRequest{
ChatId: chatId,
MessageIds: []int64{message.Id},
ForceRead: true,
})
// forward message to XMPP
gateway.SendMessage(c.jid, strconv.FormatInt(chatId, 10), text, c.xmpp)
}
// ProcessOutgoingMessage executes commands or sends messages to mapped chats // ProcessOutgoingMessage executes commands or sends messages to mapped chats
func (c *Client) ProcessOutgoingMessage(chatID int64, text string, returnJid string) client.InputMessageContent { func (c *Client) ProcessOutgoingMessage(chatID int64, text string, returnJid string) client.InputMessageContent {
if !c.Online() { if !c.Online() {