2

I'm trying to play with External Site Settings-based HTTP callouts from Flow as seen in last Friday's Spring '20 release webinar for admins ("External Site Settings" explanation & demo starts at 17:45).

I'm trying to experiment with a more "clicks, not code"-based way to reproduce the "silly GIF" screen flow seen at https://katiekodes.com/flow-apex-defined-data-types/#watch-the-fireworks.

Unfortunately, the parts of my Flow that are supposed to render yes/no/maybe and a GIF (e.g. {!Get_YesNo_From_External_Service.200.image}) simply render whitespace.

Something must be going wrong with the way I set up the org, or with the way I set up the Flow, or both.

Would anyone be able to help me troubleshoot?

The REST API endpoint from which I'm trying to include data is https://yesno.wtf/api (also sometimes https://yesno.wtf/api?forced=yes, etc), and its documentation exists at https://yesno.wtf/#api.

1. I set up a YesNo Named Credential YesNo.namedCredential-meta.xml as follows:

<?xml version="1.0" encoding="UTF-8"?>
<NamedCredential xmlns="http://soap.sforce.com/2006/04/metadata">
    <allowMergeFieldsInBody>true</allowMergeFieldsInBody>
    <allowMergeFieldsInHeader>true</allowMergeFieldsInHeader>
    <endpoint>https://yesno.wtf/api</endpoint>
    <generateAuthorizationHeader>true</generateAuthorizationHeader>
    <label>YesNo</label>
    <principalType>Anonymous</principalType>
    <protocol>NoAuthentication</protocol>
</NamedCredential>

2. Just for good measure, there's an active Remote Site Setting with a ServiceName of YesNo and Remote Site URL of https://yesno.wtf. YesNo.remoteSite-meta.xml:

<?xml version="1.0" encoding="UTF-8"?>
<RemoteSiteSetting xmlns="http://soap.sforce.com/2006/04/metadata">
    <disableProtocolSecurity>false</disableProtocolSecurity>
    <isActive>true</isActive>
    <url>https://yesno.wtf</url>
</RemoteSiteSetting>

3. Under External Services, I have an "enhanced" service YesNo.externalServiceRegistration-meta.xml with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<ExternalServiceRegistration xmlns="http://soap.sforce.com/2006/04/metadata">
    <label>YesNo</label>
    <namedCredential>YesNo</namedCredential>
    <schema>{
  &quot;swagger&quot;: &quot;2.0&quot;,
  &quot;info&quot;: {
    &quot;description&quot;: &quot;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.&quot;,
    &quot;version&quot;: &quot;99.9.9&quot;,
    &quot;title&quot;: &quot;YesNo&quot;
  },
  &quot;host&quot;: &quot;yesno.wtf&quot;,
  &quot;tags&quot;: [
    {
      &quot;name&quot;: &quot;api&quot;,
      &quot;description&quot;: &quot;The only endpoint YesNo offers&quot;,
      &quot;externalDocs&quot;: {
        &quot;description&quot;: &quot;Find out more&quot;,
        &quot;url&quot;: &quot;https://yesno.wtf/#api&quot;
      }
    }
  ],
  &quot;schemes&quot;: [
    &quot;https&quot;
  ],
  &quot;paths&quot;: {
    &quot;/api&quot;: {
      &quot;get&quot;: {
        &quot;tags&quot;: [
          &quot;api&quot;
        ],
        &quot;summary&quot;: &quot;Seek a random yes, no, or maybe&quot;,
        &quot;operationId&quot;: &quot;seekAnswer&quot;,
        &quot;produces&quot;: [
          &quot;application/json&quot;
        ],
        &quot;parameters&quot;: [
          {
            &quot;name&quot;: &quot;forced&quot;,
            &quot;in&quot;: &quot;query&quot;,
            &quot;description&quot;: &quot;Use this to force one of the 3 valid answers&quot;,
            &quot;required&quot;: false,
            &quot;type&quot;: &quot;string&quot;,
            &quot;enum&quot;: [
              &quot;yes&quot;,
              &quot;no&quot;,
              &quot;maybe&quot;
            ]
          }
        ],
        &quot;responses&quot;: {
          &quot;200&quot;: {
            &quot;description&quot;: &quot;successful operation&quot;,
            &quot;schema&quot;: {
              &quot;$ref&quot;: &quot;#/definitions/YesNoMaybe&quot;
            }
          }
        }
      }
    }
  },
  &quot;definitions&quot;: {
    &quot;YesNoMaybe&quot;: {
      &quot;type&quot;: &quot;object&quot;,
      &quot;required&quot;: [
        &quot;answer&quot;,
        &quot;forced&quot;,
        &quot;image&quot;
      ],
      &quot;properties&quot;: {
        &quot;answer&quot;: {
          &quot;type&quot;: &quot;string&quot;,
          &quot;description&quot;: &quot;yes, no, or maybe&quot;,
          &quot;example&quot;: &quot;yes&quot;,
          &quot;enum&quot;: [
            &quot;yes&quot;,
            &quot;no&quot;,
            &quot;maybe&quot;
          ]
        },
        &quot;forced&quot;: {
          &quot;type&quot;: &quot;boolean&quot;,
          &quot;description&quot;: &quot;Did you force the answer with a query parameter?&quot;,
          &quot;example&quot;: false
        },
        &quot;image&quot;: {
          &quot;type&quot;: &quot;string&quot;,
          &quot;description&quot;: &quot;The URL to a random GIF of a celebrity expressing the answer&quot;,
          &quot;example&quot;: &quot;https://yesno.wtf/assets/no/13-755222c98795431aa2e7d453ab1e75a1.gif&quot;
        }
      }
    }
  },
  &quot;externalDocs&quot;: {
    &quot;description&quot;: &quot;Find out more about YesNo&quot;,
    &quot;url&quot;: &quot;https://yesno.wtf/#api&quot;
  }
}</schema>
    <schemaType>OpenApi</schemaType>
    <status>Complete</status>
