1

I am using Salesforce REST API to pull in the user profile salesforce object into my external site. I wanted to be able to display things like about me, title, and image on my site. I get all of this information from the following endpoint.

/services/data/v41.0/sobjects/User/{USERID}

The information I then pull from this is

Name
Email
FullPhotoUrl

I tried putting the FullPhotoUrl into an img html tag but it shows as broken link

Key thing to note is I am using the JWT bearer token authentication oauth flow for server to server communication. The user of my site does not have their own salesforce login and the data gathering happens all server side. The image does show if I login to my environment myself in another tab. I am guessing there is some sort of cookie that is allowing the image to be shown

TLDR: How do I get the user profile image url link I get in the rest api to show in an external site img tag?

Documentation of JWT flow: https://help.salesforce.com/articleView?id=remoteaccess_oauth_jwt_flow.htm&type=5

  • A while ago I needed to publicly expose some user info. I found using ContentVersions & ContentDocuments was an ideal solution, since I could write a trigger to put new versions out, and the contentDocument supports public links out of the box. For the other fields, Id say a custom object to mirror the user fields, exposed through a public web site url might be easier than trying to manage tokens, depending on where you're posting the content. If this content is public, then hiding it behind a token doesn't make much sense, you might as well provide it publicly. – battery.cord Jun 12 '18 at 16:39
  • This could be a possiblity. I'm not sure how the users would feel yet about this image being a public facing url. The api calls I am making are still within the third party applications authenticated users. I was hoping to either maintain the token in the right place or to find the place to download the image binary and somehow display it that way. – Crash667 Jun 12 '18 at 16:55
  • Ah, when I read "external site" I assumed that the site was publicly available. You can provide the base64 of an image & render it with an img tag. Doesn't help carry over the user info though. I still think a custom object with specific fields mirrored would be a good choice. Could have a spot for a base64 image, and the whole thing would work well with JSON. Don't have much advice for accessing it (which is why Im making comments). – battery.cord Jun 12 '18 at 17:10
  • 1
    It sounds like you want to JIT provision users from your Salesforce Org on the "external site" and use SAML SSO to retrieve the information you're looking for. If you create a connected app between your site and Salesforce you could presumably have users authorize access to their profile information for display of the pics via the app. – crmprogdev Jun 12 '18 at 18:26
  • No actually this is for a student application. Basically we want to show to the student the contact owner information for them. This happens to be the user profile object. Students themselves don't have a login but we wanted to pull in all of this information through the api. All the other information is easily gathered except for the image which remains a broken link. – Crash667 Jun 13 '18 at 15:19
1

You might be able to add something to the headers or the page to be able to access the actual photo url, but I'd avoid the whole thing & provide the photo in another form, either in base64, or as a publicly linked (you can set up "private" links as well) ContentVersion.

Base64

  1. Get PhotoUrl
  2. Get PageReference Content
  3. Save into field/return with other data
  4. Use on page with img tag

Downsides: Spotty support (never had a problem unless its an email), large amount of text, may need to return per request depending on how you set your page up (best used as a saved database entry instead of getting a value with each request)

ContentVersion

  1. Get the photo url
  2. Create new content version
  3. Upload Blob of User photo to the version
  4. Share using built in link feature
  5. Save link back to user (needs own context)
  6. Return Link Url with user record
  7. Display link on page

Downsides: Link is likely public to anyone with a copy of it, Setting this up to happen automatically is a pain, since you cant update a setup object & a non-setup object in the same context, Lots of extra objects involved to get the data to be shareable (ContentDocument, ContentVersion, User, etc)


Base64 Sample Code (Should run in dev console):

public static String GetBase64Content(String url) {
    String Base64Content = 'data:image/png;base64, '; 

    if (url != null) {
        PageReference imageSource = new PageReference(url); 

        Blob b = imageSource.getContent();

        Base64Content += EncodingUtil.base64Encode(b); 
    }

    return Base64Content; 
}

User u = [
    SELECT Id, FullPhotoUrl 
    FROM User 
    WHERE Id = :UserInfo.getUserId()
    LIMIT 1
];

String content = GetBase64Content(u.FullPhotoUrl);

// use like: 
// <img src="{!content}" />

You may need to store the base64 result either in a long/rich text field or in a json object, depending on how your server handles the data.


ContentVersion Demo

Creates a contentVersion using the blob from the users FullPhotoUrl, set to "publicly available", which creates a ContentDistribution, which you can query & get the ContentDownloadUrl from, which you can use in an img tag or store somewhere. Could be useful to create base64 or binary files on a target server.

private static ContentVersion CreateVersion(User u, Blob body) {
    return new ContentVersion(
        // https://salesforce.stackexchange.com/questions/117113/migrating-chatter-files-attached-to-feed-comments
        OwnerId = UserInfo.getUserId(), // Has to be running user - won't be able to create otherwise.. 
        VersionData = body,
        Title = 'Profile Photo of ' + u.Name,
        PathOnClient = 'profilePhoto.png',
        Origin = 'H',
        Profile_Image_Owner__c = u.Id, 
        Externally_Available__c = true,
        FirstPublishLocationId = LibraryId  // Used Custom setting w/ specific id, should replace with target dir 
    );
}

User u = [
    SELECT Id, FullPhotoUrl 
    FROM User 
    WHERE Id = :UserInfo.getUserId()
    LIMIT 1
];

ContentVersion version = CreateVersion(u, new PageReference(u.FullPhotoUrl).getContent());

insert version;

ContentDistribution dist = [
    SELECT Id, DistributionPublicUrl, ContentDownloadUrl
    FROM ContentDistribution
    WHERE ContentVersionId = :version.Id
];

// Use like so:
// <img src="{!dist.ContentDownloadUrl}" />

// Need to update user to attach content url/id in a seperate context 
// Could also save user id to document & query, or return id in response from server 

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.