MailCore / mailcore2

MailCore 2 provide a simple and asynchronous API to work with e-mail protocols IMAP, POP and SMTP. The API has been redesigned from ground up.
Other
2.6k stars 624 forks source link

sendOperationWithData callback not recieved #1809

Closed prabath12 closed 5 years ago

prabath12 commented 5 years ago

Recently i have been facing issue with smtp sendOperationWithData while sending the email the callback is not received but in connection logger i have seen that email has been sent.

Using oAuth2.0 for authentication purposes.

Please let me know if any has faced this issue.

Using the latest version of mailcore2

vymallesh commented 5 years ago

Hi @prabath12 ,

Are you talking about Login, i meant once you login, are you not getting any callback ?

prabath12 commented 5 years ago

No when i am sending an email using smtp with the method sendOperationWithData i am not receiving the callback

haithngn commented 5 years ago

can you show me your codes ? @prabath12

prabath12 commented 5 years ago

MCOSMTPSession smtpSession = [[MCOSMTPSession alloc] init]; smtpSession.hostname = [dataSource getSMTPHost]; smtpSession.port = [dataSource getSMTPPort]; smtpSession.username = [dataSource getUserId]; smtpSession.authType = MCOAuthTypeXOAuth2; smtpSession.OAuth2Token = [dataSource getOAuthAccessToken]; smtpSession.connectionType = MCOConnectionTypeStartTLS; //MCOConnectionTypeStartTLS; //MCOConnectionTypeClear; //MCOConnectionTypeTLS; // smtpSession.checkCertificateEnabled = NO; // set timeout [smtpSession setTimeout:[[[XCConfigManager sharedManager] getConstantForKey:CONFIG_CONSTANT_SMTP_REQUEST_TIMEOUT] doubleValue]]; [smtpSession setConnectionLogger:^(void connectionID, MCOConnectionLogType type, NSData * data) { XCLogDev(@"[CLOUDMARK] %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); }]; XCLogDev(@"[XCIMAP] SMTP INFO : %@@%@:%u", smtpSession.username, smtpSession.hostname, smtpSession.port ); XCLogDev(@"[XCIMAP] SMTP Auth Token : %@", smtpSession.OAuth2Token); return smtpSession;

self.operation = [[sessionManager getSMTPSession] sendOperationWithData:self.messageData];// rfc822 data self.isInProgress = YES; [self.operation start:^(NSError error) { @try { error = [self convertIfNetworkError:error sessionManager:sessionManager]; if(completionBlock(error)) { XCLogCDev(@"[XCIMAP] Completing Request : %@ , Error : %@", [self getId], error); [self logErrorToAnalytics:error]; self.completionBlock(error); self.isInProgress = NO; } } @catch (NSException ex) { [[XCExceptionHandler sharedInstance] handleException:ex]; } }];

vymallesh commented 5 years ago

