diff --git a/telegram/commands.go b/telegram/commands.go index 58f4db3..17d212f 100644 --- a/telegram/commands.go +++ b/telegram/commands.go @@ -59,6 +59,7 @@ var chatCommands = map[string]command{ "s": command{"edited message", "edit your last message"}, "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"}, + "forward": command{"message_id target_chat", "forwards a message"}, "add": command{"@username", "add @username to your chat list"}, "join": command{"https://t.me/invite_link", "join to chat via invite link"}, "group": command{"title", "create groupchat «title» with current user"}, @@ -575,6 +576,36 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool) } else { 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 case "add": if len(args) < 1 { diff --git a/telegram/handlers.go b/telegram/handlers.go index a4fa39f..45f10fd 100644 --- a/telegram/handlers.go +++ b/telegram/handlers.go @@ -192,55 +192,7 @@ func (c *Client) updateNewMessage(update *client.UpdateNewMessage) { "chat_id": chatId, }).Warn("New message from chat") - var text string - 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 = "" - } - } 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) + c.ProcessIncomingMessage(chatId, update.Message) }() } diff --git a/telegram/utils.go b/telegram/utils.go index 9b72242..3511de0 100644 --- a/telegram/utils.go +++ b/telegram/utils.go @@ -694,6 +694,59 @@ func (c *Client) messageToPrefix(message *client.Message, fileString string) str 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 = "" + } + } 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 func (c *Client) ProcessOutgoingMessage(chatID int64, text string, returnJid string) client.InputMessageContent { if !c.Online() {