Iterate over a list of Dialogflow fulfillment messages

In this walk through, we’ll demonstrate how you can use a Dialogflow intent with multiple responses. We’ll show you how to iterate over each response with a 1 second delay before outputting each message to the user.

Dialogflow

Setup your intent

Add multiple responses

Example output in the Dialogflow simulator

{
  "responseId": "4d14cf28-8da4-4339-933f-26e34e4234b9-d5092e1d",
  "queryResult": {
    "queryText": "What's your favourite color?",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "fulfillmentText": "Ocean",
    "fulfillmentMessages": [
      {
        "text": {
          "text": [
            "Midnight"
          ]
        }
      },
      {
        "text": {
          "text": [
            "Ocean"
          ]
        }
      }
    ],
    "intent": {
      "name": "projects/test-bot-erik-dev-vqlk/agent/intents/ea72f7a3-396d-47e4-aa06-6fe4dae26026",
      "displayName": "color"
    },
    "intentDetectionConfidence": 1,
    "languageCode": "en"
  }
}

BFML + Python

triggers:
  - expect: dialogflow
    integration: integration.dialogflow

steps:
  - match:
      ^smalltalk\.:
        flow: flow.nlu.smalltalk
        data: (@ flow )
        transfer: true
      ^color:
        flow: flow.nlu.color
        data: (@ flow )
        transfer: true
    default:
      flow: flow.catchall
# requires:
#   flow.dialogflow_response (obj)

steps:
  - flow_set:
      counter: 0
      list: (@ flow.dialogflow_response.queryResult.fulfillmentMessages )
  - (pop)
  - flow_set:
      counter: (@ flow.counter + 1 )
  - type: component.pop
    list: (@ flow.list )
  - if: (@ flow.result )
    then: next
    else: end
  - say: (@ flow.counter ) - (@ flow.result.text.text[0] )
  - delay: 1
  - jump: pop
from dataclasses import dataclass
from meya.component.element import Component
from meya.element.field import element_field
from meya.element.field import response_field
from meya.entry import Entry
from typing import Any
from typing import List
from typing import Optional


@dataclass
class PopComponent(Component):
    """
    Pass in a list, and this component will pop the last item
    and put in on flow.result.
    The remaining list will be available on flow.list
    """

    list: List[Any] = element_field()

    @dataclass
    class Response:
        result: Optional[Any] = response_field()
        list: List[Any] = response_field()

    async def start(self) -> List[Entry]:
        result = self.list.pop()
        response = self.Response(result=result, list=self.list)
        return self.respond(data=response)

🎉 Result