0

Hello I'm trying to create a flow in dialogflow cx, where in case of multiple options I want my user to select 1 option where all the options are buttons. I have used the default payload but not sure how can I send back which button got clicked to my webhook and return respective info, currently if I click on button it simply open example.com, if I exclude the link it opens same page in new tab.

 {
                "type": "button",
                "icon": {
                    "type": "chevron_right",
                    "color": "#FF9800"
                },
                "text": "Button text 1",
                "link" : "www.example.com",
                "event": {
                    "name": "some name",
                    "languageCode": "en",
                    "parameters": {}
                }
   }
Jessica Rodriguez
  • 2,899
  • 1
  • 12
  • 27
Rishabh
  • 23
  • 8
  • In order to understand better your issue, could you tell me what the expected result was ? Also, have you followed this documentation in order to add buttons to Agent, [here](https://cloud.google.com/dialogflow/es/docs/intents-rich-messages#card)? – Alexandre Moraes Jun 23 '21 at 08:06
  • Hi Alexandre, the link you have shared is for dialogflow es and I'm using cx. I think button payload for the 2 is different, and yes I have verified it any I see the buttons coming up in dialogflow messenger bot. As an expected output I want to see button triggering something at backend where I receive my option set and return something back to user on basis of that button input – Rishabh Jun 23 '21 at 17:31
  • Have you configured a costom payload to handle your rich resposne(button)? Such as described [here](https://cloud.google.com/dialogflow/cx/docs/concept/fulfillment#payload). Also this question on Stack has an answer which is similar to what you are looking for: [link1](https://stackoverflow.com/questions/66076024/clickable-options-in-dialgflow-cx) and [link2](https://cloud.google.com/dialogflow/cx/docs/concept/integration/dialogflow-messenger#button_response_type). – Alexandre Moraes Jun 24 '21 at 09:35
  • Nope I have already checked both links you have pasted and yes I have used the custom payload, my problem is I want to send the button text back to webhook when it's clicked but somehow it unachieved so far – Rishabh Jun 25 '21 at 06:03

2 Answers2

1

For your use case, since the button response type always redirects to a page when clicked, you can consider using suggestion chips instead.

{
  "richContent": [
    [
      {
        "options": [
          {
            "text": "Chip 1"
          },
          {
            "text": "Chip 2"
          }
        ],
        "type": "chips"
      }
    ]
  ]
}

Suggestion chips act like a user text query when the user clicks on it, therefore, you can just create a route that can be triggered by text of the chip and get the text query from the webhook request sent to your webhook to return the respective information. For example:

Intent:

enter image description here

Route:

enter image description here

Then in your webhook, you can get the parameter value in the text field of the webhook request which you will refer to in order to create a webhook response with the respective information.

Here’s an example in Node.js using Express:

app.post("/webhook", (req, res) => {
  let option = req.body.text;
  let jsonResponse = {
    fulfillment_response: {
      messages: [
        {
          text: {
            //fulfillment text response to be sent to the agent
            text: [`You've chosen the ${option} option`]
          }
        }
      ]
    }
  };
  res.json(jsonResponse);
});

Alternatively, you can also use entity types and assign the selected chip into a parameter that will be also sent to your webhook.

To assign the text of the chip to a parameter, the intent of the route should contain training phrases that are annotated to an entity type containing all of the options. For example:

Intent:

enter image description here

Entity Type:

enter image description here

Then in your webhook, you can get the parameter value in the intentInfo.parameters.parameter_id.resolvedValue field of the webhook request which you will refer to in order to create a webhook response with the respective information.

Here’s an example in Node.js using Express:

app.post("/webhook", (req, res) => {
  let option = req.body.intentInfo.parameters.options.resolvedValue;
  let jsonResponse = {
    fulfillment_response: {
      messages: [
        {
          text: {
            //fulfillment text response to be sent to the agent
            text: [`You've chosen the ${option} option`]
          }
        }
      ]
    }
  };
  res.json(jsonResponse);
});

Results:

Marc
  • 373
  • 1
  • 4
  • Hi Mark, your suggestion seems too helpful but before I proceed with implementation I want to confirm that is it same for both DF-ES and DF-CX versions? since I'm using CX and your attested snaps looks to be from ES. Thanks!! – Rishabh Jun 28 '21 at 09:42
  • This solution is for Dialogflow CX edition only. All the screenshots provided are from the Dialogflow CX console. – Marc Jun 30 '21 at 23:22
  • Thank you Marc!! I'll keep you posted – Rishabh Jul 01 '21 at 06:34
  • It doesn't work for me, when I tried using fuflillment_response it does work if the response if it was fulfillmentResponse – Anshuman Kumar Jun 23 '22 at 08:42
0

There is a simple albeit hacky way I have discover possible (tested in es). Which is to make a chip and get its element then force clicking it

We can listen to button click and I detect that it was empty button with just text. Then I use renderCustomCard to make a chip. Everything inside dialogflow messenger are hidden deep inside nested shadowRoot. But as of now its structure allow us to get the chip out to call click() on it. In effect it make it seem very the same as user manually click the chip


      const dfMessenger = document.querySelector('df-messenger');
      
      dfMessenger.addEventListener('df-button-clicked',function(event) {
        if(event.detail.element.event || event.detail.element.link)
          return;
        
        dfMessenger.renderCustomCard([
          {
            "type": "chips",
            "options": [
              {
                "text": event.detail.element.text
              }
            ]
          }
        ]);

        var messageList = dfMessenger.shadowRoot.querySelector("df-messenger-chat").shadowRoot.querySelector("df-message-list").shadowRoot;
        var chips = [...messageList.querySelectorAll("df-chips")].flatMap((chips) => [...chips.shadowRoot.querySelectorAll(".df-chips-wrapper>a")]).filter((a) => a.innerHTML.indexOf(event.detail.element.text) > -1);
        if(chips.length > 0)
          chips.slice(-1)[0].click();
      });

Working for today. No guarantee they will block this method in the future. But I actually guess they would implement actual postback button in similar manner later after beta version

Thaina Yu
  • 1,372
  • 2
  • 16
  • 27
  • Hey Thaina...I implemented the Chip based approach, and it seems to fit well as per the needs. Thanks for the suggestion though I'm not sure if it'll work the same way in cx too. – Rishabh Nov 10 '22 at 11:12