summaryrefslogtreecommitdiffstats
path: root/vendor/go.mau.fi/whatsmeow/send.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/go.mau.fi/whatsmeow/send.go')
-rw-r--r--vendor/go.mau.fi/whatsmeow/send.go133
1 files changed, 113 insertions, 20 deletions
diff --git a/vendor/go.mau.fi/whatsmeow/send.go b/vendor/go.mau.fi/whatsmeow/send.go
index 2647d917..ab754f8f 100644
--- a/vendor/go.mau.fi/whatsmeow/send.go
+++ b/vendor/go.mau.fi/whatsmeow/send.go
@@ -34,8 +34,8 @@ import (
// GenerateMessageID generates a random string that can be used as a message ID on WhatsApp.
//
-// msgID := whatsmeow.GenerateMessageID()
-// cli.SendMessage(context.Background(), targetJID, msgID, &waProto.Message{...})
+// msgID := whatsmeow.GenerateMessageID()
+// cli.SendMessage(context.Background(), targetJID, msgID, &waProto.Message{...})
func GenerateMessageID() types.MessageID {
id := make([]byte, 8)
_, err := rand.Read(id)
@@ -80,9 +80,10 @@ type SendResponse struct {
//
// The message itself can contain anything you want (within the protobuf schema).
// e.g. for a simple text message, use the Conversation field:
-// cli.SendMessage(context.Background(), targetJID, "", &waProto.Message{
-// Conversation: proto.String("Hello, World!"),
-// })
+//
+// cli.SendMessage(context.Background(), targetJID, "", &waProto.Message{
+// Conversation: proto.String("Hello, World!"),
+// })
//
// Things like replies, mentioning users and the "forwarded" flag are stored in ContextInfo,
// which can be put in ExtendedTextMessage and any of the media message types.
@@ -114,6 +115,14 @@ func (cli *Client) SendMessage(ctx context.Context, to types.JID, id types.Messa
if !isPeerMessage {
cli.addRecentMessage(to, id, message)
}
+ if message.GetMessageContextInfo().GetMessageSecret() != nil {
+ err = cli.Store.MsgSecrets.PutMessageSecret(to, *cli.Store.ID, id, message.GetMessageContextInfo().GetMessageSecret())
+ if err != nil {
+ cli.Log.Warnf("Failed to store message secret key for outgoing message %s: %v", id, err)
+ } else {
+ cli.Log.Debugf("Stored message secret key for outgoing message %s", id)
+ }
+ }
var phash string
var data []byte
switch to.Server {
@@ -163,21 +172,68 @@ func (cli *Client) SendMessage(ctx context.Context, to types.JID, id types.Messa
}
// RevokeMessage deletes the given message from everyone in the chat.
-// You can only revoke your own messages, and if the message is too old, then other users will ignore the deletion.
//
// This method will wait for the server to acknowledge the revocation message before returning.
// The return value is the timestamp of the message from the server.
+//
+// Deprecated: This method is deprecated in favor of BuildRevoke
func (cli *Client) RevokeMessage(chat types.JID, id types.MessageID) (SendResponse, error) {
- return cli.SendMessage(context.TODO(), chat, "", &waProto.Message{
+ return cli.SendMessage(context.TODO(), chat, "", cli.BuildRevoke(chat, types.EmptyJID, id))
+}
+
+// BuildRevoke builds a message revocation message using the given variables.
+// The built message can be sent normally using Client.SendMessage.
+//
+// To revoke your own messages, pass your JID or an empty JID as the second parameter (sender).
+//
+// resp, err := cli.SendMessage(context.Background(), chat, "", cli.BuildRevoke(chat, types.EmptyJID, originalMessageID)
+//
+// To revoke someone else's messages when you are group admin, pass the message sender's JID as the second parameter.
+//
+// resp, err := cli.SendMessage(context.Background(), chat, "", cli.BuildRevoke(chat, senderJID, originalMessageID)
+func (cli *Client) BuildRevoke(chat, sender types.JID, id types.MessageID) *waProto.Message {
+ key := &waProto.MessageKey{
+ FromMe: proto.Bool(true),
+ Id: proto.String(id),
+ RemoteJid: proto.String(chat.String()),
+ }
+ if !sender.IsEmpty() && sender.User != cli.Store.ID.User {
+ key.FromMe = proto.Bool(false)
+ if chat.Server != types.DefaultUserServer {
+ key.Participant = proto.String(sender.ToNonAD().String())
+ }
+ }
+ return &waProto.Message{
ProtocolMessage: &waProto.ProtocolMessage{
Type: waProto.ProtocolMessage_REVOKE.Enum(),
- Key: &waProto.MessageKey{
- FromMe: proto.Bool(true),
- Id: proto.String(id),
- RemoteJid: proto.String(chat.String()),
+ Key: key,
+ },
+ }
+}
+
+// BuildEdit builds a message edit message using the given variables.
+// The built message can be sent normally using Client.SendMessage.
+//
+// resp, err := cli.SendMessage(context.Background(), chat, "", cli.BuildEdit(chat, originalMessageID, &waProto.Message{
+// Conversation: proto.String("edited message"),
+// })
+func (cli *Client) BuildEdit(chat types.JID, id types.MessageID, newContent *waProto.Message) *waProto.Message {
+ return &waProto.Message{
+ EditedMessage: &waProto.FutureProofMessage{
+ Message: &waProto.Message{
+ ProtocolMessage: &waProto.ProtocolMessage{
+ Key: &waProto.MessageKey{
+ FromMe: proto.Bool(true),
+ Id: proto.String(id),
+ RemoteJid: proto.String(chat.String()),
+ },
+ Type: waProto.ProtocolMessage_MESSAGE_EDIT.Enum(),
+ EditedMessage: newContent,
+ TimestampMs: proto.Int64(time.Now().UnixMilli()),
+ },
},
},
- })
+ }
}
const (
@@ -362,10 +418,16 @@ func getTypeFromMessage(msg *waProto.Message) string {
switch {
case msg.ViewOnceMessage != nil:
return getTypeFromMessage(msg.ViewOnceMessage.Message)
+ case msg.ViewOnceMessageV2 != nil:
+ return getTypeFromMessage(msg.ViewOnceMessageV2.Message)
case msg.EphemeralMessage != nil:
return getTypeFromMessage(msg.EphemeralMessage.Message)
+ case msg.DocumentWithCaptionMessage != nil:
+ return getTypeFromMessage(msg.DocumentWithCaptionMessage.Message)
case msg.ReactionMessage != nil:
return "reaction"
+ case msg.PollCreationMessage != nil, msg.PollUpdateMessage != nil:
+ return "poll"
case msg.Conversation != nil, msg.ExtendedTextMessage != nil, msg.ProtocolMessage != nil:
return "text"
//TODO this requires setting mediatype in the enc nodes
@@ -376,17 +438,36 @@ func getTypeFromMessage(msg *waProto.Message) string {
}
}
+const (
+ EditAttributeEmpty = ""
+ EditAttributeMessageEdit = "1"
+ EditAttributeSenderRevoke = "7"
+ EditAttributeAdminRevoke = "8"
+)
+
+const RemoveReactionText = ""
+
func getEditAttribute(msg *waProto.Message) string {
- if msg.ProtocolMessage != nil && msg.GetProtocolMessage().GetType() == waProto.ProtocolMessage_REVOKE && msg.GetProtocolMessage().GetKey() != nil {
- if msg.GetProtocolMessage().GetKey().GetFromMe() {
- return "7"
- } else {
- return "8"
+ switch {
+ case msg.ProtocolMessage != nil && msg.ProtocolMessage.GetKey() != nil:
+ switch msg.ProtocolMessage.GetType() {
+ case waProto.ProtocolMessage_REVOKE:
+ if msg.ProtocolMessage.GetKey().GetFromMe() {
+ return EditAttributeSenderRevoke
+ } else {
+ return EditAttributeAdminRevoke
+ }
+ case waProto.ProtocolMessage_MESSAGE_EDIT:
+ if msg.EditedMessage != nil {
+ return EditAttributeMessageEdit
+ }
}
- } else if msg.ReactionMessage != nil && msg.ReactionMessage.GetText() == "" {
- return "7"
+ case msg.ReactionMessage != nil && msg.ReactionMessage.GetText() == RemoveReactionText:
+ return EditAttributeSenderRevoke
+ case msg.KeepInChatMessage != nil && msg.KeepInChatMessage.GetKey().GetFromMe() && msg.KeepInChatMessage.GetKeepType() == waProto.KeepType_UNDO_KEEP_FOR_ALL:
+ return EditAttributeSenderRevoke
}
- return ""
+ return EditAttributeEmpty
}
func (cli *Client) preparePeerMessageNode(to types.JID, id types.MessageID, message *waProto.Message, timings *MessageDebugTimings) (*waBinary.Node, error) {
@@ -450,6 +531,18 @@ func (cli *Client) prepareMessageNode(ctx context.Context, to types.JID, id type
if includeIdentity {
content = append(content, cli.makeDeviceIdentityNode())
}
+ if attrs["type"] == "poll" {
+ pollType := "creation"
+ if message.PollUpdateMessage != nil {
+ pollType = "vote"
+ }
+ content = append(content, waBinary.Node{
+ Tag: "meta",
+ Attrs: waBinary.Attrs{
+ "polltype": pollType,
+ },
+ })
+ }
return &waBinary.Node{
Tag: "message",
Attrs: attrs,