Contents
- Contents
- WARNING:
- Why Was I Doing All this?
- Salesforce Backlog CLI
- Requirements
- TLDR (Execution with Docker)
- Current State
- Script’s Data Flow
- Caveats
- Progress and Roadmap
- What Did I Learn?
- What Is Next?
WARNING:
Dear non existing reader, I am not going to bullshit you. If, for any strange reason, you checked my Github repo or my DockerHub some time ago, you will realize that I am copying and pasting most of that content here.
I failed to create a blog post entry when I was actually working on this project, so that is the reason why I am posting it only until now.
Why Was I Doing All this?
One of the reasons is that I am a “terminal person”. If I can do something via terminal, I will try at least. I don’t consider myself a “Terminal Guru”, but again, I will try…
Then, there is the convoluted Salesforce GUI. This is how I feel when I go through this:
Don’t get me wrong, Salesforce is an amazing tool, it does its job, but my workflow is made with a very limited set of options compared to that millions that the platform offers. In my case, as a support engineer, the most common tasks are:
- Check backlog of cases.
- Reading/Changing status.
- Triggering some in-house automation via GUI.
- Adding internal and external notes.
- Replying to the customers. (Which I can do via my email client)
- Reading logs and trying to reproduce software defects in the lab.
In the face of this, I decided that I wanted to at least have my backlog of cases in the terminal. This of course might enable the possibility for further automation.
Finally, this was another attempt to work on a project instead of just doing “purposless loops” for practicing code. So, here we go…
Salesforce Backlog CLI
Golang script for interacting with the Salesforce API.
The script is meant to be used mainly by Salesforce users instead of admins.
The drive behind this was/is to automate repetitive and tedious tasks within the technical support engineer role, such as:
- Reviewing backlog of cases via Salesforce GUI.
- Retrieving case information via Salesforce GUI.
- Retrieving attachments via Salesforce GUI.
To accomplish this, the script is executed as a CLI tool.
Requirements
- Internet connection.
- Salesforce API access.
- Docker (Recommended for script execution)
NOTE: Source code and the compiled binary are available in case you do not have or prefer Docker. However, the execution is recommended via Docker.
TLDR (Execution with Docker)
- Get the CLI tool.
docker run -it rabocse/salesforce-backlog-cli
- In the container CLI, proceed to paste Salesforce Credentials: email, password, salesforce instance, client ID, client Secret and security key.
export EMAIL=rabocse@mydomain.com
export PASS=MyFakePassword123
export SF=myfake.sf.instance.salesforce.com
export CLID=xxxxxxxyyyyyyyyyyaaaaaaabbbbbbbbdddddddddddd22211111
export CLSE=11111112222222333333344444aaaaaccccc1112222222
export SECK=BAD23XXXXXXXXFFF
- Get your backlog of cases:
./main
Current State
The tool successfully requests an access token to the Salesforce Instance to authenticate and then downloads the data from sObjects/case resource ("/services/data/v55.0/sobjects/case").
First, the user must set the required credentials to authenticate against the Salesforce API. For this, environment variables are passed in the container CLI.
Once the environment variables are set, the tool is ready to be executed:
❯ ./main
+--------------------+
| SALESFORCE BACKLOG |
+--------------------+
+-----+-------------+----------------+--------------------------------+---------------+--------+-----------------------------+
| # | CASE NUMBER | CONTACT NAME | SUBJECT | SEVERITY | STATUS | ENVIRONMENT |
+-----+-------------+----------------+--------------------------------+---------------+--------+-----------------------------+
| 1 | 1234567 | Dexter | [AMER] Dee Dee Pushed some | Sev1 (High) | Open | Dexter's Lab |
| | | | Config and Services Now Are | | | |
| | | | Down | | | |
+-----+-------------+----------------+--------------------------------+---------------+--------+-----------------------------+
| 2 | 1234568 | Johnny Bravo | [AMER] Need Her Contact Number | Sev1 (High) | Open | Johnny's Mom's House |
| | | | ASAP!!! | | | |
+-----+-------------+----------------+--------------------------------+---------------+--------+-----------------------------+
| 3 | 7654321 | Dexter | [AMER] Quantum Scaling | Sev3 (Normal) | Open | Dexter's Lab |
| | | | Sometimes Fails | | | |
+-----+-------------+----------------+--------------------------------+---------------+--------+-----------------------------+
| 4 | 1122334 | Hyoga C. | [EMEA] Frozen Container is | Sev3 (Normal) | Open | Knights of the Zodiac |
| | | | Leaking Memory | | | |
+-----+-------------+----------------+--------------------------------+---------------+--------+-----------------------------+
| 5 | 9876543 | Master Roshi | [APAC] KameHouse Service Not | Sev3 (Normal) | Open | DBZ |
| | | | Accesible After Changing Cert | | | |
+-----+-------------+----------------+--------------------------------+---------------+--------+-----------------------------+
| 6 | 1234566 | Kakashi Hatake | [APAC] Unable to Deploy | Sev4 (Normal) | Open | Konoha Leaf Village |
| | | | Rinnegan Service. Stuck In MS | | | |
| | | | Phase 2 | | | |
+-----+-------------+----------------+--------------------------------+---------------+--------+-----------------------------+
| 7 | 1234555 | Aizen Sosuke. | [APAC] PROACTIVE: Upgrade | Sev3 (Low) | Open | Gotei 13 Inc |
| | | | Shinigami's Cluster to same | | | |
| | | | version than Espada's Cluster | | | |
+-----+-------------+----------------+--------------------------------+---------------+--------+-----------------------------+
| 8 | 7777777 | Tony Stark | [EMEA] Ultron's service does | Sev3 (Low) | Open | Stark Labs (Sokovia Center) |
| | | | not work as expected. | | | |
+-----+-------------+----------------+--------------------------------+---------------+--------+-----------------------------+
Script’s Data Flow
The script reads the environment variables (EMAIL, PASS, SF, CLID, CLSE, SECK) from the user’s terminal.
These environment variables are used to authenticate against the Salesforce instance and get an access token.
Once the access token is properly downloaded and parsed, it is used in a HTTP header for the data request.
The listview (Salesforce resource) is queried and successfully unmarshalled to be printed in a table format.
Caveats
The listview ID is currently hardcoded within sftool.BuildURL function.
The Salesforce API version is also hardcoded to v55.0.
Progress and Roadmap
- Input for the script to be accepted via environment variables. [DONE]
- Parse JSON output and extract only the “access token” value. [DONE]
- Pass the access token value to the next section of the script. [DONE]
- Avoid the usage of external tools (jq and/or grep), build the presentation of data in the source code. (Table format) [DONE]
- Create “Go modules” and share the interim state of the script. [DONE]
- Containerize the application. [DONE]
- Modify the downloaded resource (currently sObject/case) to a resource that provides the list of active cases from the engineer.
- Allow the user to specify a case ID to get additional information about it.
- Get the attachment from Salesforce:
- Direct attachments from Salesforce.
- Attachments from a third-party integrated tool like S-Drive.
- Add business logic or a feature to specify the listview ID to be retrieved. (See the caveats for reference)
NOTE: The only reason why I am sharing this is to show what I had in mind when working on this. At the moment, I no longer have access to the Salesforce API and therefore I cannot continue working on it.
What Did I Learn?
During my years as a technical support engineer, I was merely a Salesforce user and I was never interested in being more than that. This project forced me to spend some time learning about Salesforce from an admin point of view.
I know it sounds silly but this project really reminded me not to reinvent the wheel. There were so many moments when I realized that I opted for doing something by myself when there was already a library that could do it already. Even for the fact of retrieving this info from Salesforce, there are existing libraries, although I felt the focus was more from an admin point of view and not my use case.
I thought this was going to take a lot less time and decided to skip the error validation in pretty much everything. I am not proud of it. Next time, I will add it as I am progressing.
Handling dependencies is an art in itself. Oh God! I know I did not build anything complex but this super simple project made me realize it.
What Is Next?
I am currently evaluating how to automate some of the mentioned tasks if I do not have direct access to the Salesforce API. I am not sure yet if the effor is worth it, time will tell I guess. ;)