// // MBIMSendMessageOperation.m // kordophoned // // Created by James Magahern on 11/13/18. // Copyright © 2018 James Magahern. All rights reserved. // #import "MBIMSendMessageOperation.h" #import "IMCore_ClassDump.h" @implementation MBIMSendMessageOperation + (void)load { [super load]; } + (NSString *)endpointName { return @"sendMessage"; } - (BOOL)_sendMessage:(NSString *)messageBody toHandles:(NSArray *)handleIDs attachmentGUIDs:(NSArray *)guids { __block BOOL result = YES; dispatch_sync([[self class] sharedIMAccessQueue], ^{ IMAccount *iMessageAccount = [[IMAccountController sharedInstance] bestAccountForService:[IMServiceImpl iMessageService]]; NSMutableArray *handles = [NSMutableArray array]; for (NSString *handleID in handleIDs) { IMHandle *handle = [iMessageAccount imHandleWithID:handleID]; if (handle) { [handles addObject:handle]; } else { MBIMLogError(@"MBIMSendMessageOperation: Invalid handle ID: %@", handleID); } } IMChat *chat = nil; if (handles.count == 1) { // Single recipient IMHandle *handle = [handles firstObject]; chat = [[IMChatRegistry sharedInstance] existingChatForIMHandle:handle]; if (chat == nil) { MBIMLogInfo(@"MBIMSendMessageOperation: Creating chat with handle: %@", handle); chat = [[IMChatRegistry sharedInstance] chatForIMHandle:handle]; } } else if (handles.count > 1) { // Group chat chat = [[IMChatRegistry sharedInstance] existingChatForIMHandles:handles allowRetargeting:NO groupID:nil displayName:nil joinedChatsOnly:YES]; if (chat == nil) { MBIMLogInfo(@"MBIMSendMessageOperation: Creating group chat with handles: %@", handles); chat = [[IMChatRegistry sharedInstance] chatForIMHandles:handles]; } } else { // No handles? result = NO; } if (chat) { result = [self _sendMessage:messageBody toChat:chat attachmentGUIDs:guids]; } else { result = NO; } }); return result; } - (BOOL)_sendMessage:(NSString *)messageBody toChatWithGUID:(NSString *)chatGUID attachmentGUIDs:(NSArray *)guids { __block BOOL result = YES; dispatch_sync([[self class] sharedIMAccessQueue], ^{ IMChat *chat = [[IMChatRegistry sharedInstance] existingChatWithGUID:chatGUID]; if (!chat) { MBIMLogInfo(@"Chat does not exist: %@", chatGUID); result = NO; } else { result = [self _sendMessage:messageBody toChat:chat attachmentGUIDs:guids]; } }); return result; } - (BOOL)_sendMessage:(NSString *)messageBody toChat:(IMChat *)chat attachmentGUIDs:(NSArray *)guids { dispatch_assert_queue([[self class] sharedIMAccessQueue]); BOOL result = YES; // 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]; } [chat sendMessage:reply]; return result; } - (void)main { NSObject *response = [[HTTPErrorResponse alloc] initWithErrorCode:500]; NSError *error = nil; NSDictionary *args = [NSJSONSerialization JSONObjectWithData:self.requestBodyData options:0 error:&error]; if (error || args.count == 0) { self.serverCompletionBlock(response); return; } NSString *messageBody = [args objectForKey:@"body"]; if (!messageBody) { self.serverCompletionBlock(response); return; } NSArray *transferGUIDs = [args objectForKey:@"fileTransferGUIDs"]; if (!transferGUIDs) { transferGUIDs = @[]; } BOOL result = NO; NSString *guid = [args objectForKey:@"guid"]; NSArray *handles = [args objectForKey:@"handles"]; if (guid) { result = [self _sendMessage:messageBody toChatWithGUID:guid attachmentGUIDs:transferGUIDs]; } else if ([handles count] > 0) { result = [self _sendMessage:messageBody toHandles:handles attachmentGUIDs:transferGUIDs]; } if (result) { response = [[HTTPErrorResponse alloc] initWithErrorCode:200]; } self.serverCompletionBlock(response); } @end