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
38 changes: 21 additions & 17 deletions imessage/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,17 @@ type ContactAPI interface {
GetContactList() ([]*Contact, error)
}

type ExtraParams struct {
TraceData map[string]string
}

type API interface {
Start(readyCallback func()) error
Stop()
GetMessagesSinceDate(chatID string, minDate time.Time, backfillID string) ([]*Message, error)
GetMessagesWithLimit(chatID string, limit int, backfillID string) ([]*Message, error)
GetChatsWithMessagesAfter(minDate time.Time) ([]ChatIdentifier, error)
GetMessage(guid string) (*Message, error)
GetMessagesSinceDate(chatID string, minDate time.Time, backfillID string, extra ...ExtraParams) ([]*Message, error)
GetMessagesWithLimit(chatID string, limit int, backfillID string, extra ...ExtraParams) ([]*Message, error)
GetChatsWithMessagesAfter(minDate time.Time, extra ...ExtraParams) ([]ChatIdentifier, error)
GetMessage(guid string, extra ...ExtraParams) (*Message, error)
MessageChan() <-chan *Message
ReadReceiptChan() <-chan *ReadReceipt
TypingNotificationChan() <-chan *TypingNotification
Expand All @@ -54,22 +58,22 @@ type API interface {
MessageStatusChan() <-chan *SendMessageStatus
BackfillTaskChan() <-chan *BackfillTask
ContactAPI
GetChatInfo(chatID, threadID string) (*ChatInfo, error)
GetGroupAvatar(chatID string) (*Attachment, error)
GetChatInfo(chatID, threadID string, extra ...ExtraParams) (*ChatInfo, error)
GetGroupAvatar(chatID string, extra ...ExtraParams) (*Attachment, error)

ResolveIdentifier(identifier string) (string, error)
PrepareDM(guid string) error
ResolveIdentifier(identifier string, extra ...ExtraParams) (string, error)
PrepareDM(guid string, extra ...ExtraParams) 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)
SendMessage(chatID, text string, replyTo string, replyToPart int, richLink *RichLink, metadata MessageMetadata, extra ...ExtraParams) (*SendResponse, error)
SendFile(chatID, text, filename string, pathOnDisk string, replyTo string, replyToPart int, mimeType string, voiceMemo bool, metadata MessageMetadata, extra ...ExtraParams) (*SendResponse, error)
SendFileCleanup(sendFileDir string)
SendTapback(chatID, targetGUID string, targetPart int, tapback TapbackType, remove bool) (*SendResponse, error)
SendReadReceipt(chatID, readUpTo string) error
SendTypingNotification(chatID string, typing bool) error
SendMessageBridgeResult(chatID, messageID string, eventID id.EventID, success bool)
SendBackfillResult(chatID, backfillID string, success bool, idMap map[string][]id.EventID)
SendChatBridgeResult(guid string, mxid id.RoomID)
NotifyUpcomingMessage(eventID id.EventID)
SendTapback(chatID, targetGUID string, targetPart int, tapback TapbackType, remove bool, extra ...ExtraParams) (*SendResponse, error)
SendReadReceipt(chatID, readUpTo string, extra ...ExtraParams) error
SendTypingNotification(chatID string, typing bool, extra ...ExtraParams) error
SendMessageBridgeResult(chatID, messageID string, eventID id.EventID, success bool, extra ...ExtraParams)
SendBackfillResult(chatID, backfillID string, success bool, idMap map[string][]id.EventID, extra ...ExtraParams)
SendChatBridgeResult(guid string, mxid id.RoomID, extra ...ExtraParams)
NotifyUpcomingMessage(eventID id.EventID, extra ...ExtraParams)

PreStartupSyncHook() (StartupSyncHookResponse, error)
PostStartupSyncHook()
Expand Down
96 changes: 74 additions & 22 deletions imessage/ios/ipc.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ import (
"go.mau.fi/mautrix-imessage/ipc"
)

func firstExtraParam(params []imessage.ExtraParams) (param imessage.ExtraParams) {
if len(params) > 0 {
param = params[0]
}
return
}

const (
IncomingMessage ipc.Command = "message"
IncomingReadReceipt ipc.Command = "read_receipt"
Expand Down Expand Up @@ -374,41 +381,49 @@ func (ios *iOSConnector) handleIncomingBackfillTask(data json.RawMessage) interf
return nil
}

func (ios *iOSConnector) GetMessagesSinceDate(chatID string, minDate time.Time, backfillID string) ([]*imessage.Message, error) {
func (ios *iOSConnector) GetMessagesSinceDate(chatID string, minDate time.Time, backfillID string, extra ...imessage.ExtraParams) ([]*imessage.Message, error) {
resp := make([]*imessage.Message, 0)
err := ios.IPC.Request(context.Background(), ReqGetMessagesAfter, &GetMessagesAfterRequest{
ChatGUID: chatID,
Timestamp: timeToFloat(minDate),
BackfillID: backfillID,

TraceMeta: firstExtraParam(extra).TraceData,
}, &resp)
for _, msg := range resp {
ios.postprocessMessage(msg, "messages since date")
}
return resp, err
}

func (ios *iOSConnector) GetMessagesWithLimit(chatID string, limit int, backfillID string) ([]*imessage.Message, error) {
func (ios *iOSConnector) GetMessagesWithLimit(chatID string, limit int, backfillID string, extra ...imessage.ExtraParams) ([]*imessage.Message, error) {
resp := make([]*imessage.Message, 0)
err := ios.IPC.Request(context.Background(), ReqGetRecentMessages, &GetRecentMessagesRequest{
ChatGUID: chatID,
Limit: limit,
BackfillID: backfillID,

TraceMeta: firstExtraParam(extra).TraceData,
}, &resp)
for _, msg := range resp {
ios.postprocessMessage(msg, "messages with limit")
}
return resp, err
}

func (ios *iOSConnector) GetMessage(guid string) (resp *imessage.Message, err error) {
func (ios *iOSConnector) GetMessage(guid string, extra ...imessage.ExtraParams) (resp *imessage.Message, err error) {
return resp, ios.IPC.Request(context.Background(), ReqGetMessage, &GetMessageRequest{
GUID: guid,

TraceMeta: firstExtraParam(extra).TraceData,
}, &resp)
}

func (ios *iOSConnector) GetChatsWithMessagesAfter(minDate time.Time) (resp []imessage.ChatIdentifier, err error) {
func (ios *iOSConnector) GetChatsWithMessagesAfter(minDate time.Time, extra ...imessage.ExtraParams) (resp []imessage.ChatIdentifier, err error) {
return resp, ios.IPC.Request(context.Background(), ReqGetChats, &GetChatsRequest{
MinTimestamp: timeToFloat(minDate),

TraceMeta: firstExtraParam(extra).TraceData,
}, &resp)
}

Expand Down Expand Up @@ -461,19 +476,28 @@ func (ios *iOSConnector) GetContactList() ([]*imessage.Contact, error) {
return resp.Contacts, err
}

func (ios *iOSConnector) GetChatInfo(chatID, threadID string) (*imessage.ChatInfo, error) {
func (ios *iOSConnector) GetChatInfo(chatID, threadID string, extra ...imessage.ExtraParams) (*imessage.ChatInfo, error) {
var resp imessage.ChatInfo
err := ios.IPC.Request(context.Background(), ReqGetChat, &GetChatRequest{ChatGUID: chatID, ThreadID: threadID}, &resp)
err := ios.IPC.Request(context.Background(), ReqGetChat, &GetChatRequest{
ChatGUID: chatID,
ThreadID: threadID,

TraceMeta: firstExtraParam(extra).TraceData,
}, &resp)
return &resp, err
}

func (ios *iOSConnector) GetGroupAvatar(chatID string) (*imessage.Attachment, error) {
func (ios *iOSConnector) GetGroupAvatar(chatID string, extra ...imessage.ExtraParams) (*imessage.Attachment, error) {
var resp imessage.Attachment
err := ios.IPC.Request(context.Background(), ReqGetChatAvatar, &GetChatRequest{ChatGUID: chatID}, &resp)
err := ios.IPC.Request(context.Background(), ReqGetChatAvatar, &GetChatRequest{
ChatGUID: chatID,

TraceMeta: firstExtraParam(extra).TraceData,
}, &resp)
return &resp, err
}

func (ios *iOSConnector) SendMessage(chatID, text string, replyTo string, replyToPart int, richLink *imessage.RichLink, metadata imessage.MessageMetadata) (*imessage.SendResponse, error) {
func (ios *iOSConnector) SendMessage(chatID, text string, replyTo string, replyToPart int, richLink *imessage.RichLink, metadata imessage.MessageMetadata, extras ...imessage.ExtraParams) (*imessage.SendResponse, error) {
var resp imessage.SendResponse
err := ios.IPC.Request(context.Background(), ReqSendMessage, &SendMessageRequest{
ChatGUID: chatID,
Expand All @@ -482,6 +506,8 @@ func (ios *iOSConnector) SendMessage(chatID, text string, replyTo string, replyT
ReplyToPart: replyToPart,
RichLink: richLink,
Metadata: metadata,

TraceMeta: firstExtraParam(extras).TraceData,
}, &resp)
if err == nil {
var warn bool
Expand All @@ -496,7 +522,7 @@ 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 string, pathOnDisk string, replyTo string, replyToPart int, mimeType string, voiceMemo bool, metadata imessage.MessageMetadata, extra ...imessage.ExtraParams) (*imessage.SendResponse, error) {
var resp imessage.SendResponse
err := ios.IPC.Request(context.Background(), ReqSendMedia, &SendMediaRequest{
ChatGUID: chatID,
Expand All @@ -510,6 +536,8 @@ func (ios *iOSConnector) SendFile(chatID, text, filename string, pathOnDisk stri
ReplyToPart: replyToPart,
IsAudioMessage: voiceMemo,
Metadata: metadata,

TraceMeta: firstExtraParam(extra).TraceData,
}, &resp)
if err == nil {
var warn bool
Expand All @@ -525,7 +553,7 @@ func (ios *iOSConnector) SendFileCleanup(sendFileDir string) {
_ = os.RemoveAll(sendFileDir)
}

func (ios *iOSConnector) SendTapback(chatID, targetGUID string, targetPart int, tapback imessage.TapbackType, remove bool) (*imessage.SendResponse, error) {
func (ios *iOSConnector) SendTapback(chatID, targetGUID string, targetPart int, tapback imessage.TapbackType, remove bool, extra ...imessage.ExtraParams) (*imessage.SendResponse, error) {
if remove {
tapback += imessage.TapbackRemoveOffset
}
Expand All @@ -535,28 +563,34 @@ func (ios *iOSConnector) SendTapback(chatID, targetGUID string, targetPart int,
TargetGUID: targetGUID,
TargetPart: targetPart,
Type: tapback,

TraceMeta: firstExtraParam(extra).TraceData,
}, &resp)
if err != nil {
return nil, err
}
return &resp, err
}

func (ios *iOSConnector) SendReadReceipt(chatID, readUpTo string) error {
func (ios *iOSConnector) SendReadReceipt(chatID, readUpTo string, extra ...imessage.ExtraParams) error {
return ios.IPC.Send(ReqSendReadReceipt, &SendReadReceiptRequest{
ChatGUID: chatID,
ReadUpTo: readUpTo,

TraceMeta: firstExtraParam(extra).TraceData,
})
}

func (ios *iOSConnector) SendTypingNotification(chatID string, typing bool) error {
func (ios *iOSConnector) SendTypingNotification(chatID string, typing bool, extra ...imessage.ExtraParams) error {
return ios.IPC.Send(ReqSetTyping, &SetTypingRequest{
ChatGUID: chatID,
Typing: typing,

TraceMeta: firstExtraParam(extra).TraceData,
})
}

func (ios *iOSConnector) SendMessageBridgeResult(chatID, messageID string, eventID id.EventID, success bool) {
func (ios *iOSConnector) SendMessageBridgeResult(chatID, messageID string, eventID id.EventID, success bool, extra ...imessage.ExtraParams) {
if !ios.isAndroid {
// Only android needs message bridging confirmations
return
Expand All @@ -566,10 +600,12 @@ func (ios *iOSConnector) SendMessageBridgeResult(chatID, messageID string, event
GUID: messageID,
EventID: eventID,
Success: success,

TraceMeta: firstExtraParam(extra).TraceData,
})
}

func (ios *iOSConnector) SendBackfillResult(chatID, backfillID string, success bool, idMap map[string][]id.EventID) {
func (ios *iOSConnector) SendBackfillResult(chatID, backfillID string, success bool, idMap map[string][]id.EventID, extra ...imessage.ExtraParams) {
if !ios.isAndroid {
// Only android needs message bridging confirmations
return
Expand All @@ -582,22 +618,30 @@ func (ios *iOSConnector) SendBackfillResult(chatID, backfillID string, success b
BackfillID: backfillID,
Success: success,
MessageIDs: idMap,

TraceMeta: firstExtraParam(extra).TraceData,
})
}

func (ios *iOSConnector) SendChatBridgeResult(guid string, mxid id.RoomID) {
func (ios *iOSConnector) SendChatBridgeResult(guid string, mxid id.RoomID, extra ...imessage.ExtraParams) {
_ = ios.IPC.Send(ReqChatBridgeResult, &ChatBridgeResult{
ChatGUID: guid,
MXID: mxid,

TraceMeta: firstExtraParam(extra).TraceData,
})
}

func (ios *iOSConnector) NotifyUpcomingMessage(eventID id.EventID) {
func (ios *iOSConnector) NotifyUpcomingMessage(eventID id.EventID, extra ...imessage.ExtraParams) {
if !ios.isAndroid {
// Only android needs to be notified about upcoming messages to stay awake
return
}
_ = ios.IPC.Send(ReqUpcomingMessage, &UpcomingMessage{EventID: eventID})
_ = ios.IPC.Send(ReqUpcomingMessage, &UpcomingMessage{
EventID: eventID,

TraceMeta: firstExtraParam(extra).TraceData,
})
}

func (ios *iOSConnector) PreStartupSyncHook() (resp imessage.StartupSyncHookResponse, err error) {
Expand All @@ -609,25 +653,33 @@ func (ios *iOSConnector) PostStartupSyncHook() {
_ = ios.IPC.Send(ReqPostStartupSync, nil)
}

func (ios *iOSConnector) ResolveIdentifier(identifier string) (string, error) {
func (ios *iOSConnector) ResolveIdentifier(identifier string, extra ...imessage.ExtraParams) (string, error) {
if ios.isAndroid {
return imessage.Identifier{
LocalID: identifier,
Service: "SMS",
IsGroup: false,
}.String(), nil
}
req := ResolveIdentifierRequest{Identifier: identifier}
req := ResolveIdentifierRequest{
Identifier: identifier,

TraceMeta: firstExtraParam(extra).TraceData,
}
var resp ResolveIdentifierResponse
err := ios.IPC.Request(context.Background(), ReqResolveIdentifier, &req, &resp)
return resp.GUID, err
}

func (ios *iOSConnector) PrepareDM(guid string) error {
func (ios *iOSConnector) PrepareDM(guid string, extra ...imessage.ExtraParams) error {
if ios.isAndroid {
return nil
}
return ios.IPC.Request(context.Background(), ReqPrepareDM, &PrepareDMRequest{GUID: guid}, nil)
return ios.IPC.Request(context.Background(), ReqPrepareDM, &PrepareDMRequest{
GUID: guid,

TraceMeta: firstExtraParam(extra).TraceData,
}, nil)
}

func (ios *iOSConnector) Capabilities() imessage.ConnectorCapabilities {
Expand Down
Loading