new message: initial commit
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
|
||||
#import "IMCore_ClassDump.h"
|
||||
#import "IMMessageItem+Encoded.h"
|
||||
#import "MBIMErrorResponse.h"
|
||||
|
||||
@implementation MBIMSendMessageOperation
|
||||
|
||||
@@ -20,40 +21,93 @@
|
||||
return @"sendMessage";
|
||||
}
|
||||
|
||||
- (IMMessage *)_sendMessage:(NSString *)messageBody toChatWithGUID:(NSString *)chatGUID attachmentGUIDs:(NSArray<NSString *> *)guids
|
||||
- (nullable IMChat *)_chatForHandleIDs:(NSArray<NSString *> *)handleIDs registry:(IMChatRegistry *)registry
|
||||
{
|
||||
__block IMMessage *result = nil;
|
||||
|
||||
dispatch_sync([[self class] sharedIMAccessQueue], ^{
|
||||
IMChat *chat = [[IMChatRegistry sharedInstance] existingChatWithGUID:chatGUID];
|
||||
|
||||
// TODO: chat might not be an iMessage chat!
|
||||
IMAccount *iMessageAccount = [[IMAccountController sharedInstance] bestAccountForService:[IMServiceImpl iMessageService]];
|
||||
IMHandle *senderHandle = [iMessageAccount loginIMHandle];
|
||||
|
||||
NSAttributedString *replyAttrString = [[NSAttributedString alloc] initWithString:messageBody];
|
||||
NSAttributedString *attrStringWithFileTransfers = IMCreateSuperFormatStringWithAppendedFileTransfers(replyAttrString, guids);
|
||||
|
||||
IMMessage *reply = [IMMessage fromMeIMHandle:senderHandle
|
||||
withText:attrStringWithFileTransfers
|
||||
fileTransferGUIDs:guids
|
||||
flags:(kIMMessageFinished | kIMMessageIsFromMe)];
|
||||
|
||||
for (NSString *guid in [reply fileTransferGUIDs]) {
|
||||
[[IMFileTransferCenter sharedInstance] assignTransfer:guid toHandle:chat.recipient];
|
||||
IMAccount *iMessageAccount = [[IMAccountController sharedInstance] bestAccountForService:[IMServiceImpl iMessageService]];
|
||||
if (!iMessageAccount) {
|
||||
MBIMLogError(@"Unable to find an iMessage account for message send.");
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSMutableArray<IMHandle *> *handles = [NSMutableArray arrayWithCapacity:[handleIDs count]];
|
||||
for (NSString *handleID in handleIDs) {
|
||||
IMHandle *handle = [iMessageAccount imHandleWithID:handleID];
|
||||
if (!handle) {
|
||||
MBIMLogError(@"Couldn't resolve IMHandle for id %@", handleID);
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
[handles addObject:handle];
|
||||
}
|
||||
|
||||
if ([handles count] == 1) {
|
||||
IMHandle *handle = [handles firstObject];
|
||||
IMChat *chat = [registry existingChatWithHandle:handle allowAlternativeService:NO];
|
||||
if (!chat) {
|
||||
MBIMLogInfo(@"Chat does not exist: %@", chatGUID);
|
||||
} else {
|
||||
result = reply;
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[chat sendMessage:reply];
|
||||
});
|
||||
chat = [registry chatWithHandle:handle];
|
||||
}
|
||||
|
||||
return chat;
|
||||
}
|
||||
|
||||
IMChat *chat = [registry existingChatWithHandles:handles
|
||||
allowAlternativeService:NO
|
||||
groupID:nil
|
||||
displayName:nil
|
||||
joinedChatsOnly:YES];
|
||||
|
||||
if (!chat) {
|
||||
chat = [registry chatWithHandles:handles displayName:nil joinedChatsOnly:YES];
|
||||
}
|
||||
|
||||
return chat;
|
||||
}
|
||||
|
||||
- (nullable NSDictionary *)_sendMessage:(NSString *)messageBody toChat:(IMChat *)chat attachmentGUIDs:(NSArray<NSString *> *)guids includeConversationGUID:(BOOL)includeConversationGUID
|
||||
{
|
||||
if (!chat) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
IMAccount *sendingAccount = [chat account];
|
||||
if (!sendingAccount) {
|
||||
sendingAccount = [[IMAccountController sharedInstance] bestAccountForService:[IMServiceImpl iMessageService]];
|
||||
}
|
||||
|
||||
IMHandle *senderHandle = [sendingAccount loginIMHandle];
|
||||
if (!senderHandle) {
|
||||
MBIMLogError(@"Unable to determine sender handle for message send.");
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSAttributedString *replyAttrString = [[NSAttributedString alloc] initWithString:messageBody];
|
||||
NSAttributedString *attrStringWithFileTransfers = IMCreateSuperFormatStringWithAppendedFileTransfers(replyAttrString, guids);
|
||||
|
||||
IMMessage *reply = [IMMessage fromMeIMHandle:senderHandle
|
||||
withText:attrStringWithFileTransfers
|
||||
fileTransferGUIDs:guids
|
||||
flags:(kIMMessageFinished | kIMMessageIsFromMe)];
|
||||
|
||||
for (NSString *guid in [reply fileTransferGUIDs]) {
|
||||
[[IMFileTransferCenter sharedInstance] assignTransfer:guid toMessage:reply account:sendingAccount];
|
||||
}
|
||||
|
||||
NSMutableDictionary *result = [[reply mbim_dictionaryRepresentation] mutableCopy];
|
||||
if (includeConversationGUID) {
|
||||
NSString *conversationGUID = [chat guid];
|
||||
if (!conversationGUID) {
|
||||
conversationGUID = [[[IMChatRegistry sharedInstance] allGUIDsForChat:chat] firstObject];
|
||||
}
|
||||
|
||||
if (conversationGUID) {
|
||||
result[@"conversationGUID"] = conversationGUID;
|
||||
}
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[chat sendMessage:reply];
|
||||
});
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -79,7 +133,7 @@
|
||||
|
||||
- (void)main
|
||||
{
|
||||
NSObject<HTTPResponse> *response = [[HTTPErrorResponse alloc] initWithErrorCode:500];
|
||||
__block NSObject<HTTPResponse> *response = [[HTTPErrorResponse alloc] initWithErrorCode:500];
|
||||
|
||||
NSError *error = nil;
|
||||
NSDictionary *args = [NSJSONSerialization JSONObjectWithData:self.requestBodyData options:0 error:&error];
|
||||
@@ -90,31 +144,70 @@
|
||||
|
||||
NSString *guid = [args objectForKey:@"guid"];
|
||||
NSString *messageBody = [args objectForKey:@"body"];
|
||||
if (!guid || !messageBody) {
|
||||
NSArray *rawHandleIDs = [args objectForKey:@"handleIDs"];
|
||||
BOOL hasGUID = [guid isKindOfClass:[NSString class]] && [guid length] > 0;
|
||||
BOOL hasHandleIDs = [rawHandleIDs isKindOfClass:[NSArray class]] && [rawHandleIDs count] > 0;
|
||||
|
||||
if (![messageBody isKindOfClass:[NSString class]] || (!hasGUID && !hasHandleIDs) || (hasGUID && hasHandleIDs)) {
|
||||
response = [[MBIMErrorResponse alloc] initWithErrorCode:500 message:@"sendMessage requires body and exactly one of guid or handleIDs."];
|
||||
self.serverCompletionBlock(response);
|
||||
return;
|
||||
}
|
||||
|
||||
// tapbacks
|
||||
#if 0
|
||||
IMMessage *acknowledgment = [IMMessage instantMessageWithAssociatedMessageContent: /* [NSString stringWithFormat:@"%@ \"%%@\"", tapbackAction] */
|
||||
flags:0
|
||||
associatedMessageGUID:guid
|
||||
associatedMessageType:IMAssociatedMessageTypeAcknowledgmentHeart
|
||||
associatedMessageRange:[imMessage messagePartRange]
|
||||
messageSummaryInfo:[self adjustMessageSummaryInfoForSending:message]
|
||||
threadIdentifier:[imMessage threadIdentifier]];
|
||||
#endif
|
||||
|
||||
NSArray *transferGUIDs = [args objectForKey:@"fileTransferGUIDs"];
|
||||
if (!transferGUIDs) {
|
||||
transferGUIDs = @[];
|
||||
NSMutableArray<NSString *> *handleIDs = [NSMutableArray array];
|
||||
if (hasHandleIDs) {
|
||||
for (id handleID in rawHandleIDs) {
|
||||
if ([handleID isKindOfClass:[NSString class]] && [handleID length] > 0) {
|
||||
[handleIDs addObject:handleID];
|
||||
}
|
||||
}
|
||||
|
||||
handleIDs = [[[NSOrderedSet orderedSetWithArray:handleIDs] array] mutableCopy];
|
||||
if ([handleIDs count] == 0) {
|
||||
response = [[MBIMErrorResponse alloc] initWithErrorCode:500 message:@"No valid handle IDs provided."];
|
||||
self.serverCompletionBlock(response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
IMMessage *result = [self _sendMessage:messageBody toChatWithGUID:guid attachmentGUIDs:transferGUIDs];
|
||||
if (result) {
|
||||
response = [MBIMJSONDataResponse responseWithJSONObject:[result mbim_dictionaryRepresentation]];
|
||||
|
||||
NSArray *rawTransferGUIDs = [args objectForKey:@"fileTransferGUIDs"];
|
||||
NSMutableArray<NSString *> *transferGUIDs = [NSMutableArray array];
|
||||
if ([rawTransferGUIDs isKindOfClass:[NSArray class]]) {
|
||||
for (id transferGUID in rawTransferGUIDs) {
|
||||
if ([transferGUID isKindOfClass:[NSString class]] && [transferGUID length] > 0) {
|
||||
[transferGUIDs addObject:transferGUID];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dispatch_sync([[self class] sharedIMAccessQueue], ^{
|
||||
IMChatRegistry *registry = [IMChatRegistry sharedInstance];
|
||||
IMChat *chat = nil;
|
||||
BOOL includeConversationGUID = NO;
|
||||
|
||||
if (hasGUID) {
|
||||
chat = [registry existingChatWithGUID:guid];
|
||||
if (!chat) {
|
||||
response = [[MBIMErrorResponse alloc] initWithErrorCode:500 message:@"Chat does not exist for the provided guid."];
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
chat = [self _chatForHandleIDs:handleIDs registry:registry];
|
||||
includeConversationGUID = YES;
|
||||
if (!chat) {
|
||||
response = [[MBIMErrorResponse alloc] initWithErrorCode:500 message:@"Unable to create or locate a chat for the provided handles."];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
NSDictionary *result = [self _sendMessage:messageBody
|
||||
toChat:chat
|
||||
attachmentGUIDs:transferGUIDs
|
||||
includeConversationGUID:includeConversationGUID];
|
||||
if (result) {
|
||||
response = [MBIMJSONDataResponse responseWithJSONObject:result];
|
||||
}
|
||||
});
|
||||
|
||||
self.serverCompletionBlock(response);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user