-(void)replayMail:(NSArray )toId CC:(NSArray )ccId BCC:(NSArray )bcc subject:(NSString)_subject withText:(NSString)_withtext attachments:(NSArray)_attachmentArr originalMsg:(MCOIMAPMessage)_originalMsg messageBody:(NSString)_messageBody from:(nonnull NSString )fromEmail date:(nonnull NSDate )messageDate Session:(nonnull void (^)(bool))sessionHandler{

NSMutableArray * toAddressArr = [NSMutableArray new];
NSMutableArray * ccAddressArr = [NSMutableArray new];
NSMutableArray * bccAddressArr = [NSMutableArray new];

for (NSString *toAddress in toId) {
    MCOAddress *address = [[MCOAddress alloc] init];
    address.mailbox = toAddress;
    [toAddressArr addObject:address];
}

for (NSString *ccAddress in ccId) {
    MCOAddress *address = [[MCOAddress alloc] init];
    address.mailbox = ccAddress;
    [ccAddressArr addObject:address];
}

for (NSString *bccAddress in bcc) {
    MCOAddress *address = [[MCOAddress alloc] init];
    address.mailbox = bccAddress;
    [bccAddressArr addObject:address];
}

MCOMessageBuilder *builder = [[MCOMessageBuilder alloc] init];
builder.header.to = toAddressArr;
builder.header.cc = ccAddressArr;
builder.header.bcc = bccAddressArr;

MCOMessageHeader*replayMsgHeader = [[MCOMessageHeader alloc]init];

// replayMsgHeader = [_originalMsg.header replyHeaderWithExcludedRecipients:nil]; NSStringreplaySub = replayMsgHeader.subject; // MCOAddress recipents = (MCOAddress*)replayMsgHeader.to;

NSString*replayDate = [NSDateFormatter localizedStringFromDate:messageDate dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterMediumStyle];

// MCOAddress from = [[MCOAddress alloc]init]; // builder.header.from = (MCOAddress ) fromEmail;

MCOAddress * fromAddress = [[MCOAddress alloc]init];
fromAddress.mailbox = fromEmail;
builder.header.from = fromAddress;

NSString*fromEmailStr = fromEmail;

NSString*replayMsgBody = [NSString stringWithFormat:@"%@ \n\n\n on %@ %@ %@ \n \n %@",_withtext,replayDate,fromEmailStr,@"wrote",_messageBody];

builder.header.subject = replaySub;
builder.textBody = replayMsgBody;

for (AttachmentModel * attachmentObj in _attachmentArr) {

    MCOAttachment *mcoAttachmentFile = [MCOAttachment attachmentWithContentsOfFile:attachmentObj.name];
    mcoAttachmentFile.mimeType = attachmentObj.mimeType;
    mcoAttachmentFile.filename = [NSString stringWithFormat:@"%@%@",attachmentObj.name,attachmentObj.fileExtension];
    mcoAttachmentFile.data = attachmentObj.imageData;
    [builder addAttachment:mcoAttachmentFile];

}

NSData * rfc822Data = [builder data];

MCOSMTPSendOperation *sendOperation =
[smtpSession sendOperationWithData:rfc822Data];
[sendOperation start:^(NSError *error) {
    if(error) {
        NSLog(@"Error sending email: %@", error);
        sessionHandler(NO);

    } else {
        NSLog(@"Successfully sent email!");
        sessionHandler(YES);
    }
}];

}

You can try this one @prabath12 .. and let me know whether it is working or not..

vymallesh commented 5 years ago

@haithngn .. I have few queries in MCOIMAPFetchMessagesOperation..

I am using below code for Mail Sync which were already downloaded

int start =  1;

int lastUID = [[[NSUserDefaults standardUserDefaults]valueForKey:@"lastUID"]intValue];

MCOIndexSet *UIDS = [MCOIndexSet indexSetWithRange:MCORangeMake(start, UINT64_MAX)];

MCOIMAPFetchMessagesOperation * op = [session syncMessagesByUIDWithFolder:@"INBOX"
                                                              requestKind:MCOIMAPMessagesRequestKindUid
                                                                     uids:UIDS
                                                                   modSeq:lastUID];
[op start:^(NSError * __nullable error, NSArray * messages, MCOIndexSet * vanishedMessages) {
    NSLog(@"added or modified messages: %@", messages);
    NSLog(@"deleted messages: %@", vanishedMessages);
}];

In log block i am expecting to get Modified messages/deleted messages, so that i can be able to cross check with my local DB.But, i am getting all mails in the log.

Any help would be appreciated..

prabath12 commented 5 years ago

you are sending the wron value in modSequence.. you should be sending the modsequence value from the folderstatus [session syncMessagesByUIDWithFolder:@"INBOX" requestKind:MCOIMAPMessagesRequestKindUid uids:UIDS modSeq:"mod sequence from folderstatus"]; will work please try it @vymallesh

vymallesh commented 5 years ago

Which value do I need to pass actually ?

On Wed, 1 May 2019 at 6:30 PM, prabath12 notifications@github.com wrote:

you are sending the wron value in modSequence.. you should be sending the modsequence value from the folderstatus [session syncMessagesByUIDWithFolder:@"INBOX" requestKind:MCOIMAPMessagesRequestKindUid uids:UIDS modSeq:]; will work please try it

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/MailCore/mailcore2/issues/1809#issuecomment-488276019, or mute the thread https://github.com/notifications/unsubscribe-auth/AEUVWGO4ZAHGTHWYQVVDCVLPTGH5JANCNFSM4HJPWXEQ .

