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 Answer 1

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!

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .