Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion imessage/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type API interface {
PrepareDM(guid string) error

SendMessage(chatID, text string, replyTo string, replyToPart int, richLink *RichLink, metadata MessageMetadata) (*SendResponse, error)
SendFile(chatID, text, filename string, pathOnDisk string, replyTo string, replyToPart int, mimeType string, voiceMemo bool, metadata MessageMetadata) (*SendResponse, error)
SendFile(chatID, text, filename string, pathOnDisk, guid string, replyTo string, replyToPart int, mimeType string, voiceMemo bool, metadata MessageMetadata) (*SendResponse, error)
SendFileCleanup(sendFileDir string)
SendTapback(chatID, targetGUID string, targetPart int, tapback TapbackType, remove bool) (*SendResponse, error)
SendReadReceipt(chatID, readUpTo string) error
Expand All @@ -81,6 +81,11 @@ type API interface {
Capabilities() ConnectorCapabilities
}

type FilePreparingAPI interface {
API
SendFilePrepare(filename string, data []byte) (dir, guid string, err error)
}

var TempFilePermissions os.FileMode = 0640
var TempDirPermissions os.FileMode = 0700

Expand Down
8 changes: 7 additions & 1 deletion imessage/ios/ipc.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ func timeToFloat(time time.Time) float64 {
type APIWithIPC interface {
imessage.API
SetIPC(*ipc.Processor)
GetIPC() *ipc.Processor
SetContactProxy(api imessage.ContactAPI)
SetChatInfoProxy(api imessage.ChatInfoAPI)
}
Expand Down Expand Up @@ -121,6 +122,10 @@ func (ios *iOSConnector) SetIPC(proc *ipc.Processor) {
ios.IPC = proc
}

func (ios *iOSConnector) GetIPC() *ipc.Processor {
return ios.IPC
}

func (ios *iOSConnector) SetContactProxy(api imessage.ContactAPI) {
ios.contactProxy = api
}
Expand Down Expand Up @@ -517,12 +522,13 @@ func (ios *iOSConnector) SendMessage(chatID, text string, replyTo string, replyT
return &resp, err
}

func (ios *iOSConnector) SendFile(chatID, text, filename string, pathOnDisk string, replyTo string, replyToPart int, mimeType string, voiceMemo bool, metadata imessage.MessageMetadata) (*imessage.SendResponse, error) {
func (ios *iOSConnector) SendFile(chatID, text, filename, pathOnDisk, guid, replyTo string, replyToPart int, mimeType string, voiceMemo bool, metadata imessage.MessageMetadata) (*imessage.SendResponse, error) {
var resp imessage.SendResponse
err := ios.IPC.Request(context.Background(), ReqSendMedia, &SendMediaRequest{
ChatGUID: chatID,
Text: text,
Attachment: imessage.Attachment{
GUID: guid,
FileName: filename,
PathOnDisk: pathOnDisk,
MimeType: mimeType,
Expand Down
9 changes: 9 additions & 0 deletions imessage/ios/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

const (
ReqSendMessage ipc.Command = "send_message"
ReqUploadMedia ipc.Command = "upload_media"
ReqSendMedia ipc.Command = "send_media"
ReqSendTapback ipc.Command = "send_tapback"
ReqSendReadReceipt ipc.Command = "send_read_receipt"
Expand Down Expand Up @@ -66,6 +67,14 @@ type SendMediaRequest struct {
Metadata imessage.MessageMetadata `json:"metadata,omitempty"`
}

type UploadMediaRequest struct {
PathOnDisk string `json:"path_on_disk"`
}

type UploadMediaResponse struct {
GUID string `json:"guid"`
}

type SendTapbackRequest struct {
ChatGUID string `json:"chat_guid"`
TargetGUID string `json:"target_guid"`
Expand Down
17 changes: 17 additions & 0 deletions imessage/mac-nosip/nosip.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package mac_nosip

import (
"context"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -320,6 +321,22 @@ func (mac *MacNoSIPConnector) Capabilities() imessage.ConnectorCapabilities {
}
}

func (mac *MacNoSIPConnector) SendFilePrepare(filename string, data []byte) (string, string, error) {
dir, path, err := imessage.SendFilePrepare(filename, data)
if err != nil {
return dir, "", fmt.Errorf("failed to write file to disk: %w", err)
}
var resp ios.UploadMediaResponse
ctx := context.Background()
err = mac.GetIPC().Request(ctx, ios.ReqUploadMedia, &ios.UploadMediaRequest{
PathOnDisk: path,
}, &resp)
if err != nil {
return dir, "", fmt.Errorf("failed to upload file: %w", err)
}
return dir, resp.GUID, nil
}

func init() {
imessage.Implementations["mac-nosip"] = NewMacNoSIPConnector
}
2 changes: 1 addition & 1 deletion imessage/mac/send.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func (mac *macOSDatabase) SendMessage(chatID, text string, replyTo string, reply
return nil, mac.sendMessageWithRetry(sendMessage, sendMessageWithService, sendMessageBuddy, imessage.ParseIdentifier(chatID), text)
}

func (mac *macOSDatabase) SendFile(chatID, text, filename string, pathOnDisk string, replyTo string, replyToPart int, mimeType string, voiceMemo bool, metadata imessage.MessageMetadata) (*imessage.SendResponse, error) {
func (mac *macOSDatabase) SendFile(chatID, text, filename, pathOnDisk, guid, replyTo string, replyToPart int, mimeType string, voiceMemo bool, metadata imessage.MessageMetadata) (*imessage.SendResponse, error) {
if voiceMemo {
mac.log.Warn("received a request to send a file as a voice memo, but mac does not support this. sending as regular attachment.")
}
Expand Down
11 changes: 8 additions & 3 deletions portal.go
Original file line number Diff line number Diff line change
Expand Up @@ -1313,8 +1313,13 @@ func (portal *Portal) handleMatrixMediaDirect(url id.ContentURI, file *event.Enc
}
}

var dir, filePath string
dir, filePath, err = imessage.SendFilePrepare(filename, data)
var dir, filePath, guid string
prep, ok := portal.bridge.IM.(imessage.FilePreparingAPI)
if ok {
dir, guid, err = prep.SendFilePrepare(filename, data)
} else {
dir, filePath, err = imessage.SendFilePrepare(filename, data)
}
if err != nil {
portal.log.Errorfln("failed to prepare to send file: %w", err)
return
Expand All @@ -1333,7 +1338,7 @@ func (portal *Portal) handleMatrixMediaDirect(url id.ContentURI, file *event.Enc
}
}

resp, err = portal.bridge.IM.SendFile(portal.getTargetGUID("media message", evt.ID, ""), caption, filename, filePath, messageReplyID, messageReplyPart, mimeType, isVoiceMemo, metadata)
resp, err = portal.bridge.IM.SendFile(portal.getTargetGUID("media message", evt.ID, ""), caption, filename, filePath, guid, messageReplyID, messageReplyPart, mimeType, isVoiceMemo, metadata)
portal.bridge.IM.SendFileCleanup(dir)
return
}
Expand Down