0

I have the following Python code using simple_salesforce module:

    def get_email_template(sf, agreement_id):

         email_templates = sf.query(f"""
            SELECT VersionData, Title, PathOnClient
            FROM ContentVersion
            WHERE FirstPublishLocationId = '{agreement_id}'
            AND pathonclient = 'email.html'
         """)['records']

         if len(email_templates) != 0:
            return base64.b64decode(email_templates[0]['VersionData'])
         return None

The following is the error log:

    Traceback (most recent call last):
  File "c:\code\Python\social\social_messaging.py", line 293, in <module>
    email_template = get_email_template(sf, agreement_id)
  File "c:\code\Python\social\social_messaging.py", line 113, in get_email_template
    return base64.b64decode(email_templates[0]['VersionData'])
  File "C:\ProgramData\Anaconda3\lib\base64.py", line 87, in b64decode
    return binascii.a2b_base64(s)
binascii.Error: Incorrect padding

index.html is uploaded and attached to Contract object as a File and contains simple html.

I might be doing the conversion wrong. Any help is appreciated.

Thanks.

OP: Final Solution after David's post below:

    def get_email_template(sf, agreement_id):
    
        email_templates = sf.query(f"""
                SELECT VersionData, Title, PathOnClient
                FROM ContentVersion
                WHERE FirstPublishLocationId = '{agreement_id}'
                AND pathonclient = 'email_template.html'
        """)['records']
    
        if len(email_templates) != 0:
            url = f"https://{sf.sf_instance}{email_templates[0]['VersionData']}"
    
            response = requests.get(url, headers={"Authorization": "OAuth " + sf.session_id,
                                                "Content-Type": "application/octet-stream"})
            if response.ok:
                return(bytes.decode(response.content))
            else:
                log.debug(f"Couldn't download %s" % url)
        return None
    
    # end get_email_template

1 Answer 1

3

You're decoding data that's not actually Base64.

When you query ContentVersion, the VersionData attribute that you're returned does not contain the binary content of the version. Rather, it contains a relative URL you can retrieve to obtain the binary data - specifically, it's the relevant sObject Blob Retrieve endpoint.

For example, you might get back

services/data/v47.0/sobjects/ContentVersion/0683600000XXXXXAAQ/VersionData

which you can retrieve to get the binary content for this particular ContentVersion.

1
  • Thanks @David Reed, I have updated my question with a solution based on your comments. Commented May 1, 2020 at 20:16

You must log in to answer this question.

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