Remove message builder
This commit is contained in:
parent
b8d4b49de3
commit
b2e6d206bd
4 changed files with 116 additions and 282 deletions
|
@ -90,12 +90,7 @@ func (c *Conversations) FetchMessages(conversationId string, count int64, cursor
|
|||
return res, nil
|
||||
}
|
||||
|
||||
func (c *Conversations) SendMessage(messageBuilder *MessageBuilder) (*binary.SendMessageResponse, error) {
|
||||
payload, failedToBuild := messageBuilder.Build()
|
||||
if failedToBuild != nil {
|
||||
return nil, failedToBuild
|
||||
}
|
||||
|
||||
func (c *Conversations) SendMessage(payload *binary.SendMessagePayload) (*binary.SendMessageResponse, error) {
|
||||
actionType := binary.ActionType_SEND_MESSAGE
|
||||
|
||||
sentRequestId, sendErr := c.client.sessionHandler.completeSendMessage(actionType, true, payload)
|
||||
|
|
|
@ -1,41 +1,50 @@
|
|||
package libgm
|
||||
|
||||
import (
|
||||
"go.mau.fi/mautrix-gmessages/libgm/binary"
|
||||
"go.mau.fi/mautrix-gmessages/libgm/crypto"
|
||||
"go.mau.fi/mautrix-gmessages/libgm/util"
|
||||
)
|
||||
|
||||
type ImageType struct {
|
||||
type MediaType struct {
|
||||
Extension string
|
||||
Format string
|
||||
Type int64
|
||||
}
|
||||
|
||||
var ImageTypes = map[string]ImageType{
|
||||
"image/jpeg": {Extension: "jpeg", Format: "image/jpeg", Type: 1},
|
||||
"image/jpg": {Extension: "jpg", Format: "image/jpg", Type: 2},
|
||||
"image/png": {Extension: "png", Format: "image/png", Type: 3},
|
||||
"image/gif": {Extension: "gif", Format: "image/gif", Type: 4},
|
||||
"image/wbmp": {Extension: "wbmp", Format: "image/wbmp", Type: 5},
|
||||
"image/bmp": {Extension: "bmp", Format: "image/bmp", Type: 6},
|
||||
"image/x-ms-bmp": {Extension: "bmp", Format: "image/x-ms-bmp", Type: 6},
|
||||
"audio/aac": {Extension: "aac", Format: "audio/aac", Type: 14},
|
||||
"audio/amr": {Extension: "amr", Format: "audio/amr", Type: 15},
|
||||
"audio/mp3": {Extension: "mp3", Format: "audio/mp3", Type: 16},
|
||||
"audio/mpeg": {Extension: "mpeg", Format: "audio/mpeg", Type: 17},
|
||||
"audio/mpg": {Extension: "mpg", Format: "audio/mpg", Type: 18},
|
||||
"audio/mp4": {Extension: "mp4", Format: "audio/mp4", Type: 19},
|
||||
"audio/mp4-latm": {Extension: "latm", Format: "audio/mp4-latm", Type: 20},
|
||||
"audio/3gpp": {Extension: "3gpp", Format: "audio/3gpp", Type: 21},
|
||||
"audio/ogg": {Extension: "ogg", Format: "audio/ogg", Type: 22},
|
||||
"video/mp4": {Extension: "mp4", Format: "video/mp4", Type: 8},
|
||||
"video/3gpp2": {Extension: "3gpp2", Format: "video/3gpp2", Type: 9},
|
||||
"video/3gpp": {Extension: "3gpp", Format: "video/3gpp", Type: 10},
|
||||
"video/webm": {Extension: "webm", Format: "video/webm", Type: 11},
|
||||
"video/x-matroska": {Extension: "mkv", Format: "video/x-matroska", Type: 12},
|
||||
var MediaTypes = map[string]MediaType{
|
||||
"image/jpeg": {Extension: "jpeg", Format: "image/jpeg", Type: 1},
|
||||
"image/jpg": {Extension: "jpg", Format: "image/jpg", Type: 2},
|
||||
"image/png": {Extension: "png", Format: "image/png", Type: 3},
|
||||
"image/gif": {Extension: "gif", Format: "image/gif", Type: 4},
|
||||
"image/wbmp": {Extension: "wbmp", Format: "image/wbmp", Type: 5},
|
||||
"image/bmp": {Extension: "bmp", Format: "image/bmp", Type: 6},
|
||||
"image/x-ms-bmp": {Extension: "bmp", Format: "image/x-ms-bmp", Type: 6},
|
||||
"image": {Type: 7},
|
||||
|
||||
"video/mp4": {Extension: "mp4", Format: "video/mp4", Type: 8},
|
||||
"video/3gpp2": {Extension: "3gpp2", Format: "video/3gpp2", Type: 9},
|
||||
"video/3gpp": {Extension: "3gpp", Format: "video/3gpp", Type: 10},
|
||||
"video/webm": {Extension: "webm", Format: "video/webm", Type: 11},
|
||||
"video/x-matroska": {Extension: "mkv", Format: "video/x-matroska", Type: 12},
|
||||
"video": {Type: 13},
|
||||
|
||||
"audio/aac": {Extension: "aac", Format: "audio/aac", Type: 14},
|
||||
"audio/amr": {Extension: "amr", Format: "audio/amr", Type: 15},
|
||||
"audio/mp3": {Extension: "mp3", Format: "audio/mp3", Type: 16},
|
||||
"audio/mpeg": {Extension: "mpeg", Format: "audio/mpeg", Type: 17},
|
||||
"audio/mpg": {Extension: "mpg", Format: "audio/mpg", Type: 18},
|
||||
"audio/mp4": {Extension: "mp4", Format: "audio/mp4", Type: 19},
|
||||
"audio/mp4-latm": {Extension: "latm", Format: "audio/mp4-latm", Type: 20},
|
||||
"audio/3gpp": {Extension: "3gpp", Format: "audio/3gpp", Type: 21},
|
||||
"audio/ogg": {Extension: "ogg", Format: "audio/ogg", Type: 22},
|
||||
"auidio": {Type: 23},
|
||||
|
||||
"text/vcard": {Extension: "vcard", Format: "text/vcard", Type: 24},
|
||||
"text/x-vcard": {Extension: "vcard", Format: "text/x-vcard", Type: 24},
|
||||
"application/pdf": {Extension: "pdf", Format: "application/pdf", Type: 25},
|
||||
"application/txt": {Extension: "txt", Format: "application/txt", Type: 26},
|
||||
"application/html": {Extension: "html", Format: "application/html", Type: 27},
|
||||
"text/plain": {Extension: "txt", Format: "text/plain", Type: 26},
|
||||
"text/html": {Extension: "html", Format: "text/html", Type: 27},
|
||||
"application/msword": {Extension: "doc", Format: "application/msword", Type: 28},
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": {Extension: "docx", Format: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", Type: 29},
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation": {Extension: "pptx", Format: "application/vnd.openxmlformats-officedocument.presentationml.presentation", Type: 30},
|
||||
|
@ -51,8 +60,6 @@ var ImageTypes = map[string]ImageType{
|
|||
"application/vcs": {Extension: "vcs", Format: "application/vcs", Type: 41},
|
||||
"application/ics": {Extension: "ics", Format: "application/ics", Type: 42},
|
||||
"application/hbs-vcs": {Extension: "vcs", Format: "application/hbs-vcs", Type: 43},
|
||||
"text/vcard": {Extension: "vcard", Format: "text/vcard", Type: 24},
|
||||
"text/x-vcard": {Extension: "vcard", Format: "text/x-vcard", Type: 24},
|
||||
}
|
||||
|
||||
type Image struct {
|
||||
|
@ -60,7 +67,7 @@ type Image struct {
|
|||
|
||||
imageName string
|
||||
imageID string
|
||||
imageType ImageType
|
||||
imageType MediaType
|
||||
imageBytes []byte
|
||||
imageSize int64
|
||||
}
|
||||
|
@ -89,7 +96,7 @@ func (i *Image) GetImageSize() int64 {
|
|||
return i.imageSize
|
||||
}
|
||||
|
||||
func (i *Image) GetImageType() ImageType {
|
||||
func (i *Image) GetImageType() MediaType {
|
||||
return i.imageType
|
||||
}
|
||||
|
||||
|
@ -100,52 +107,42 @@ func (i *Image) GetImageID() string {
|
|||
// This is the equivalent of dragging an image into the window on messages web
|
||||
//
|
||||
// Keep in mind that adding an image to a MessageBuilder will also upload the image to googles server
|
||||
func (mb *MessageBuilder) AddImage(imgBytes []byte, mime string) *MessageBuilder {
|
||||
if mb.err != nil {
|
||||
return mb
|
||||
}
|
||||
|
||||
newImage, newImageErr := mb.newImageData(imgBytes, mime)
|
||||
if newImageErr != nil {
|
||||
mb.err = newImageErr
|
||||
return mb
|
||||
}
|
||||
|
||||
startUploadImage, failedUpload := mb.client.StartUploadMedia(newImage)
|
||||
if failedUpload != nil {
|
||||
mb.err = failedUpload
|
||||
return mb
|
||||
}
|
||||
|
||||
finalizedImage, failedFinalize := mb.client.FinalizeUploadMedia(startUploadImage)
|
||||
if failedFinalize != nil {
|
||||
mb.err = failedFinalize
|
||||
return mb
|
||||
}
|
||||
|
||||
mb.images = append(mb.images, finalizedImage)
|
||||
return mb
|
||||
}
|
||||
|
||||
func (mb *MessageBuilder) newImageData(imgBytes []byte, mime string) (*Image, error) {
|
||||
// TODO explode on unsupported types
|
||||
imgType := ImageTypes[mime]
|
||||
imageId := util.GenerateImageID()
|
||||
imageName := util.RandStr(8) + "." + imgType.Extension
|
||||
func (c *Client) UploadMedia(data []byte, mime string) (*binary.MediaContent, error) {
|
||||
mediaType := MediaTypes[mime]
|
||||
mediaID := util.GenerateImageID()
|
||||
fileName := util.RandStr(8) + "." + mediaType.Extension
|
||||
decryptionKey, err := crypto.GenerateKey(32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
imageCryptor, cryptorErr := crypto.NewImageCryptor(decryptionKey)
|
||||
if cryptorErr != nil {
|
||||
return nil, cryptorErr
|
||||
cryptor, err := crypto.NewImageCryptor(decryptionKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Image{
|
||||
imageCryptor: imageCryptor,
|
||||
imageID: imageId,
|
||||
imageBytes: imgBytes,
|
||||
imageType: imgType,
|
||||
imageSize: int64(len(imgBytes)),
|
||||
imageName: imageName,
|
||||
image := &Image{
|
||||
imageCryptor: cryptor,
|
||||
imageID: mediaID,
|
||||
imageBytes: data,
|
||||
imageType: mediaType,
|
||||
imageSize: int64(len(data)),
|
||||
imageName: fileName,
|
||||
}
|
||||
|
||||
startUploadImage, err := c.StartUploadMedia(image)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
upload, err := c.FinalizeUploadMedia(startUploadImage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &binary.MediaContent{
|
||||
Format: binary.MediaFormats(image.GetImageType().Type),
|
||||
MediaID: upload.MediaID,
|
||||
MediaName: image.GetImageName(),
|
||||
Size: image.GetImageSize(),
|
||||
DecryptionKey: image.GetImageCryptor().GetKey(),
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -1,186 +0,0 @@
|
|||
package libgm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"go.mau.fi/mautrix-gmessages/libgm/binary"
|
||||
"go.mau.fi/mautrix-gmessages/libgm/util"
|
||||
)
|
||||
|
||||
var (
|
||||
errContentNotSet = errors.New("failed to build MessageBuilder: content must be larger than length 0")
|
||||
errConversationIdNotSet = errors.New("failed to build MessageBuilder: conversationID is empty")
|
||||
errSelfParticipantIdNotSet = errors.New("failed to build MessageBuilder: selfParticipantID is empty")
|
||||
)
|
||||
|
||||
type MessageBuilder struct {
|
||||
client *Client
|
||||
|
||||
content string
|
||||
conversationID string
|
||||
tmpID string
|
||||
selfParticipantID string
|
||||
|
||||
replyToMessageID string
|
||||
|
||||
images []*MediaUpload
|
||||
|
||||
err error
|
||||
}
|
||||
|
||||
func (mb *MessageBuilder) Err() error {
|
||||
return mb.err
|
||||
}
|
||||
|
||||
func (mb *MessageBuilder) GetImages() []*MediaUpload {
|
||||
return mb.images
|
||||
}
|
||||
|
||||
func (mb *MessageBuilder) GetContent() string {
|
||||
return mb.content
|
||||
}
|
||||
|
||||
func (mb *MessageBuilder) GetConversationID() string {
|
||||
return mb.conversationID
|
||||
}
|
||||
|
||||
func (mb *MessageBuilder) GetSelfParticipantID() string {
|
||||
return mb.selfParticipantID
|
||||
}
|
||||
|
||||
func (mb *MessageBuilder) GetTmpID() string {
|
||||
return mb.tmpID
|
||||
}
|
||||
|
||||
func (mb *MessageBuilder) SetContent(content string) *MessageBuilder {
|
||||
mb.content = content
|
||||
return mb
|
||||
}
|
||||
|
||||
func (mb *MessageBuilder) SetConversationID(conversationId string) *MessageBuilder {
|
||||
mb.conversationID = conversationId
|
||||
return mb
|
||||
}
|
||||
|
||||
// sendmessage function will set this automatically but if u want to set it yourself feel free
|
||||
func (mb *MessageBuilder) SetSelfParticipantID(participantId string) *MessageBuilder {
|
||||
mb.selfParticipantID = participantId
|
||||
return mb
|
||||
}
|
||||
|
||||
// messageID of the message to reply to
|
||||
func (mb *MessageBuilder) SetReplyMessage(messageId string) *MessageBuilder {
|
||||
mb.replyToMessageID = messageId
|
||||
return mb
|
||||
}
|
||||
|
||||
// sendmessage function will set this automatically but if u want to set it yourself feel free
|
||||
func (mb *MessageBuilder) SetTmpID(tmpId string) *MessageBuilder {
|
||||
mb.tmpID = tmpId
|
||||
return mb
|
||||
}
|
||||
|
||||
func (mb *MessageBuilder) Build() (*binary.SendMessagePayload, error) {
|
||||
|
||||
if mb.conversationID == "" {
|
||||
return nil, errConversationIdNotSet
|
||||
}
|
||||
|
||||
if mb.selfParticipantID == "" {
|
||||
return nil, errSelfParticipantIdNotSet
|
||||
}
|
||||
|
||||
if mb.content == "" {
|
||||
return nil, errContentNotSet
|
||||
}
|
||||
|
||||
if mb.tmpID == "" {
|
||||
mb.tmpID = util.GenerateTmpID()
|
||||
}
|
||||
|
||||
return mb.newSendConversationMessage(), nil
|
||||
}
|
||||
|
||||
func (c *Client) NewMessageBuilder() *MessageBuilder {
|
||||
mb := &MessageBuilder{
|
||||
client: c,
|
||||
}
|
||||
|
||||
tmpId := util.GenerateTmpID()
|
||||
mb.SetTmpID(tmpId)
|
||||
|
||||
return mb
|
||||
}
|
||||
|
||||
func (mb *MessageBuilder) newSendConversationMessage() *binary.SendMessagePayload {
|
||||
|
||||
convId := mb.GetConversationID()
|
||||
content := mb.GetContent()
|
||||
selfParticipantId := mb.GetSelfParticipantID()
|
||||
tmpId := mb.GetTmpID()
|
||||
|
||||
messageInfo := make([]*binary.MessageInfo, 0)
|
||||
messageInfo = append(messageInfo, &binary.MessageInfo{Data: &binary.MessageInfo_MessageContent{
|
||||
MessageContent: &binary.MessageContent{
|
||||
Content: content,
|
||||
},
|
||||
}})
|
||||
|
||||
mb.appendImagesPayload(&messageInfo)
|
||||
|
||||
sendMsgPayload := &binary.SendMessagePayload{
|
||||
ConversationID: convId,
|
||||
MessagePayload: &binary.MessagePayload{
|
||||
TmpID: tmpId,
|
||||
ConversationID: convId,
|
||||
SelfParticipantID: selfParticipantId,
|
||||
MessageInfo: messageInfo,
|
||||
TmpID2: tmpId,
|
||||
},
|
||||
TmpID: tmpId,
|
||||
}
|
||||
|
||||
if len(content) > 0 {
|
||||
sendMsgPayload.MessagePayload.MessagePayloadContent = &binary.MessagePayloadContent{
|
||||
MessageContent: &binary.MessageContent{
|
||||
Content: content,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if mb.replyToMessageID != "" {
|
||||
sendMsgPayload.IsReply = true
|
||||
sendMsgPayload.Reply = &binary.ReplyPayload{MessageID: mb.replyToMessageID}
|
||||
}
|
||||
|
||||
mb.client.Logger.Debug().Any("sendMsgPayload", sendMsgPayload).Msg("sendMessagePayload")
|
||||
|
||||
return sendMsgPayload
|
||||
}
|
||||
|
||||
func (mb *MessageBuilder) appendImagesPayload(messageInfo *[]*binary.MessageInfo) {
|
||||
if len(mb.images) <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for _, media := range mb.images {
|
||||
imgData := mb.newImageContent(media)
|
||||
*messageInfo = append(*messageInfo, imgData)
|
||||
}
|
||||
}
|
||||
|
||||
func (mb *MessageBuilder) newImageContent(media *MediaUpload) *binary.MessageInfo {
|
||||
imageMessage := &binary.MessageInfo{
|
||||
Data: &binary.MessageInfo_MediaContent{
|
||||
MediaContent: &binary.MediaContent{
|
||||
Format: binary.MediaFormats(media.Image.GetImageType().Type),
|
||||
MediaID: media.MediaID,
|
||||
MediaName: media.Image.GetImageName(),
|
||||
Size: media.Image.GetImageSize(),
|
||||
DecryptionKey: media.Image.GetImageCryptor().GetKey(),
|
||||
},
|
||||
},
|
||||
}
|
||||
mb.client.Logger.Debug().Any("imageMessage", imageMessage).Msg("New Media Content")
|
||||
return imageMessage
|
||||
}
|
66
portal.go
66
portal.go
|
@ -1207,7 +1207,24 @@ func (portal *Portal) HandleMatrixMessage(sender *User, evt *event.Event, timing
|
|||
return
|
||||
}
|
||||
|
||||
var replyToID string
|
||||
txnID := util.GenerateTmpID()
|
||||
portal.outgoingMessagesLock.Lock()
|
||||
portal.outgoingMessages[txnID] = &outgoingMessage{Event: evt}
|
||||
portal.outgoingMessagesLock.Unlock()
|
||||
if evt.Type == event.EventSticker {
|
||||
content.MsgType = event.MsgImage
|
||||
}
|
||||
req := &binary.SendMessagePayload{
|
||||
ConversationID: portal.ID,
|
||||
TmpID: txnID,
|
||||
MessagePayload: &binary.MessagePayload{
|
||||
ConversationID: portal.ID,
|
||||
TmpID: txnID,
|
||||
TmpID2: txnID,
|
||||
SelfParticipantID: portal.SelfUserID,
|
||||
},
|
||||
}
|
||||
|
||||
replyToMXID := content.RelatesTo.GetReplyTo()
|
||||
if replyToMXID != "" {
|
||||
replyToMsg, err := portal.bridge.DB.Message.GetByMXID(ctx, replyToMXID)
|
||||
|
@ -1216,35 +1233,46 @@ func (portal *Portal) HandleMatrixMessage(sender *User, evt *event.Event, timing
|
|||
} else if replyToMsg == nil {
|
||||
log.Warn().Str("reply_to_mxid", replyToMXID.String()).Msg("Reply target message not found")
|
||||
} else {
|
||||
replyToID = replyToMsg.ID
|
||||
req.IsReply = true
|
||||
req.Reply = &binary.ReplyPayload{MessageID: replyToMsg.ID}
|
||||
}
|
||||
}
|
||||
|
||||
txnID := util.GenerateTmpID()
|
||||
portal.outgoingMessagesLock.Lock()
|
||||
portal.outgoingMessages[txnID] = &outgoingMessage{Event: evt}
|
||||
portal.outgoingMessagesLock.Unlock()
|
||||
switch content.MsgType {
|
||||
case event.MsgText, event.MsgEmote, event.MsgNotice:
|
||||
text := content.Body
|
||||
if content.MsgType == event.MsgEmote {
|
||||
text = "/me " + text
|
||||
}
|
||||
_, err := sender.Client.Conversations.SendMessage(
|
||||
sender.Client.NewMessageBuilder().
|
||||
SetConversationID(portal.ID).
|
||||
SetSelfParticipantID(portal.SelfUserID).
|
||||
SetReplyMessage(replyToID).
|
||||
SetContent(text).
|
||||
SetTmpID(txnID),
|
||||
)
|
||||
if err != nil {
|
||||
go ms.sendMessageMetrics(evt, err, "Error sending", true)
|
||||
} else {
|
||||
go ms.sendMessageMetrics(evt, nil, "", true)
|
||||
}
|
||||
req.MessagePayload.MessageInfo = []*binary.MessageInfo{{
|
||||
Data: &binary.MessageInfo_MessageContent{MessageContent: &binary.MessageContent{
|
||||
Content: text,
|
||||
}},
|
||||
}}
|
||||
case event.MsgImage, event.MsgVideo, event.MsgAudio, event.MsgFile:
|
||||
//fileName := content.Body
|
||||
//if content.FileName != "" {
|
||||
// fileName = content.FileName
|
||||
//}
|
||||
//sender.Client.StartUploadMedia()
|
||||
//req.MessagePayload.MessageInfo = []*binary.MessageInfo{{
|
||||
// Data: &binary.MessageInfo_MediaContent{MediaContent: &binary.MediaContent{
|
||||
// Format: 0,
|
||||
// MediaID: mediaID,
|
||||
// MediaName: fileName,
|
||||
// Size: int64(len(data)),
|
||||
// DecryptionKey: decryptionKey,
|
||||
// }},
|
||||
//}}
|
||||
default:
|
||||
go ms.sendMessageMetrics(evt, fmt.Errorf("unsupported msgtype"), "Ignoring", true)
|
||||
return
|
||||
}
|
||||
_, err := sender.Client.Conversations.SendMessage(req)
|
||||
if err != nil {
|
||||
go ms.sendMessageMetrics(evt, err, "Error sending", true)
|
||||
} else {
|
||||
go ms.sendMessageMetrics(evt, nil, "", true)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue