Tutorial: Flow External Services for Salesforce Admins

Katie - Jan 30 '20 - - Dev Community

Who remembers my #GIFSquad-friendly Salesforce Flow project from last summer, teaching Apex-Defined Data Types? I just learned that you can build the same project in Flow without writing any Apex code!

screenshot

screenshot

We'll build the same Flow as before, but with almost no code.

Business purpose

I picked this technique up from Liz Skaates, a senior product manager at Salesforce, during the Spring '20 Admin Preview video, so check it out if you haven't yet.

On a desktop, navigate to "Critical Updates & External Services" and start at 2:08. On mobile, jump to 17:45.

In the real world, Liz suggests using this to integrate Salesforce with serious 3rd-party "APIs" like from Slack, the enterprise chat room company.

For example, she points out that you could post a message containing relevant Salesforce data to a Slack chat room every time a certain type of business process happens within your Salesforce org.

  • Q: Want to see how she does that?
  • A: Watch her in the release video -- she has a powerful demo. 💪🏼

(Pssst -- other Flowtastic Spring '20 release videos: Flow for 90 minutes, Dev w/ 12 minutes of Flow.)

Disclaimer

Disclaimer: As I said, this is almost no-code.

  • Technically, you have to copy and paste a snippet of code, provided by a 3rd party (like Slack).
  • But it's no more complicated than grabbing the snippet of HTML code that YouTube makes available when you click "Embed this video."

The code you'll be copying and pasting is called a "schema." A "schema" specifies to your flow how the 3rd-party "API" you're using wants to be talked to, and how it will respond.

In that way, it functions like the Apex-Defined Data Types and Apex Invocable Action code we hand-wrote in the original post. The difference is that this time, we don't have to write it.

  • (If the 3rd-party company forgot to write a schema, it is possible to write one yourself. That's what I had to do for the YesNo silly GIF service so that you could follow along in this tutorial. It might take a developer's comfort with code, though, to write it in a way that is compatible with Salesforce External Services.)

For all practical purposes -- particularly with real-world "APIs" from major companies -- what you're about to read is no-code.


TL, DR

External Services use a small amount of "copy-and-paste" code that someone else wrote to let admins building Flows create business logic that talks to non-Salesforce computers over the internet.

Keep reading to try it yourself with an amusing side project.


Silly GIFs

As before, it sure would be nice if we could leverage amazing code other people have put on the internet to do something fun with a Flow, right?

About YesNo

We'll leverage a really fun "API" on the internet called "YesNo."

According to its documentation, an HTTP GET request to https://yesno.wtf/api will respond with plain text formatted according to the JSON standard indicating:

  1. A random yes/no/maybe answer, labeled "answer"
  2. A true/false indicating whether we forced the answer to a specific yes/no/maybe value, labeled "forced"
  3. The URL to a random GIF expressing the yes/no/maybe emotion returned, labeled "image"

Here's an example:

{"answer":"no","forced":false,"image":"https://yesno.wtf/assets/no/27-8befe9bcaeb66f865dd3ecdcf8821f51.gif"}
Enter fullscreen mode Exit fullscreen mode

YesNo has dozens, if not hundreds, of silly GIFs, so it's endless fun hitting "refresh."

Note: Want a little extra geekiness when you're done with this project?

Let's build a flow

We'll incorporate this data into a Screen Flow that looks different every time we run it.

This time, instead of asking YesNo for a silly GIF by incorporating an "Apex Action" into our Flow, we'll do it by incorporating an "External Service Action" into our Flow.

Security

First, we need to tell Salesforce that it's safe to talk to 3rd-party resources starting with https://yesno.wtf.

  1. Outside of Flow Builder, in Salesforce Setup, search for and visit "Named Credentials."
  2. Click "New Named Credential."
  3. Enter something useful like YesNo into "Label" and "Name."
  4. Enter https://yesno.wtf in "URL."
  5. Leave "Certificate" blank.
  6. Choose "Anonymous" for "Identity Type."
    • (YesNo's "API" doesn't require you to log into it to use it.)
  7. Choose "No Authentication" for "Authentication Protocol."
    • (YesNo's "API" doesn't require you to log into it to use it.)
  8. Leave "Generate Authorization Header" un-checked.
    • (YesNo's "API" doesn't require you to log into it to use it.)
  9. Leave "Allow Merge Fields in HTTP Header" and "Allow Merge Fields in HTTP Body" un-checked.
  10. Click "Save."

screenshot

Warning: In theory, one day YesNo could be taken over by hackers and start delivering viruses instead of fun GIFs.

You might want to delete this entry from your Named Credentials after you're done playing so you don't forget you put it here.

Behind-the-scenes data processing

Second, we need to teach Salesforce how YesNo works (that is, we need to teach it that the "body" of a YesNo "response" is made up of 3 parts: "answer," "forced," and "image").

  1. Outside of Flow Builder, in Salesforce Setup, search for and visit "External Services."
  2. Click "Add an External Service."
  3. Enter something useful like YesNo into "External Service Name."
  4. Pick the Named Credential you just set up, by the "Name" value you gave it, in "Select a Named Credential."
  5. In the gray box at the bottom of the editor, change the radio box to use the "Service Schema Complete JSON" option.
  6. In the text area below "Service Schema Complete JSON", paste the following "schema" code, then click "Save," and if further prompted, click "Done:" (As mentioned before, this code is what teaches your Flow how YesNo works.)

screenshot

screenshot

{
  "swagger": "2.0",
  "info": {
    "description": "This is a sample server YesNo server.  You can find out more about     Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/).  Katie Kodes wrote it.",
    "version": "99.9.9",
    "title": "YesNo"
  },
  "host": "yesno.wtf",
  "tags": [
    {
      "name": "api",
      "description": "The only endpoint YesNo offers",
      "externalDocs": {
        "description": "Find out more",
        "url": "https://yesno.wtf/#api"
      }
    }
  ],
  "schemes": [
    "https"
  ],
  "paths": {
    "/api": {
      "get": {
        "tags": [
          "api"
        ],
        "summary": "Seek a random yes, no, or maybe",
        "operationId": "seekAnswer",
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "force",
            "in": "query",
            "description": "Use this to force one of the 3 valid answers",
            "required": false,
            "type": "string",
            "enum": [
              "yes",
              "no",
              "maybe"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "successful operation",
            "schema": {
              "$ref": "#/definitions/YesNoMaybe"
            }
          }
        }
      }
    }
  },
  "definitions": {
    "YesNoMaybe": {
      "type": "object",
      "required": [
        "answer",
        "forced",
        "image"
      ],
      "properties": {
        "answer": {
          "type": "string",
          "description": "yes, no, or maybe",
          "example": "yes",
          "enum": [
            "yes",
            "no",
            "maybe"
          ]
        },
        "forced": {
          "type": "boolean",
          "description": "Did you force the answer with a query parameter?",
          "example": false
        },
        "image": {
          "type": "string",
          "description": "The URL to a random GIF of a celebrity expressing the answer",
          "example": "https://yesno.wtf/assets/no/13-755222c98795431aa2e7d453ab1e75a1.gif"
        }
      }
    }
  },
  "externalDocs": {
    "description": "Find out more about YesNo",
    "url": "https://yesno.wtf/#api"
  }
}
Enter fullscreen mode Exit fullscreen mode

