How I Solved It: The totally-unofficial-not-endorsed-by-salesforce-like-at-all solution I made for getting headshots onto Contact records.

I’m reaching back in my memory here, back to 2012 and 2013. I was working in the National offices for Teach For America and with no knowledge, skills, or experience for doing so, was a team lead for our first-time Salesforce implementation. In my recollection, we were super jazzed about the ability to have photos of our Corps Members and Alumni right there on their contact record. Before that we had been looking at rows on spreadsheets - and honestly sometimes I looked at the IDs more than I looked at the names :( So to imagine a world in which technology was able to not only organize and display data in flexible and easy-to-use ways, it was also going to humanize the data - show a picture of a person! Look at who we are serving! t

So did we get all those photos up on the records? Uh, no, I don’t think that we did. If anyone reading this works at TFA right now and can tell me if people’s faces are part of their contact records in TFACT, I’d be super grateful to get your input!!

Now I’m working with another incredible education non-profit, and we actually DID collect headshots from the students we are serving, and we DO want them on the contact records. There just HAS to be an automated, simple, easy way to do that, right?

Well I couldn’t find one. I’m a little burnt right now from trying to battle with how Files & Attachments work in Salesforce and being met with complexity and roadblocks. Add to the fact that we collected the photos through a forms tool that is typically such a great platform, but in this instance is falling very short since it is cumbersome and time-consuming to actually GET these images out of the system. So I wasn’t feeling cozy with my main systems (which are both big companies with well-established products) and I was ready to try to hack my way to a solution.

Of course the first place I went was Google, but a close second was the AppExchange (like the Apple store or the Google Play store, but for Salesforce). There are some add-ons to Salesforce that you can find that will let you upload a picture onto a contact record. I installed one into my instance (YES, I installed an app right to production, didn’t even bother with a sandbox. Talk to me about that separately if you’d like). It was pretty good, but still incredibly manual - you need to go to each contact and choose a file to upload. AND there is no second-step to the delete button. Hit that button and pop! You’ve lost your picture. I needed something way more automated and responsive.

At this point I thought back to my incredible mentor and manager from my last full-time education non-profit role at New Leaders. She was amazing at finding ways to make systems that I thought were set in stone do things that I never would have thought possible. Just seeing the possibilities and how her mind was open to finding a solution to any challenge really inspired me to think about different ways I might be able to figure this little pickle out. I decided to take myself through my Beginner’s Mindset Method. First, I re-wrote and re-worded the outcome I wanted, just getting everything out of my head. I could whittle down all of that to some variation on this one-liner about what I wanted to do: I had a whole bunch of images I needed to match up to contact records and display them on the record. 

The next step in the Beginner’s Mindset Method is to draw a picture of the outcome you want - but I skipped it this time. Yep, I even mess around with my own methods - why not? So I went right to step three, breaking everything down into a list. This ended up a very short list:

  • Matching up photos to records in Salesforce

  • Displaying the photo on the record

When I looked at it this way, the whole situation seemed much more manageable. Step four in the Method is translating the vision to technical approaches. I had a thought about how I might match the photos to the records (by naming the photo as the ContactID of the matching contact, which in hindsight we could have done more automatically through our forms platform). And I had seen my former mentor and manager at New Leaders use JavaScript to reference the URL of an open web page, so I thought to go for it even though I have no background or education in JavaScript. What I do have is an oversized sense of confidence that I can figure anything out from some good Google searches and what people have shared on the internet. 

So after a few hours of fiddling and some heavy internet searching and utilizing some great free tools and information, I am happy to share the solution I came upon. Anyone can use it with very few changes needed to make it work in your systems. And if you can improve on it, please do and share! This was just a proof of concept at this point, so I’m still working on making it better myself, and I’d much rather do it with others.

Solution: VisualForce Page on Lightning Layout + Cloud Hosting Service + JavaScript

The VisualForce Page Part

I had never created a VisualForce page before this. I say that here to emphasize the fact that it can be a worthwhile pursuit to try going down a path of using some technology or functionality that you have never ever used before, because you just might pick up some great ideas, learnings, and solutions along the way. So anyway, VisualForce. In case you didn’t know (I didn’t, I Googled it and tried it out), VisualForce Pages are like little containers for programming code (computer languages). Sort of like websites are little containers for programming code - you can loosely think of it like this: HTML code gives the website shape and structure, CSS code makes it pretty, JavaScript code tells it to do things, like react when you press a button or give you a specific message based on the length of time you are on a page. There are many other programming languages that can be used to do these things. Those three that I mentioned are just some of the oldest and most commonly used. I wasn’t sure if you could use any of these coding languages inside a VisualForce page, so I asked Google and the internet and the wonderful people behind it informed me that yes, VisualForce pages could have those coding languages on them. So you can think of VisualForce pages as little mini websites that you can program and design, and display on your Salesforce records and homepages. I have experience using HTML code to “show” things on one web page that “live” (or, are stored on) on another web page. Enter Amazon Cloud Services into our solution.

The Cloud Hosting Services Part

I have used Amazon Cloud Services to “store” lots of things - images, videos, documents - well, I’ve saved a lot of these kinds of things anyway. It is like Dropbox or Google Drive - you can make the permissions so that other people on the internet can have access to see certain files in your cloud hosting service. So I knew that if I had the photos of my contacts saved in a place like this with the right permissions, I could use some programming language to access those photos based on their URL. For example, here is an image of mickey mouse I have saved on Amazon. And here is an image of donald duck. You may have noticed that the actual URLs that show up in your browser when you click those links look very similar:

https://heafmusttransfer.s3.us-east-2.amazonaws.com/0030W00003wUkKfQAK

https://heafmusttransfer.s3.us-east-2.amazonaws.com/0036T00003yE3IHQA0

The beginning of the URLs are exactly the same. Salesforce users will likely recognize that the ending part of the URL, the last 18 digits, are unique IDs of Contact records from Salesforce. This last piece corresponds to the name of the image file that I saved in Amazon - I named all the photos we received simply as the Contact ID of the matching contact record. I did this through another automated process that I won’t go into here but am happy to share at any point with anyone interested in talking about it, and there are several different ways this might be accomplished in a bulk or mass update of file names.

With all the photos named and saved on Amazon, I needed some code that could give the instructions in Salesforce. The instructions would be something like: When a Contact Record page is opened in a web browser, look at the URL of that Contact Record page (which always contains the unique ID of the record in it), then reference the Amazon URL that ends in the same unique ID, and more than reference it, display that webpage inside the VisualForce page. Enter JavaScript.

The JavaScript Part

I had seen JavaScript used in the past to “look up” the URL of the open web page you are currently on. So I was pretty sure that I could find some code on the internet to cobble together with my basic HTML knowledge to make this magic happen. I’ll put the full code in for you to see, and then I’ll break down the components below. Quick heads up and warning - sometimes it seems like this code is doing stuff backwards, so if it feels like that to you don’t worry, it’s not you, it’s the code.

<apex:page > <!-- Begin Default Content REMOVE THIS --> <html lang="en"> <head> <title>Get Current URL in JavaScript</title> </head> <body> <img height="275" src="" id="magic"/> <script> var outputs = window.location.href; var res = outputs.slice(107, 125); var urly = "https://heafmusttransfer.s3.us-east-2.amazonaws.com/" + res; document.getElementById("magic").src = urly; </script> </body> </html> <!-- End Default Content REMOVE THIS --> </apex:page>

I’ve broken down this code in A LOT of more detail down below. For now, what happens when you create a VisualForce page in Salesforce with this code in it?

When a Salesforce user opens up any Contact record, the JavaScript will be initiated, it will look at the URL of the page it is on (the Contact record) and isolate the 18 digits of the unique ID. It will then write out the URL that is the Amazon Cloud Services URL that always starts the same and add the 18 digit number and letter string (the Salesforce record id) to the end. Finally it will show the image that lives at this URL, and it will re-size it to be the same height as the VisualForce page that I added as a component on my Contact records. Voila! When I pull up a contact record, if we have a photo saved with the name that is the same as their unique Salesforce ID, that image will appear in the “Photo Test” component on the page - which is a VF Page Component:

Footnotes (revealing some secrets):

  1. The technical footnote: The URL that is referenced in the “window.location.href” part of the code is actually longer than just the Salesforce URL we see. So you’ll need to display that URL first to find the number of characters that come before the 18 digit unique record id. Need help doing that? Let me know!

  2. My nonprofit didn’t even end up going with this solution in the short-term!! They needed photos FAST so they put in the work to manually add them all through PhotoLoader, a third-party app for Salesforce. But we still have this option available for the future. Plus I learned a lot, so I was happy with the work.

  3. While I was writing this post, I started editing my own code. I realized that through cobbling stuff together, I actually had some erroneous lines of code, and I was able to understand what was happening in the JavaScript better and edit it to be more efficient. So THANK YOU for the opportunity to write about all this and share it, because it certainly gave me more insight into the whole thing.

  4. Using the unique ID from the URL is not the only way to do this. It is a way I thought I would know how to do and would serve the need that we identified. It might not even be the best way - I’m sure someone reading this is looking at this and thinking “omg I can’t believe they wrote this dumb code when the answer to this need is so obviously….” So obviously WHAT? Please let me know!!

I don’t think you actually need some of this - like "head" and "title" pieces. But I don’t mind having it in there like a nice little note to remind me what is happening in the code that comes next (it is “Getting the Current URL in JavaScript”). I know I could make a better title for this.
This is HTML that asks the VisualForce page to show an image (img), change the height of that image to the height I need to fit into my VisualForce page (275 pixels - don’t worry about knowing this, I tried about 5 other numbers first and reloaded my page to get to the right size for the images to appear), and the website where that image lives - except that I need some JavaScript to create the URL where the image lives (src=”” id=”magic”/>) - I called my JavaScript code "magic" because this all felt a little bit like magic to me. So we are referencing some JavaScript code that we will now review:
The "script" part here tells the VisualForce page that some JavaScript is coming to tell it to do things!

The “var” part adds a name to something. In this case it is adding the name outputs (but it could be anything you want to name it) to the “window.location.href” which is the code to find whatever the URL is of the web page open in your web browser.
Next we add the name res (but it could be anything you want to name it) on top of the result of “outputs.slice(107,125);”

.slice can be used to pull out a “slice” of a text string. For example, if we are looking at the text string “MY CAT MAX” and we use .slice(4,7) then the result would be “CAT” because we are taking a slice of our statement out - from the 4th character (“C”) and stopping before the 7th character (the space after the word cat).

In our actual use case, we are pulling out the slice that is the 18-digit unique ID from the URL of the Salesforce page of the Contact Record (and calling it res).
Next we are adding a name of urly (but it could be anything you want to name it) on top of the result of adding two things together:

The non-changing beginning to the Amazon URL where our photos are stored
+
res (which we just defined above as the slice of the Salesforce URL that contains the Contact unique ID).

That leaves us with something like:

https://heafmusttransfer.s3.us-east-2.amazonaws.com/0036T00003yE3IHQA0

(where the last 18-digits are the Contact Unique ID that came from the above steps of looking up the URL of the Salesforce page and isolating the Unique ID of the record from that URL).
This next part (“document.getElementById(XXX).src”) is a JavaScript code that I looked up but don’t totally understand. I think it just allows you to create an “Id” thingy (which is not like the Unique IDs we’ve been talking about so far - it is a kind of element or thing you can create in JavaScript).

Here the “Id” that we are creating and calling “magic” will equal the URL that we just created above and called urly. And remember from the second step - we need this Id to use as the URL we are looking for as the source for the image (img) we are asking the VisualForce page to display.

The "script" part indicates this is the end of the JavaScript section of the code.
This is just the ending that we need. Clearly I didn’t even take the time to remove where it says “REMOVE THIS” but that isn’t hurting anybody or the process.
Previous
Previous

The Secret to Documentation

Next
Next

THERE IS NO OPTING-OUT OF THE INFORMATION AGE