diff options
author | Wim <wim@42.be> | 2019-08-26 23:22:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-26 23:22:34 +0200 |
commit | d525f1c9e4ac39b74575052b61c4de72de794b4e (patch) | |
tree | 90f444dd4046c7d29ed08c005648c573deb484b2 /vendor/github.com/Rhymen/go-whatsapp/chat_history.go | |
parent | 921f2dfcdf1a6263220b55eb55716e497373dfcf (diff) | |
download | matterbridge-msglm-d525f1c9e4ac39b74575052b61c4de72de794b4e.tar.gz matterbridge-msglm-d525f1c9e4ac39b74575052b61c4de72de794b4e.tar.bz2 matterbridge-msglm-d525f1c9e4ac39b74575052b61c4de72de794b4e.zip |
Update Rhymen/go-whatsapp vendor (#876)
Diffstat (limited to 'vendor/github.com/Rhymen/go-whatsapp/chat_history.go')
-rw-r--r-- | vendor/github.com/Rhymen/go-whatsapp/chat_history.go | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/vendor/github.com/Rhymen/go-whatsapp/chat_history.go b/vendor/github.com/Rhymen/go-whatsapp/chat_history.go new file mode 100644 index 00000000..55c7ae63 --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/chat_history.go @@ -0,0 +1,183 @@ +package whatsapp + +import ( + "github.com/Rhymen/go-whatsapp/binary" + "github.com/Rhymen/go-whatsapp/binary/proto" + "log" + "strconv" + "time" +) + +type MessageOffsetInfo struct { + FirstMessageId string + FirstMessageOwner bool +} + +func decodeMessages(n *binary.Node) []*proto.WebMessageInfo { + + var messages = make([]*proto.WebMessageInfo, 0) + + if n == nil || n.Attributes == nil || n.Content == nil { + return messages + } + + for _, msg := range n.Content.([]interface{}) { + switch msg.(type) { + case *proto.WebMessageInfo: + messages = append(messages, msg.(*proto.WebMessageInfo)) + default: + log.Println("decodeMessages: Non WebMessage encountered") + } + } + + return messages +} + +// LoadChatMessages is useful to "scroll" messages, loading by count at a time +// if handlers == nil the func will use default handlers +// if after == true LoadChatMessages will load messages after the specified messageId, otherwise it will return +// message before the messageId +func (wac *Conn) LoadChatMessages(jid string, count int, messageId string, owner bool, after bool, handlers ...Handler) error { + if count <= 0 { + return nil + } + + if handlers == nil { + handlers = wac.handler + } + + kind := "before" + if after { + kind = "after" + } + + node, err := wac.query("message", jid, messageId, kind, + strconv.FormatBool(owner), "", count, 0) + + if err != nil { + wac.handleWithCustomHandlers(err, handlers) + return err + } + + for _, msg := range decodeMessages(node) { + wac.handleWithCustomHandlers(ParseProtoMessage(msg), handlers) + wac.handleWithCustomHandlers(msg, handlers) + } + return nil + +} + +// LoadFullChatHistory loads full chat history for the given jid +// chunkSize = how many messages to load with one query; if handlers == nil the func will use default handlers; +// pauseBetweenQueries = how much time to sleep between queries +func (wac *Conn) LoadFullChatHistory(jid string, chunkSize int, + pauseBetweenQueries time.Duration, handlers ...Handler) { + if chunkSize <= 0 { + return + } + + if handlers == nil { + handlers = wac.handler + } + + beforeMsg := "" + beforeMsgIsOwner := true + + for { + node, err := wac.query("message", jid, beforeMsg, "before", + strconv.FormatBool(beforeMsgIsOwner), "", chunkSize, 0) + + if err != nil { + wac.handleWithCustomHandlers(err, handlers) + } else { + + msgs := decodeMessages(node) + for _, msg := range msgs { + wac.handleWithCustomHandlers(ParseProtoMessage(msg), handlers) + wac.handleWithCustomHandlers(msg, handlers) + } + + if len(msgs) == 0 { + break + } + + beforeMsg = *msgs[0].Key.Id + beforeMsgIsOwner = msgs[0].Key.FromMe != nil && *msgs[0].Key.FromMe + } + + <-time.After(pauseBetweenQueries) + + } + +} + +// LoadFullChatHistoryAfter loads all messages after the specified messageId +// useful to "catch up" with the message history after some specified message +func (wac *Conn) LoadFullChatHistoryAfter(jid string, messageId string, chunkSize int, + pauseBetweenQueries time.Duration, handlers ...Handler) { + + if chunkSize <= 0 { + return + } + + if handlers == nil { + handlers = wac.handler + } + + msgOwner := true + prevNotFound := false + + for { + node, err := wac.query("message", jid, messageId, "after", + strconv.FormatBool(msgOwner), "", chunkSize, 0) + + if err != nil { + + // Whatsapp will return 404 status when there is wrong owner flag on the requested message id + if err == ErrServerRespondedWith404 { + + // this will detect two consecutive "not found" errors. + // this is done to prevent infinite loop when wrong message id supplied + if prevNotFound { + log.Println("LoadFullChatHistoryAfter: could not retrieve any messages, wrong message id?") + return + } + prevNotFound = true + + // try to reverse the owner flag and retry + if msgOwner { + // reverse initial msgOwner value and retry + msgOwner = false + + <-time.After(time.Second) + continue + } + + } + + // if the error isn't a 404 error, pass it to the error handler + wac.handleWithCustomHandlers(err, handlers) + } else { + + msgs := decodeMessages(node) + for _, msg := range msgs { + wac.handleWithCustomHandlers(ParseProtoMessage(msg), handlers) + wac.handleWithCustomHandlers(msg, handlers) + } + + if len(msgs) != chunkSize { + break + } + + messageId = *msgs[0].Key.Id + msgOwner = msgs[0].Key.FromMe != nil && *msgs[0].Key.FromMe + } + + // message was found + prevNotFound = false + + <-time.After(pauseBetweenQueries) + + } + +} |