Note: Sometimes, a 3rd-party "API" will provide you the convenience of hosting a URL with their "schema" code published within, rather than making you copy and paste code. That's what the "Service Schema Relative URL" option is for, as opposed to the "Service Schema Complete JSON" option, in the External Service definition screen.

Warning: Again, in theory, one day YesNo could be taken over by hackers and start delivering viruses instead of fun GIFs.

You might want to delete this entry from your External Services after you're done playing so you don't forget you put it here.

Flow action

Third ... we're ready to start building our Flow.

  1. Back in Flow Builder, start with a new Screen Flow so you have a clean design area with nothing but a "Start" node.
    • If you already had Flow Builder open before you built out the Named Credential and the External Service, you might need to close and re-open it.
  2. Click Toolbox -> Elements and drag an "Action" onto the flow builder.
  3. Click into the "Search All actions..." box and start typing "Yes." As the search results narrow down, choose "seekAnswer." (It has a subtitle of externalService-YesNo.seekAnswer.)
    • Q: Why "seekAnswer?"
    • A: Because that's what I named it in the copy-paste "schema" code I gave you above, and now you're stuck with it. 😜
  4. Give the Action a "Label" of "Ask The Internet Yes or No" and let Salesforce generate an "API Name" (it will be "Ask_The_Internet_Yes_or_No").
  5. In the lower portion of the Action definition area, under "Set Input Values," make sure that "force" has its toggle-switch (at right) turned off (grayed out, not blue, and slid to the left, and reading "Don't Include").
  6. Leave "Manually assign variables (advanced)" un-checked. You don't need it.
  7. Click "Done."

