2023-06-30 09:54:08 +00:00
|
|
|
package payload
|
|
|
|
|
2023-07-09 11:16:52 +00:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"google.golang.org/protobuf/proto"
|
|
|
|
|
|
|
|
"go.mau.fi/mautrix-gmessages/libgm/crypto"
|
2023-07-17 13:51:31 +00:00
|
|
|
"go.mau.fi/mautrix-gmessages/libgm/gmproto"
|
2023-07-09 11:16:52 +00:00
|
|
|
"go.mau.fi/mautrix-gmessages/libgm/pblite"
|
|
|
|
"go.mau.fi/mautrix-gmessages/libgm/routes"
|
2023-07-16 12:55:30 +00:00
|
|
|
"go.mau.fi/mautrix-gmessages/libgm/util"
|
2023-07-09 11:16:52 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type SendMessageBuilder struct {
|
2023-07-17 13:51:31 +00:00
|
|
|
message *gmproto.SendMessage
|
|
|
|
b64Message *gmproto.SendMessageInternal
|
2023-07-09 11:16:52 +00:00
|
|
|
|
|
|
|
err error
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *SendMessageBuilder) Err() error {
|
|
|
|
return sm.err
|
|
|
|
}
|
|
|
|
|
2023-07-17 13:51:31 +00:00
|
|
|
func NewSendMessageBuilder(tachyonAuthToken []byte, pairedDevice *gmproto.Device, requestId string, sessionId string) *SendMessageBuilder {
|
2023-07-09 11:16:52 +00:00
|
|
|
return &SendMessageBuilder{
|
2023-07-17 13:51:31 +00:00
|
|
|
message: &gmproto.SendMessage{
|
2023-07-09 11:16:52 +00:00
|
|
|
Mobile: pairedDevice,
|
2023-07-17 13:51:31 +00:00
|
|
|
MessageData: &gmproto.SendMessageData{
|
2023-07-09 11:16:52 +00:00
|
|
|
RequestID: requestId,
|
|
|
|
},
|
2023-07-17 13:51:31 +00:00
|
|
|
MessageAuth: &gmproto.SendMessageAuth{
|
2023-07-09 11:16:52 +00:00
|
|
|
RequestID: requestId,
|
|
|
|
TachyonAuthToken: tachyonAuthToken,
|
2023-07-16 12:55:30 +00:00
|
|
|
ConfigVersion: util.ConfigMessage,
|
2023-07-09 11:16:52 +00:00
|
|
|
},
|
2023-07-17 13:51:31 +00:00
|
|
|
EmptyArr: &gmproto.EmptyArr{},
|
2023-07-09 11:16:52 +00:00
|
|
|
},
|
2023-07-17 13:51:31 +00:00
|
|
|
b64Message: &gmproto.SendMessageInternal{
|
2023-07-09 11:16:52 +00:00
|
|
|
RequestID: requestId,
|
|
|
|
SessionID: sessionId,
|
2023-06-30 09:54:08 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-17 13:51:31 +00:00
|
|
|
func (sm *SendMessageBuilder) SetPairedDevice(device *gmproto.Device) *SendMessageBuilder {
|
2023-07-09 11:16:52 +00:00
|
|
|
sm.message.Mobile = device
|
|
|
|
return sm
|
|
|
|
}
|
|
|
|
|
2023-07-17 13:51:31 +00:00
|
|
|
func (sm *SendMessageBuilder) setBugleRoute(bugleRoute gmproto.BugleRoute) *SendMessageBuilder {
|
2023-07-09 11:16:52 +00:00
|
|
|
sm.message.MessageData.BugleRoute = bugleRoute
|
|
|
|
return sm
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *SendMessageBuilder) SetRequestId(requestId string) *SendMessageBuilder {
|
|
|
|
sm.message.MessageAuth.RequestID = requestId
|
|
|
|
sm.message.MessageData.RequestID = requestId
|
|
|
|
sm.b64Message.RequestID = requestId
|
|
|
|
return sm
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *SendMessageBuilder) SetSessionId(sessionId string) *SendMessageBuilder {
|
|
|
|
sm.b64Message.SessionID = sessionId
|
|
|
|
return sm
|
|
|
|
}
|
|
|
|
|
2023-07-17 13:51:31 +00:00
|
|
|
func (sm *SendMessageBuilder) SetRoute(actionType gmproto.ActionType) *SendMessageBuilder {
|
2023-07-09 11:16:52 +00:00
|
|
|
action, ok := routes.Routes[actionType]
|
|
|
|
if !ok {
|
|
|
|
sm.err = fmt.Errorf("invalid action type")
|
|
|
|
return sm
|
2023-06-30 09:54:08 +00:00
|
|
|
}
|
2023-07-09 11:16:52 +00:00
|
|
|
|
|
|
|
sm.setBugleRoute(action.BugleRoute)
|
|
|
|
sm.setMessageType(action.MessageType)
|
|
|
|
sm.b64Message.Action = action.Action
|
|
|
|
return sm
|
|
|
|
}
|
|
|
|
|
2023-07-17 13:51:31 +00:00
|
|
|
func (sm *SendMessageBuilder) setMessageType(eventType gmproto.MessageType) *SendMessageBuilder {
|
|
|
|
sm.message.MessageData.MessageTypeData = &gmproto.MessageTypeData{
|
|
|
|
EmptyArr: &gmproto.EmptyArr{},
|
2023-07-09 11:16:52 +00:00
|
|
|
MessageType: eventType,
|
|
|
|
}
|
|
|
|
return sm
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *SendMessageBuilder) SetTTL(ttl int64) *SendMessageBuilder {
|
|
|
|
sm.message.TTL = ttl
|
|
|
|
return sm
|
2023-06-30 09:54:08 +00:00
|
|
|
}
|
|
|
|
|
2023-07-16 11:36:13 +00:00
|
|
|
func (sm *SendMessageBuilder) SetEncryptedProtoMessage(message proto.Message, cryptor *crypto.AESCTRHelper) *SendMessageBuilder {
|
2023-07-15 17:43:28 +00:00
|
|
|
plaintextBytes, err := proto.Marshal(message)
|
|
|
|
if err != nil {
|
|
|
|
sm.err = err
|
|
|
|
return sm
|
|
|
|
}
|
|
|
|
|
|
|
|
encryptedBytes, err := cryptor.Encrypt(plaintextBytes)
|
|
|
|
if err != nil {
|
|
|
|
sm.err = err
|
2023-07-09 11:16:52 +00:00
|
|
|
return sm
|
2023-06-30 09:54:08 +00:00
|
|
|
}
|
2023-07-09 11:16:52 +00:00
|
|
|
|
|
|
|
sm.b64Message.EncryptedProtoData = encryptedBytes
|
|
|
|
return sm
|
2023-06-30 09:54:08 +00:00
|
|
|
}
|
|
|
|
|
2023-07-09 11:16:52 +00:00
|
|
|
func (sm *SendMessageBuilder) Build() ([]byte, error) {
|
|
|
|
if sm.err != nil {
|
|
|
|
return nil, sm.err
|
|
|
|
}
|
|
|
|
encodedMessage, err := proto.Marshal(sm.b64Message)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
sm.message.MessageData.ProtobufData = encodedMessage
|
|
|
|
|
2023-07-15 12:56:55 +00:00
|
|
|
protoJSONBytes, serializeErr := pblite.Marshal(sm.message)
|
2023-07-09 11:16:52 +00:00
|
|
|
if serializeErr != nil {
|
2023-07-09 20:32:19 +00:00
|
|
|
panic(serializeErr)
|
2023-07-09 11:16:52 +00:00
|
|
|
return nil, serializeErr
|
|
|
|
}
|
|
|
|
|
|
|
|
return protoJSONBytes, nil
|
2023-06-30 09:54:08 +00:00
|
|
|
}
|