diff --git a/broker/action.go b/broker/action.go index 7247ca8..60a05fb 100644 --- a/broker/action.go +++ b/broker/action.go @@ -17,5 +17,8 @@ func executeClientCommand(action tg.ClientCommand, client net.Conn) { case tg.CmdSendPhoto: data := *(action.PhotoData) api.SendPhoto(data) + case tg.CmdForwardMessage: + data := *(action.ForwardMessageData) + api.ForwardMessage(data) } } diff --git a/broker/telegram.go b/broker/telegram.go index d179e0c..ac776fe 100644 --- a/broker/telegram.go +++ b/broker/telegram.go @@ -114,6 +114,17 @@ func (t Telegram) SendPhoto(data tg.ClientPhotoData) { checkerr("SendPhoto/http.Do", err) } +func (t Telegram) ForwardMessage(data tg.ClientForwardMessageData) { + postdata := url.Values{ + "chat_id": {strconv.FormatInt(data.ChatID, 10)}, + "from_chat_id": {strconv.FormatInt(data.FromChatID, 10)}, + "message_id": {strconv.FormatInt(data.MessageID, 10)}, + } + + _, err := http.PostForm(t.apiURL("forwardMessage"), postdata) + checkerr("ForwardMessage/http.PostForm", err) +} + // GetFile sends a "getFile" API call to Telegram's servers and fetches the file // specified afterward. The file will be then send back to the client that requested it // with the specified callback id. diff --git a/mods/remind.go b/mods/remind.go index a1c6377..02b01cf 100644 --- a/mods/remind.go +++ b/mods/remind.go @@ -16,9 +16,15 @@ import ( var remindpath *string type Reminder struct { - TargetID int64 - When int64 - Text string + TargetID int64 + When int64 + Text string + Reference *ReminderReference +} + +type ReminderReference struct { + Chat int64 + Message int64 } var reminders map[string]Reminder @@ -69,11 +75,18 @@ func remind(broker *tg.Broker, update tg.APIMessage) { } id := strconv.FormatInt(update.Chat.ChatID, 36) + "-" + strconv.FormatInt(update.MessageID, 36) - reminders[id] = Reminder{ + reminder := Reminder{ TargetID: update.User.UserID, When: timestamp.Unix(), Text: message, } + if update.ReplyTo != nil { + reminder.Reference = &ReminderReference{ + Chat: update.Chat.ChatID, + Message: update.ReplyTo.MessageID, + } + } + reminders[id] = reminder savereminder() go runreminder(id) @@ -98,6 +111,9 @@ func runreminder(id string) { } // Remind! broker.SendTextMessage(&tg.APIChat{ChatID: r.TargetID}, "Heyla! Mi avevi chiesto di ricordarti questo:\n"+r.Text, nil) + if r.Reference != nil { + broker.ForwardMessage(&tg.APIChat{ChatID: r.TargetID}, tg.APIMessage{MessageID: r.Reference.Message, Chat: &tg.APIChat{ChatID: r.Reference.Chat}}) + } // Delete reminder from pending list and save list to disk delete(reminders, id) savereminder() diff --git a/tg/broker.go b/tg/broker.go index daa20fb..2b93c44 100644 --- a/tg/broker.go +++ b/tg/broker.go @@ -63,6 +63,18 @@ func (b *Broker) SendPhoto(chat *APIChat, data []byte, filename string, caption }) } +// ForwardMessage forwards a message between chats. +func (b *Broker) ForwardMessage(chat *APIChat, message APIMessage) { + b.sendCmd(ClientCommand{ + Type: CmdForwardMessage, + ForwardMessageData: &ClientForwardMessageData{ + ChatID: chat.ChatID, + FromChatID: message.Chat.ChatID, + MessageID: message.MessageID, + }, + }) +} + // GetFile sends a file retrieval request to the Broker. // This function is asynchronous as data will be delivered to the given callback. func (b *Broker) GetFile(fileID string, fn BrokerCallback) int { diff --git a/tg/command.go b/tg/command.go index ce196c3..f14c341 100644 --- a/tg/command.go +++ b/tg/command.go @@ -33,6 +33,9 @@ const ( // CmdSendPhoto requests the broker to send a photo to a chat CmdSendPhoto ClientCommandType = "sendPhoto" + // CmdForwardMessage requests the broker to forward a message between chats + CmdForwardMessage ClientCommandType = "forwardMessage" + // CmdGetFile requests the broker to get a file from Telegram CmdGetFile ClientCommandType = "getFile" ) @@ -53,6 +56,13 @@ type ClientPhotoData struct { ReplyID *int64 `json:",omitempty"` } +// ClientForwardMessageData is the required data for a CmdForwardMessage request +type ClientForwardMessageData struct { + ChatID int64 + FromChatID int64 + MessageID int64 +} + // FileRequestData is the required data for a CmdGetFile request type FileRequestData struct { FileID string @@ -60,9 +70,10 @@ type FileRequestData struct { // ClientCommand is a request sent by clients to the broker type ClientCommand struct { - Type ClientCommandType - TextMessageData *ClientTextMessageData `json:",omitempty"` - PhotoData *ClientPhotoData `json:",omitempty"` - FileRequestData *FileRequestData `json:",omitempty"` - Callback *int `json:",omitempty"` + Type ClientCommandType + TextMessageData *ClientTextMessageData `json:",omitempty"` + PhotoData *ClientPhotoData `json:",omitempty"` + ForwardMessageData *ClientForwardMessageData `json:",omitempty"` + FileRequestData *FileRequestData `json:",omitempty"` + Callback *int `json:",omitempty"` }