screenshot

Text template

To make our image link show up as an actual image, we have to wrap it in a little bit of HTML. For that, we need a Text Template.

  1. Click Toolbox -> Manager -> New Resource
  2. Drop down "Resource Type" and choose "Text Template"
  3. Give it a nice "API name" like viewable_gif
  4. In "Body," drop down the "down-arrow" picklist indicator to the right of the "Insert a resource..." box and change from "Rich Text" to "Plain Text."
  5. In "Text Template," in the big text-editor area below "Insert a resource...," type <img src="{!Ask_The_Internet_Yes_or_No.200.image}">
  6. Click "Done"

screenshot

screenshot

screenshot

screenshot

screenshot

Screen

  1. Click Toolbox -> Elements and drag a "Screen" onto the flow builder.
  2. Give the "Screen Properties" a "Label" of "GIF Squad Heaven" and let Salesforce generate an "API Name."
  3. Drag a "Text"-typed "Screen Component" onto the screen and give it a "Label" of "Mood." Let Salesforce generate an "API Name."
  4. Click the box below "Default Value," scroll down into the "Actions," click Outputs from Ask_The_Internet_Yes_or_No, click 2001, and click "answer." Salesforce will populate the box with{!Ask_The_Internet_Yes_or_No.200.answer}`.
  5. Drag a "Display Text"-typed "Screen Component" onto the screen and give it a good API name like the_gif.
  6. Click the "Insert a resource..." box and, under "Text Templates," choose viewable_gif. Salesforce will populate the box with {!viewable_gif}.
  7. Click "Done."

screenshot

screenshot

screenshot

screenshot

screenshot

Watch the fireworks

  1. In the flow builder, add arrow connectors flowing from Start to the Ask The Internet Yes or No action and onward to the GIF Squad Heaven screen.
  2. Click "Save"
  3. Click "Run"
  4. Refresh the page that pops up a few times until you're satisfied that your Flow is randomly picking a GIF every time you run it.

screenshot

screenshot

screenshot

screenshot


Silly GIFs -- choose your own answer

Fun, right?

GIF of Kamala Harris dancing

But I mentioned earlier that YesNo allows you to "force" a specific yes/no/maybe answer.

Let's have some fun and try that.

For simplicity's sake, we'll hand-type a specific answer into the Flow, but of course in the real world, you could use data out of your Salesforce org or the value of a variable from within your Flow.

Edit the Flow Action

  1. Click Toolbox -> Manager, scroll to Elements -> Actions, and click Ask_The_Internet_Yes_or_No to bring it up for editing. (Alternatively, double-click the icon for the action in your Flow Builder panel.)
  2. In the lower portion of the Action definition area, under "Set Input Values," make sure that "force" has its toggle-switch (at right) turned on (blue, slid to the right, and reading "Include").
  3. In the "Enter value or search resources..." box beneath the word "force," type "maybe" in all lower-case letters.
  4. Click "Done"

screenshot

Watch the fireworks

  1. In the flow builder, click "Save" to save the latest version of your flow.
  2. Click "Run"
  3. Refresh the page that pops up a few times until you're satisfied that your Flow is randomly picking a GIF associated with the word "maybe" every time you run it.

screenshot

screenshot

screenshot

Let me know -- did you get it to work??

GIF from Kim's Convenience


Takeaway

External Services make an Admin's life easier when trying to talk to a 3rd-party service over the internet in a Flow.

Warning: Don't go crazy with this functionality without researching good security practices.

  • Putting things from strangers' "APIs" into the web pages your Salesforce users will be looking at is a bit like accepting candy from a stranger.
  • Sending strangers' "APIs" your Salesforce data is a bit like giving a stranger your credit card number.

There are a lot of principles that go into good security practices, but here are two to get you started:

  1. Only use "API" URLs that start with "httpS," not plain-old "http."
  2. Only use "APIs" from companies you trust ... which includes trusting their ability to protect themselves from getting hacked.
    • In a real org, as fun as it is, YesNo is probably a little too small-time to trust.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .