【问题标题】:How to insert a message with an attachment using Gmail API (Java)如何使用 Gmail API (Java) 插入带有附件的邮件
【发布时间】:2019-02-24 12:27:38
【问题描述】:

我通过 Java 客户端库使用 Gmail API,我发现 Gmail API insert(java.lang.String userId, com.google.api.services.gmail.model.Message content) 方法只插入小于 5Mb 的文件。

我尝试使用Insert insert(java.lang.String userId, com.google.api.services.gmail.model.Message content, com.google.api.client.http.AbstractInputStreamContent mediaContent) 插入带有文件(大小为 10MB)的消息。

MimeMessage email = GmailAPI.createEmail("toXXX@gmail.com", "fromYYY@gmail.com", "subject", "message body");
FileContent content = new FileContent("message/rfc822", new File("C:\\Users\\user\\someFile"));
Message message = createMessageWithEmail(email);
message = service.users().messages().insert(userId, message, mediaContent).execute();

CreateEmail 是快速入门中的简单方法:

   public static MimeMessage createEmail(String to,
                                              String from,
                                              String subject,
                                              String bodyText)
                throws MessagingException {
            Properties props = new Properties();
            Session session = Session.getDefaultInstance(props, null);

            MimeMessage email = new MimeMessage(session);

            email.setFrom(new InternetAddress(from));
            email.addRecipient(javax.mail.Message.RecipientType.TO,
                    new InternetAddress(to));
            email.setSubject(subject);
            email.setText(bodyText);
            return email;
        }

邮件出现在我的邮箱中,但没有文件。

这里出了什么问题?

UPD1: 插入媒体内容,仅插入不带附件的电子邮件。我觉得我用错了。

【问题讨论】:

标签: java email gmail gmail-api


【解决方案1】:

我已经弄清楚如何使用 java 库使用可恢复上传(通过 REST 的相同想法):

byte[] bytes = Base64.decodeBase64(message.getRaw());
Insert insertReq;
Message content = new Message();
content.setLabelIds(message.getLabelIds());
try {
    insertReq = gmail.users().messages().insert(account, content,
        new ByteArrayContent("message/rfc822", bytes, 0, bytes.length));
    helper.execute(insertReq, task.getPartnerID(), task.isUnderWhiteLable());
} catch (IOException e) {
    Log.error("Failed to insert a message with resumable upload message", e);
}

该方法的描述被证明是完全可以理解的,但却是事后的。我不知道为什么描述如此糟糕:

/**                                                                                                                                                                                                
 * Directly inserts a message into only this user's mailbox similar to IMAP APPEND, bypassing most                                                                                                 
 * scanning and classification. Does not send a message.                                                                                                                                           
 *                                                                                                                                                                                                 
 * Create a request for the method "messages.insert".                                                                                                                                              
 *                                                                                                                                                                                                 
 * This request holds the parameters needed by the the gmail server.  After setting any optional                                                                                                   
 * parameters, call the {@link Insert#execute()} method to invoke the remote operation.                                                                                                            
 *                                                                                                                                                                                                 
 * <p>                                                                                                                                                                                             
 * This method should be used for uploading media content.                                                                                                                                         
 * </p>                                                                                                                                                                                            
 *                                                                                                                                                                                                 
 * @param userId The user's email address. The special value me can be used to indicate the authenticated user.                                                                                    
 *        [default: me]                                                                                                                                                                            
 * @param content the {@link com.google.api.services.gmail.model.Message} media metadata or {@code null} if none                                                                                   
 * @param mediaContent The media HTTP content or {@code null} if none.                                                                                                                             
 * @return the request                                                                                                                                                                             
 * @throws java.io.IOException if the initialization of the request fails                                                                                                                          
 */                                                                                                                                                                                                
public Insert insert(java.lang.String userId, com.google.api.services.gmail.model.Message content, com.google.api.client.http.AbstractInputStreamContent mediaContent) throws java.io.IOException {
  Insert result = new Insert(userId, content, mediaContent);                                                                                                                                       
  initialize(result);                                                                                                                                                                              
  return result;                                                                                                                                                                                   
}    

【讨论】:

    【解决方案2】:

    要插入大于 5MB 的电子邮件,您必须使用分段上传可恢复上传(详情请参阅docs)。

    在 Java Gmail API 客户端库中,insert 方法的 2 参数版本发送 简单上传 请求,最多可以上传 5MB。要发送可恢复上传请求,请使用insert 方法的三参数版本。使用可恢复上传,您最多可以插入 50MB。

    这是一个使用可恢复上传插入javax.mail.internet.MimeMessage的方法:

    import com.google.api.client.http.ByteArrayContent;
    import com.google.api.services.gmail.Gmail;
    import com.google.api.services.gmail.model.Message;
    
    import javax.mail.internet.MimeMessage;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.util.List;
    import javax.mail.MessagingException;
    
    private Message insertMessage(Gmail gmail, String userId, MimeMessage mimeMessage, List<String> labelIds, String threadId) throws IOException, MessagingException {
        // Create Message instance containing email message metadata
        Message metadata = new Message()
                .setLabelIds(labelIds)
                .setThreadId(threadId);
    
        // Create byte array containing email message data (in RFC 2822 format)
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        mimeMessage.writeTo(baos);
        ByteArrayContent rawMessageBytes = new ByteArrayContent("message/rfc822", baos.toByteArray());
    
        return gmail.users().messages()
                .insert(userId, metadata, rawMessageBytes)
                .setInternalDateSource("dateHeader")  // The GMail internal message time is based on the Date header in the email, when valid.
                .execute();
    }
    

    【讨论】:

      猜你喜欢
      • 2018-11-11
      • 1970-01-01
      • 2018-08-28
      • 2016-12-21
      • 2016-05-29
      • 2020-09-06
      • 2011-12-17
      • 1970-01-01
      • 2016-09-22
      相关资源
      最近更新 更多