3

Recently, my project add to use Gmail, so I meet many questions about it, it make me so sad. Now, I want to know how to send Images to the draft, my code as follows:

func postEmailMessageRequest(model: MEMailMessageModel, request: CompletionRequest) {

        let uploadParameters = GTLUploadParameters()
        uploadParameters.data = "String".dataUsingEncoding(NSUTF8StringEncoding)
        uploadParameters.MIMEType = "message/rfc2822"

        let query = GTLQueryGmail.queryForUsersDraftsCreateWithUploadParameters(uploadParameters) as! GTLQueryProtocol!
        service.executeQuery(query) { (ticket : GTLServiceTicket!, messages : AnyObject!, error : NSError?) -> Void in
            if error == nil {
                let messages = (messages as! GTLGmailDraft)
                messages.message.threadId = model.threadID
                self.sendMailRequest(messages, model: model, request: request)
            } else {
                request(status: false, result: "failure")
            }
        }
    }

    func sendMailRequest(draft: GTLGmailDraft, model: MEMailMessageModel, request: CompletionRequest) {

        let query = GTLQueryGmail.queryForUsersDraftsSendWithUploadParameters(nil) as! GTLQueryGmail
        draft.message.raw = self.generateRawString(model)
        query.draft = draft

        self.service.executeQuery(query, completionHandler: { (ticket, response, error) -> Void in
            if error == nil {
                request(status: true, result: "success")
            } else {
                request(status: false, result: "failure")
            }
        })
    }

above I can send the text success, but i do not know how to send Images or PDFs to the drafts.

ySeN
  • 39
  • 5
  • Sorry, title omission a "drafts". – ySeN Dec 14 '15 at 10:30
  • Get data from image like this UIImageJPEGRepresentation(yourImage, 0.7) encode it and assign it to your uploadParameters.data property and change the mimeType accordingly and try. – Muneeba Dec 14 '15 at 12:37
  • @Muneeba but if there are more than one pictures should be upload, than how to do it? – ySeN Dec 14 '15 at 16:33
  • You need to go for multipart upload. check the link for further information https://developers.google.com/gmail/api/guides/uploads – Muneeba Dec 15 '15 at 04:36
  • @Muneeba thx, I try to understand that. – ySeN Dec 16 '15 at 02:36
  • did you find any solution for this? – jose920405 Jan 21 '16 at 13:27
  • I tried using the code above in XCode 7 and Swift 2.1 and I get an error saying 'Use of undeclared type MEMailMessageModel' and 'Use of undeclared type type CompletionRequest' – gbotha Jul 15 '16 at 15:46
  • @gbotha as you see, 'MEMailMessageModel' is custom model and 'CompletionReques' is custom block about handler complete request. that means you should create you model and base contains (threadID, messageID, references, subject, fromUserInformation, toUserInformation). and create a block to handler complete the request. – ySeN Jul 16 '16 at 03:01
  • @ySen I'm basically looking to use the Gmail API with Swift to send emails with an attachment. Would you be able to post usable code that I could use to do this. There really should be a standard way for users to do this without having to recreate it and Google has not published anything for Swift yet. Thanks. – gbotha Jul 17 '16 at 18:02
  • @gbotha, the code as follow: – ySeN Jul 20 '16 at 04:33
  • @gbotha you can see the answer area, I just push the code on there. hope you can understand the code. or if you can not figure out of this, you can also send a email to my gmail: yangyangyang02@gmail.com. – ySeN Jul 20 '16 at 05:24

1 Answers1

0

