Postal icon indicating copy to clipboard operation
Postal copied to clipboard

Not seeing any text/html parts in fetched messages

Open james-rant opened this issue 5 years ago • 2 comments

I'm fetching emails from Gmail, using Postal.

I fetch the last 100 emails, with all flags ([.structure, .size, .flags, .headers, .gmailLabels, .gmailThreadID, .gmailMessageID, .body, .fullHeaders, .headerSubject]), and then iterate over each fetch result's body.allParts and fetch the attachments for each part.

When I do this, I don't ever see any text/html parts, only ever text/plain, but when viewing the raw source of the mail on Gmail, it shows there is a text/html and a text/plain.

My code looks like so:

func fetchMail(in folder: Folder) {
	mailService?.fetchLast(folder.name, last: 100, flags: allFlags, onMessage: { result in
		result.body?.allParts.forEach { part in
			print(part.mimeType) // This always prints "text/plain"
			self.mailService?.fetchAttachments(folder.name, uid: result.uid, partId: part.id, onAttachment: { mailData in
				if let data = Data(base64Encoded: mailData.decodedData, options: .ignoreUnknownCharacters) {
					let content = String(data: data, encoding: .utf8)
					print(content) // this is always a plain text representation
				} else {
					let content = String(data: mailData.decodedData, encoding: .utf8)
					print(content) // this is always a plain text representation
				}
			}, onComplete: { error in
				if let error = error {
					print("Error fetching attachment: \(error)")
				}
			})
		}
	}, onComplete: { error in
		if let error = error {
			print("error fetching email in \(folder.name): \(error)")
			return
		}
	})
}

An example of the log when I'm testing this is as follows:

text/plain
Optional("D4Test was granted access to your Google account\r\n\r\n\r\[email protected]\r\n\r\nIf you did not grant access, you should check this activity and secure your\r\naccount.\r\nCheck activity\r\n<https://accounts.google.com/[email protected]&continue=https://myaccount.google.com/alert/nt/1570456286000?rfn%3D127%26rfnc%3D1%26eid%3D650020303090366957%26et%3D0%26anexp%3Dgivab-fa--mdv2-fa>\r\nYou received this email to let you know about important changes to your\r\nGoogle Account and services.\r\n© 2019 Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA\r\n")

But when I check the source of the email via the Gmail website it shows two parts of the email, one text/plain, which is the plain text encoded as bas64, and the other text/html, but the html part does not appear in the parts in the Postal response.

james-rant avatar Oct 14 '19 17:10 james-rant

I'm also seeing this, using the latest version (installed using the "manual" install instructions). Possibly related, mailData.encoding is always .binary, even though most of the message parts are quoted-printable (and as such, mailData.encoding should be .quotedPrintable). As far as I can tell, this determination is done by libetpan, and it looks like the binary included with Postal is about three years old. I'll try to compile a new version when I get a chance (just ran dependencies/build-dependencies.sh and got the error below):

2019-10-23 19:55:46.974 xcodebuild[47519:2044033] DTDeviceKit: deviceType from 63b2f67ccb315dd6482032d6ed2d7221c04c5a10 was NULL ** BUILD FAILED **

The following build commands failed: ExternalBuildToolExecution libetpan-prepare-ios (1 failure) failed

ggruen avatar Oct 24 '19 01:10 ggruen

have you guys found any solution on attachment downloading ? no matter what I have tried I am always getting undefined error

    postal?.fetchMessages(Folders.inbox.description, uids: indexSet, flags: [.body, .headerSubject], onMessage: { result in
        result.body?.allParts.forEach { part in
   
            // download images if mimetype is pdf or jpeg
            if part.mimeType.subtype.contains("pdf") || part.mimeType.subtype.contains("jpeg") {
                self.postal?.fetchAttachments(Folders.inbox.description, uid: result.uid, partId: part.id, onAttachment: { mailData in
                    if let data = Data(base64Encoded: mailData.decodedData, options: .ignoreUnknownCharacters) {
                        let content = String(data: data, encoding: .utf8)
                        print(content)
                    } else {
                        let content = String(data: mailData.decodedData, encoding: .utf8)
                        print(content) // this is always a plain text representation
                    }
                }, onComplete: { error in
                    if let error = error {
                        print("Error fetching attachment: \(error)")
                    }
                })
    }, onComplete: { error in
        if let error = error {
            print("error fetching email in \(Folders.inbox.description): \(error)")
            return
        }
    })

lionserdar avatar Jun 14 '22 09:06 lionserdar