0

I try to encode and decode a BLOB in order to avoid the 'BLOB is not valid UTF-8 string' error, but when I encode the BLOB in UTF-8, decode it again and use the .toString-method, I stil get the error. Here is my code:

global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope env){


   Messaging.InboundEmailResult result = new Messaging.InboundEmailResult();

   for(Messaging.InboundEmail.BinaryAttachment att : email.binaryAttachments){
      Blob csvBlob = att.body;
      String csvBody = EncodingUtil.base64Encode(csvBlob);
      Blob csvBlobAfter = EncodingUtil.base64Decode(csvBody);
      String csvString = csvBlobAfter.toString();

      system.debug(logginglevel.debug, 'Attachment Body '+csvString);
   }

}

The csv file was a test file and looks like this:

foo,bar
Hello,World

It's properties are "Microsoft Excel-CSV-File (.csv)"

What am I missing here?

As a further step, considering the answer to my question, and I do have a signature in my email, I tried:

  for(Messaging.InboundEmail.BinaryAttachment att : email.binaryAttachments){
    if(att.mimeTypeSubType != 'text/csv') {
      System.debug(logginglevel.debug, 'Attachment is not text');
      System.debug(logginglevel.debug, 'Attachment Body '+att.body);
      continue; // not a text/csv file! //
    }
    // Remove BOM //
    System.debug(logginglevel.debug, 'Attachment Body after text check'+att.body);
    String encoded = EncodingUtil.base64encode(att.body);
    System.debug(logginglevel.debug, 'encoded '+encoded);
    Blob decoded = EncodingUtil.base64Decode(encoded.removeStart('feff').removeStart('fffe'));
    String csvText = decoded.toString();

    system.debug(logginglevel.debug, 'csvText '+csvText);

  }

This gives me the following debug log: enter image description here

The debug log is the same also when I uncheck 'Convert Text Attachments to Binary Attachments' in the Email Services Settings.

This code however gave me the error 'BLOB is not a valid UTF-8 string' and a different debug log:

for(Messaging.InboundEmail.BinaryAttachment att : email.binaryAttachments){
   if(att.mimeTypeSubType != 'text/csv') {
      System.debug(logginglevel.debug, 'Attachment is not text');
      System.debug(logginglevel.debug, 'Attachment Body '+att.body);

      String encoded = EncodingUtil.base64encode(att.body);
      system.debug(logginglevel.debug, 'encoded '+encoded);
      Blob decoded = EncodingUtil.base64Decode(encoded.removeStart('feff').removeStart('fffe'));
      String csvText = decoded.toString();

      system.debug(logginglevel.debug, 'csvText '+csvText);

   }

}

enter image description here

After the suggestion to use hex instead of base64 I used this code:

  for(Messaging.InboundEmail.BinaryAttachment att : email.binaryAttachments){

    System.debug(logginglevel.debug, 'Attachment Body '+att.body);
    String encoded = EncodingUtil.convertToHex(att.body);
    System.debug(logginglevel.debug, 'encoded '+encoded);
    Blob decoded = EncodingUtil.convertFromHex(encoded.removeStart('feff').removeStart('fffe'));
    String csvText = decoded.toString();
    system.debug(logginglevel.debug, 'csvText '+csvText);

  }

I got the same error 'BLOB is not a valid UTF-8 string' with this debug log: enter image description here

Then I tried: encoded.removeStart('ffd8ffe') and got the error: System.InvalidParameterValueException:

input string must be an even number of characters long, but was 80501

2 Answers 2

2

Encoding and decoding is just wasting time; the transformation is lossless and won't wipe out invalid characters. It's possible that you have an extra attachment incoming (e.g. if you have an inline image in your signature, it would appear as an attachment). Make sure you're dealing with a text file:

for(Messaging.InboundEmail.BinaryAttachment att : email.binaryAttachments){
    if(!att.mimeTypeSubType.startsWith('text/')) {
        continue; // not a text file! //
    }

}

There may also be a BOM (Byte Order Mark), if so, we need to take this out, too:

for(Messaging.InboundEmail.BinaryAttachment att : email.binaryAttachments){
    if(att.mimeTypeSubType != 'text/csv') {
        continue; // not a text/csv file! //
    }
    // Remove BOM //
    String encoded = EncodingUtil.convertToHex(att.body);
    Blob decoded = EncodingUtil.convertFromHex(encoded.removeStart('feff').removeStart('fffe'));
    String csvText = decoded.toString();
}
5
  • Thank you, @sfdcfox, that seemed to hint to the right directions. However, it still did not function. Please see my edited question where I put the debug logs in. Apr 29, 2020 at 7:52
  • @user40501 I just realized it should have been convertToHex/convertfromHex for taking care of the BOM. Still, /9j/ when decoded definitely isn't UTF-8. Why don't you dump the mimeTypeSubType as well and see what that is?
    – sfdcfox
    Apr 29, 2020 at 12:55
  • '@sfdxfox thanks, I tried your suggestions, please see the enhanced question above: I still get the error 'BLOB is not a valid UTF-8 string', the encoded string looks like this: ffd8ffe104f74578696600004d4d002a000000080007011200030000000100010000011a00050000000100000062011b0005000000010000006a012800030000000100020000013100020000001f000000720132000200000014000000918769000400000001000000a8000000d4002dc6c000 Apr 30, 2020 at 6:51
  • @user40501 That file you're trying to decode into a string is actually a JPEG format file. It is definitely not a string. You're looking at the wrong attachment.
    – sfdcfox
    Apr 30, 2020 at 16:48
  • I added "if(att.fileName.contains('.csv')){}" and that did the trick. Now it works fine. Thanks a lot, @sfdcfox! May 3, 2020 at 10:34
1

Same as previous answer, but added other BOM:

Blob csvBlob = [...];

// Remove BOM //
String encoded = EncodingUtil.convertToHex(csvBlob);
Blob decoded = EncodingUtil.convertFromHex(
encoded
    .removeStart('0000feff') // UTF-32, big-endian
    .removeStart('fffe0000') // UTF-32, little-endian
    .removeStart('feff')     // UTF-16, big-endian
    .removeStart('fffe')     // UTF-16, little-endian
    .removeStart('efbbbf')   // UTF-8
);

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .