forked from lug/matterbridge
Update Rhymen/go-whatsapp vendor (#876)
This commit is contained in:
+183
@@ -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)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user