haithngn commented 5 years ago

@vymallesh , modSeq is not the las message UID, you coult get that value by using MCOIMAPFolderStatusOperation that be returned from MCOIMAPSession

vymallesh commented 5 years ago

Ok..I will try and let you know

On Wed, 1 May 2019 at 6:47 PM, Nguyen Thanh Hai notifications@github.com wrote:

@vymallesh https://github.com/vymallesh , modSeq is not the las message UID, you coult get that value by using MCOIMAPFolderStatusOperation that be return from MCOIMAPSession

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/MailCore/mailcore2/issues/1809#issuecomment-488279281, or mute the thread https://github.com/notifications/unsubscribe-auth/AEUVWGMROPIRW4MLLTXLGT3PTGJ5LANCNFSM4HJPWXEQ .

vymallesh commented 5 years ago

@haithngn .. using MCOIMAPFolderStatusOperation we can retrieve information like UIDNEXT , UIDVALIDITY etc right ? Then how can i get modSeq value ..

Actually what is modSeq value ?

vymallesh commented 5 years ago

@haithngn and @prabath12

I am getting below log values for MCOIMAPFolderStatusOperation, which one shall i use as modSeq,

UIDNEXT: 1363 UIDVALIDITY: 1485867903

prabath12 commented 5 years ago

use highestModSeqValue

haithngn commented 5 years ago

http://libmailcore.com/api/objc/Classes/MCOIMAPFolderStatus.html

do you have these properties ? uidNext property uidValidity property recentCount property unseenCount property messageCount property highestModSeqValue property Does your server implement CONDSTORE RFC 4551. ?

vymallesh commented 5 years ago

@prabath12 .. Can i have your email id, i will shoot on email directly

vymallesh commented 5 years ago
int start =  1;
int lastUID = [[[NSUserDefaults standardUserDefaults]valueForKey:@"lastUID"]intValue];

MCOIMAPFolderStatusOperation * op = [session folderStatusOperation:@"INBOX"];
[op start:^(NSError *error, MCOIMAPFolderStatus * info) {

    NSLog(@"UIDNEXT: %lu", (unsigned long) [info uidNext]);
    NSLog(@"UIDVALIDITY: %lu", (unsigned long) [info uidValidity]);

    MCOIndexSet *UIDS = [MCOIndexSet indexSetWithRange:MCORangeMake(start, UINT64_MAX)];

    MCOIMAPFetchMessagesOperation * op1 = [session syncMessagesByUIDWithFolder:@"INBOX"
                                                                   requestKind:MCOIMAPMessagesRequestKindUid
                                                                          uids:UIDS
                                                                        modSeq:[info highestModSeqValue]];
    [op1 start:^(NSError * __nullable error, NSArray * messages, MCOIndexSet * vanishedMessages) {
        NSLog(@"added or modified messages: %@", messages);
        NSLog(@"deleted messages: %@", vanishedMessages);
    }];

}];

i was using above code, i have modified an email in my webmail, but i didn't get that modified message/uid/flag in the log.I was getting array count as '0'.

haithngn commented 5 years ago

@vymallesh I think you should read IMAP RFC a little bit to understand how to get a change from IMAP server side

vymallesh commented 5 years ago

Am i doing the right approach for mail synchronisation.I meant to say, modified mails which were already stored in local DB.

vymallesh commented 5 years ago

@haithngn

My server is supporting below things, This is only for servers that support Conditional Store. See RFC4551 vanishedMessages will be set only for servers that support QRESYNC. See RFC5162.

But still i am not getting any modified mails / Deleted mails.Below is the code,

int start =  1;
int lastUID = [[[NSUserDefaults standardUserDefaults]valueForKey:@"lastUID"]intValue];

MCOIMAPFolderStatusOperation * op = [session folderStatusOperation:@"INBOX"];
[op start:^(NSError *error, MCOIMAPFolderStatus * info) {

    NSLog(@"UIDNEXT: %lu", (unsigned long) [info uidNext]);
    NSLog(@"UIDVALIDITY: %lu", (unsigned long) [info uidValidity]);
    NSLog(@"UIDVALIDITY: %lu", (unsigned long) [info highestModSeqValue]);

    MCOIndexSet *UIDS = [MCOIndexSet indexSetWithRange:MCORangeMake(start, UINT64_MAX)];

    MCOIMAPFetchMessagesOperation * op1 = [session syncMessagesByUIDWithFolder:@"INBOX"
                                                                   requestKind:MCOIMAPMessagesRequestKindUid
                                                                          uids:UIDS
                                                                        modSeq:[info highestModSeqValue]];
    [op1 start:^(NSError * __nullable error, NSArray * messages, MCOIndexSet * vanishedMessages) {
        NSLog(@"added or modified messages: %@", messages);
        NSLog(@"deleted messages: %@", vanishedMessages);
    }];
}];

Still i am not getting any modified mails in the log.

vymallesh commented 5 years ago

Does MailCore 2 supports Gmail, Outlook , Yahoo etc.. or do i need to integrate them separately..

haithngn commented 5 years ago

@vymallesh yes it does no you don't

vymallesh commented 5 years ago

@haithngn ,

Do i need to provide my application details(bundle ID etc..) in their respective developer accounts ?

I am using below code for Gmail emails integration,

session = [[MCOIMAPSession alloc]init];
session.hostname = @"imap.gmail.com";
session.username = @"blablabla";
session.password = @"blabla";
session.port = 993;
session.authType = MCOAuthTypeSASLPlain;
session.connectionType = MCOConnectionTypeTLS;
NSString *valueToSave = session.username;

But above code ends up with an error says Standard connection should be established.

Using below code for Microsoft account integration,

session = [[MCOIMAPSession alloc]init];
session.hostname = @"imap-mail.outlook.com";
session.username = @"blablabla";
session.password = @"blabla";
session.port = 993;
session.authType = MCOAuthTypeSASLPlain;
session.connectionType = MCOConnectionTypeTLS;
NSString *valueToSave = session.username;

Even it ends up with an errors says, A Standard Connection should be established.

I am not able to find the exact issue happening around.

I have one more query, i have seen few third party email apps, they have done Gmail, Outlook integration in such a way that the app needs to navigate to their login SDK's(Gmail , Outlook) followed by their app.Do i need to follow the same approach or just through Mailcore2 integration is fine.

vymallesh commented 5 years ago

If i try to login Outlook , it ends up with the below error.

Error Domain=MCOErrorDomain Code=1 "A stable connection to the server could not be established." UserInfo={NSLocalizedDescription=A stable connection to the server could not be established.}

I am using below code,

session = [[MCOIMAPSession alloc]init]; session.hostname = @"mail.outlook.com"; session.username = userName; session.password = pwd; session.port = 993; session.authType = MCOAuthTypeSASLPlain; session.connectionType = MCOConnectionTypeTLS; Any help would be appreciated..

beczesz commented 5 years ago

Hi, On Android I'm using the following code to authenticate Outlook, (Aol, Yahoo, Gmail, Hotmail)

// create a new session IMAPSession imapSession = new IMAPSession(); imapSession.setUsername(carrier.getUserName()); imapSession.setHostname(carrier.getMailConfig().getImapHostName()); imapSession.setPort(carrier.getMailConfig().getImapPort()); imapSession.setConnectionType(ConnectionType.ConnectionTypeTLS); imapSession.setAllowsFolderConcurrentAccessEnabled(true);

    // If the carrier supports OAuth then use token based otherwise password based authentication
    if (carrier.getMailConfig().isUseOAuth()) {
        imapSession.setOAuth2Token(carrier.getAccessToken());
        imapSession.setAuthType(carrier.getCarrierType().isMicrosoft() ? AuthType.AuthTypeXOAuth2Outlook : AuthType.AuthTypeXOAuth2);
    } else {
        imapSession.setPassword(carrier.getPassword());
    }

Also please check the host, on my side I'm using imap-mail.outlook.com

vymallesh commented 5 years ago

Yeah...Hostname might be wrong, but i am facing the same issue with Gmail and Yahoo too.

Do we need to change any settings to access these mails form any third apps.

vymallesh commented 5 years ago

@beczesz ,

Was IMAP Outlook configuration working for you ?

haithngn commented 5 years ago

feel free to reopen this issue if you still face with it.