there is final code to send attachment email and reply email. `

// send email
extension MENetworkUtil {

/**
 * block: typealias NetworkResponse = (status: Bool, result: AnyObject) -> Void
 *
 * model: MEMailMessageModel contains(threadID, messageID, toUsers, fromUser, ccUsers, bccUsers, subject, contentText, attachmentsModels, isReplyEmail)
 **/
func setMailReqest(model: MEMailMessageModel, responseBlock: NetworkResponse) {
    let query = GTLQueryGmail.queryForUsersMessagesSendWithUploadParameters(nil) as! GTLQueryGmail
    let message = GTLGmailMessage()

    message.threadId = model.threadID
    message.raw = getEmailRawString(model)
    query.message = message

    service.executeQuery(query) { (ticket, response, error) in
        if error == nil {
            let result = response as! GTLGmailMessage

            if model.isReply { // send reply email success
                responseBlock(status: ture, result: result)
            } else {
                responseBlock(status: ture, result: result)
            }

        } else {
            request(status: false, result: "send email failure")
            printLog(error.debugDescription)
        }
    }
}

func getEmailRawString(model: MEMailMessageModel) -> String {
    var headerMessage = ""
    headerMessage += setSimpleEmailHeader(model) // send email

    if model.isReply { // send reply email
        headerMessage += setReplyEmail(model)
    }

    if model.attachments.count > 0 { // send attachments
        headerMessage += setAttachmentsEmail(model)
    } else {
        headerMessage += "\r\n\(model.contentText)\r\n\r\n"
    }

    // it should be convert to base64 string
    return GTLEncodeWebSafeBase64(headerMessage.dataUsingEncoding(NSUTF8StringEncoding))
}

func setSimpleEmailHeader(model: MEMailMessageModel) -> String {
    var rawMessage = ""
    let fromEmail = MEGlobal.loginEmail // login google email

    // send email date
    let date = MEMailMessagelFormatUtil.coverDateFromDate(NSDate(), dateFormat: "EEE, dd MMM yyyy HH:mm:ss Z")!

    // send email subject
    let subject = "=?UTF-8?B?" + "\(GTLEncodeBase64(model.subject.dataUsingEncoding(NSUTF8StringEncoding)))" + "?="

    let toInfoStr = model.toUsersString
    let ccInfoStr = model.ccUsersString
    let fromInfoStr = model.fromUserString

    if !ccInfoStr.isEmpty {
        rawMessage += "Cc: \(ccInfoStr)\r\n"
    }

    rawMessage += "MIME-Version: 1.0\r\n"
    rawMessage += "Date: \(date)\r\n"
    rawMessage += "From: \(fromInfoStr)\r\n"
    rawMessage += "To: \(toInfoStr)\r\n"
    rawMessage += "Subject: \(subject) \r\n"

    return rawMessage
}

// send reply email you should add two properties: References/In-Reply-To
// references means the same thread messageIDs()
// In-Reply-To means you reply thread the last email messageID
func setReplyEmail(model: MEMailMessageModel) -> String { // 回复邮件样式
    var rawMessage = ""
    rawMessage = "" + "In-Reply-To: \(model.messageID)\r\n"

    if let references = model.references { // check thread has more than 1 message.
        rawMessage += "References: \(references) \(model.messageID)\r\n"
    } else {
        rawMessage += "References: \(model.messageID)\r\n"
    }

    return rawMessage
}

// the attachments email
// first of all, you should figure out 'Content-Type'
// MEMailAttachmentsModel: is constom attachment model, contains(attachment type, attachment name, data), and data should be convert NSData to Base64 String.
func setAttachmentsEmail(model: MEMailMessageModel) -> String {

    var rawMessage = ""
    rawMessage += "Content-Type: multipart/mixed; boundary=\"foo_bar_baz\"\r\n"
    rawMessage += "Content-Length: 99999999999999999999999999\r\n\r\n"
    rawMessage += "--foo_bar_baz\r\n"
    rawMessage += "Content-Type: text/plain; charset=\"UTF-8\"\r\n"
    rawMessage += "MIME-Version: 1.0\r\n\r\n"
    rawMessage += "\(model.contentText)\r\n\r\n"

    var attachments: [MEMailAttachmentsModel] = model.attachments

    for i in 0..<attachments.count {
        let attachment  = attachments[i]
        var contentType = ""
        switch attachment.attachmentType {
        case .Text:
            contentType = "text/plain"
        case .JPEG:
            contentType = "image/jpeg"
        case .PNG:
            contentType = "image/png"
        case .HTML:
            contentType = "text/html"
        case .Multipart:
            contentType = "multipart/mixed"
        case .Video:
            contentType = "video/mpeg"
        case .Application:
            contentType = "application/octet-stream"
        case .MSWord:
            contentType = "application/msword"
        case .PDF:
            contentType = "application/pdf"
        default: break
        }

        if attachment.mimeType != "" {
            contentType = attachment.mimeType
        }

        rawMessage += "--foo_bar_baz\r\n" +
            "Content-Type: \(contentType)\r\n" +
            "MIME-Version: 1.0\r\n" +
            "Content-Transfer-Encoding: base64\r\n" +
            "Content-Disposition: attachment; filename=\"\(attachment.fileName)\"\r\n" +
        "Content-Type: message/rfc822\r\n\r\n"
        rawMessage += "\(GTLEncodeBase64(attachment.fileData!))\r\n\r\n"
    }

    rawMessage += "--foo_bar_baz--"

    return rawMessage
}
}

`

ySeN
  • 39
  • 5