</ExternalServiceRegistration>

For readability, here's the actual JSON for that schema (note that I wrote it myself by hand, since "YesNo.WTF" doesn't come with an OpenAPI schema, but it seems to validate, and the flow's nested picklists auto-populate with things like "answer" or "forced" as components of the repsonse, so I guess I did something right):

{
  "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": "forced",
            "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"
  }
}

4. Here's the XML for my flow Get_YesNo_From_External_Service.flow-meta.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Flow xmlns="http://soap.sforce.com/2006/04/metadata">
    <actionCalls>
        <name>Get_YesNo_From_External_Service</name>
        <label>Get YesNo From External Service</label>
        <locationX>174</locationX>
        <locationY>50</locationY>
        <actionName>YesNo.seekAnswer</actionName>
        <actionType>externalService</actionType>
        <connector>
            <targetReference>GIF_Squad_Heaven</targetReference>
        </connector>
        <inputParameters>
            <name>forced</name>
            <value>
                <stringValue>maybe</stringValue>
            </value>
        </inputParameters>
        <storeOutputAutomatically>true</storeOutputAutomatically>
    </actionCalls>
    <interviewLabel>Get YesNo From External Service {!$Flow.CurrentDateTime}</interviewLabel>
    <label>Get YesNo From External Service</label>
    <processMetadataValues>
        <name>BuilderType</name>
        <value>
            <stringValue>LightningFlowBuilder</stringValue>
        </value>
    </processMetadataValues>
    <processMetadataValues>
        <name>OriginBuilderType</name>
        <value>
            <stringValue>LightningFlowBuilder</stringValue>
        </value>
    </processMetadataValues>
    <processType>Flow</processType>
    <screens>
        <name>GIF_Squad_Heaven</name>
        <label>GIF Squad Heaven</label>
        <locationX>317</locationX>
        <locationY>50</locationY>
        <allowBack>true</allowBack>
        <allowFinish>false</allowFinish>
        <allowPause>false</allowPause>
        <fields>
            <name>Top</name>
            <fieldText>&lt;p&gt;There should be a picture below this text.&lt;/p&gt;</fieldText>
            <fieldType>DisplayText</fieldType>
        </fields>
        <fields>
            <name>Mood</name>
            <fieldText>&lt;p&gt;&lt;span style=&quot;font-size: 24px;&quot;&gt;{!Get_YesNo_From_External_Service.200.answer}&lt;/span&gt;&lt;/p&gt;</fieldText>
            <fieldType>DisplayText</fieldType>
        </fields>
        <fields>
            <name>GIF</name>
            <fieldText>&lt;p&gt;{!viewable_gif}&lt;/p&gt;</fieldText>
            <fieldType>DisplayText</fieldType>
        </fields>
        <fields>
            <name>Bottom</name>
            <fieldText>&lt;p&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(62, 62, 60);&quot;&gt;There should be a picture above this text.&lt;/span&gt;&lt;/p&gt;</fieldText>
            <fieldType>DisplayText</fieldType>
        </fields>
        <showFooter>false</showFooter>
        <showHeader>false</showHeader>
    </screens>
    <start>
        <locationX>50</locationX>
        <locationY>50</locationY>
        <connector>
            <targetReference>Get_YesNo_From_External_Service</targetReference>
        </connector>
    </start>
    <status>Draft</status>
    <textTemplates>
        <name>viewable_gif</name>
        <text>&lt;img src=&quot;{!Get_YesNo_From_External_Service.200.image}&quot;&gt;</text>
    </textTemplates>
</Flow>

Any thoughts why my Flow isn't talking to yesno.wtf properly / isn't rendering the response?

1

Salesforce's Liz Skaates figured it out: the Named Credential endpoint should just be the https://domain.com part of the API, not the full https://domain.com/endpoint_base.

<?xml version="1.0" encoding="UTF-8"?>
<NamedCredential xmlns="http://soap.sforce.com/2006/04/metadata">
    <allowMergeFieldsInBody>true</allowMergeFieldsInBody>
    <allowMergeFieldsInHeader>true</allowMergeFieldsInHeader>
    <endpoint>https://yesno.wtf</endpoint>
    <generateAuthorizationHeader>true</generateAuthorizationHeader>
    <label>YesNo</label>
    <principalType>Anonymous</principalType>
    <protocol>NoAuthentication</protocol>
</NamedCredential>

It works now!

| improve this answer | |

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.