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

1

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();
}
  • 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. – user40501 Apr 29 '20 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 '20 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 – user40501 Apr 30 '20 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 '20 at 16:48
  • I added "if(att.fileName.contains('.csv')){}" and that did the trick. Now it works fine. Thanks a lot, @sfdcfox! – user40501 May 3 '20 at 10:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.