iOS - 使用 messageId 和 attachmentId 从 Gmail 下载附件

iOS - download attachment from Gmail using messageId and attachmentId

我正在关注 Google Gmail API documentation in my iOS project where I need to download an attachment from a mail by using it userId, messageId and id Try out from Google。 其中 userId 是用户的电子邮件地址, id 是 mailId (Try it.Enter only your EmailId) messageId 是我们通过使用带有附件的上述 id 之一获得的。

到目前为止,这是我拥有的代码:

- (void)fetchLabels {
    GTLQueryGmail *query = [GTLQueryGmail queryForUsersThreadsList];
    [self.service executeQuery:query
                      delegate:self
            didFinishSelector:@selector(displayResultWithTicket:finishedWithObject:error:)];
}

- (void)displayResultWithTicket:(GTLServiceTicket *)ticket
             finishedWithObject:(GTLGmailListLabelsResponse *)labelsResponse
                          error:(NSError *)error {

    NSDictionary *allIDsDictionaryValue=[labelsResponse.JSON valueForKey:@"threads"];
    NSMutableArray *allIDs=[NSMutableArray new];
    for (int i=0; i<[allIDsDictionaryValue count]; i++) {
        [allIDs addObject:[allIDsDictionaryValue valueForKey:@"id"]];
    }
   NSString *mailID=[[allIDs objectAtIndex:0]objectAtIndex:0];
    NSLog(@"%@",mailID);//Ex: 14e8af86776e595b 
    //As of now I am using the first id only because it has an attachment.

   // Getting messageId from an id of a mail.
    GTLQueryGmail *query1 = [GTLQueryGmail queryForUsersMessagesGet];
    query1.identifier=mailID;
    [self.service executeQuery:query1
                      delegate:self
             didFinishSelector:@selector(displayResultWithTicketOfAttachment:finishedWithObject:error:)];
}

- (void)displayResultWithTicketOfAttachment:(GTLServiceTicket *)ticket
             finishedWithObject:(GTLGmailListLabelsResponse *)labelsResponse
                          error:(NSError *)error {

    NSDictionary *response1=labelsResponse.JSON;
    NSDictionary *response2=[[[response1 valueForKey:@"payload"] valueForKey:@"parts"]objectAtIndex:1];
    if ([[response2 valueForKey:@"mimeType"] isEqualToString:@"application/vnd.ms-excel"]) {
         attachmentId=[[response2 valueForKey:@"body"]valueForKey:@"attachmentId"];
         NSLog(@"%@",attachmentId); //Ex: ANGjdJ_Uw2o7G2Q16jfC4JSTwD2UIO6LuqDIJZvXFCft0q5ALYuiYfM2gPWG0dcty2n6ZkjnVWekIb_3e2_0TqSpctWNAABsfaSF2x2ktf9uHu63e3eIot_GFA9xgppmaRDyaJEL1V-gIvjfPRxgINK8xM0OuuwnVz2xzcCFckkwpK2XwzZG_QPGPvC2Be2bGKNJI8Ds3hGtqfHYeSWZjOjbsjBuxbUFjf1Mlp0TLol9LLAy2cjGZ_CUBQXzZhhWw9AtNHTU4jwhk4WizKRXbfuDvmRtAy1lPCnTKS6pLg

///Based on id and messageId, I am trying to download the attachment
        GTLQueryGmail *query2 = [GTLQueryGmail queryForUsersMessagesAttachmentsGet];
        query2.identifier=mailID;
        query2.messageId=attachmentId;
        [self.service executeQuery:query2
                          delegate:self
                 didFinishSelector:@selector(displayResultWithTicketOfDownloadAttachment:finishedWithObject:error:)];
    }else{
        UIAlertView *alertShow=[[UIAlertView alloc]initWithTitle:@"Error" message:@"No Attachment found" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
        [alertShow show];
    }
}

- (void)displayResultWithTicketOfDownloadAttachment:(GTLServiceTicket *)ticket
                         finishedWithObject:(GTLGmailListLabelsResponse *)labelsResponse
                                      error:(NSError *)error {
    NSLog(@"response is :%@",labelsResponse.JSON);
     NSLog(@"error is :%@",error);
}

But I am getting error as : Error Domain=com.google.GTLJSONRPCErrorDomain Code=400 "The operation couldn’t be completed. (Invalid attachment token)" UserInfo=0x7b68e740 {error=Invalid attachment token, GTLStructuredError=GTLErrorObject 0x7b6876e0: {message:"Invalid attachment token" code:400 data:[1]}, NSLocalizedFailureReason=(Invalid attachment token)}

您的 ID 有点混乱。

GTLQueryGmail *query2 = [GTLQueryGmail queryForUsersMessagesAttachmentsGet];
        query2.id=attachmentId;
        query2.messageId=mailID;

您在回复中获得的数据是 Base64-encoded 并且已通过将所有“+”替换为“-”并将所有“/”替换为“_”来确保 URL 安全。

只需将其转换回常规 Base64 数据并解码即可!在您的开发人员工具中尝试此操作(按 F12):

atob("SGV5IE5pbGVzaCEgSSBob3BlIHlvdSB3aWxsIGdldCBpdCB0byB3b3JrIHNvb24h".replace(/\-/g, '+').replace(/\_/g, '/'));

在您的代码中执行相同的步骤,您将获得原始格式的数据。