File size: 4,418 Bytes
df37f6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
from fastapi.responses import JSONResponse
from pydantic import BaseModel, Field
from typing import List, Dict, Any, Optional


class MessageText(BaseModel):
    text: list[str] = Field(default_factory=list)


class Message(BaseModel):
    text: MessageText | None = None
    payload: dict | None = None


class FulfillmentResponse(BaseModel):
    messages: list[Message] = Field(default_factory=list)


class SessionInfo(BaseModel):
    parameters: dict[str, Any] = Field(default_factory=dict)


class DialogflowResponse(BaseModel):
    fulfillment_response: FulfillmentResponse
    sessionInfo: Optional[SessionInfo] = Field(default_factory=dict)


def DialogFlowResponseAPI(
    text: list[str] = None,
    payload: dict | None = None,
    parameters: dict | None = None,
):

    messages = []
    if text:
        messages.append(Message(text=MessageText(text=text)))

    if payload:
        messages.append(Message(payload=payload))

    response_data = DialogflowResponse(
        fulfillment_response=FulfillmentResponse(messages=messages),
        sessionInfo=SessionInfo(parameters=parameters or {}),
    )

    return JSONResponse(content=response_data.model_dump())


def dialogflow_response(
    text: list[str] | None = None,
    payload: dict | None = None,
    parameters: dict | None = None,
) -> JSONResponse:
    messages: List[Message] = []
    if text:
        messages.append(Message(text=MessageText(text=text)))
    if payload:
        messages.append(Message(payload=payload))

    response = DialogflowResponse(
        fulfillment_response=FulfillmentResponse(messages=messages),
        sessionInfo=SessionInfo(parameters=parameters or {}),
    )
    return JSONResponse(content=response.model_dump(mode="json"))


def dialogflow_error(message: str) -> JSONResponse:
    return dialogflow_response(text=[message])


def dialogflow_choice(
    prompt: str, options: list[str], parameters: dict | None = None
) -> JSONResponse:
    chips = {
        "richContent": [[{"type": "chips", "options": [{"text": o} for o in options]}]]
    }
    return dialogflow_response(text=[prompt], payload=chips, parameters=parameters)


class DialogflowResponseBuilder:
    def __init__(self):
        self._messages: list[Message] = []
        self._parameters: dict = {}

    def add_text(self, lines: list[str]) -> "DialogflowResponseBuilder":
        if lines:
            self._messages.append(Message(text=MessageText(text=lines)))
        return self

    def add_payload(self, payload: dict) -> "DialogflowResponseBuilder":
        if payload:
            self._messages.append(Message(payload=payload))
        return self

    def add_choice_chips(
        self,
        options: list[str] | list[dict],
        key: str = None,
        prompt: str | None = None,
    ) -> "DialogflowResponseBuilder":
        if options:
            chips = {
                "richContent": [
                    [
                        {
                            "type": "chips",
                            "options": [
                                (
                                    {"text": option.get(key, "")}
                                    if isinstance(option, dict)
                                    else {"text": option}
                                )
                                for option in options
                            ],
                        }
                    ]
                ]
            }
            self.add_payload(chips)
        if prompt:
            self.add_text([prompt])
        return self

    def set_parameters(self, parameters: dict[str, any]) -> "DialogflowResponseBuilder":
        if parameters:
            self._parameters = parameters
        return self

    def build(self) -> JSONResponse:
        response = DialogflowResponse(
            fulfillment_response=FulfillmentResponse(messages=self._messages),
            sessionInfo=SessionInfo(parameters=self._parameters),
        )
        return JSONResponse(content=response.model_dump(mode="json"))


## Use Builder return (
#     DialogflowResponseBuilder()
#     .add_choice_chips(["Xem vé", "Đặt vé"], prompt="Bạn muốn làm gì tiếp?")
#     .set_parameters({"next_step": "booking"})
#     .build()
# )


class DialogServiceResult(BaseModel):
    text: list[str] | None = None
    options: list[str] | list[dict] | None = None
    parameters: dict | None = None