dialogflowAPI / app /api /routes.py
OnlyBiggg
fix
56ddfb0
raw
history blame
17.5 kB
from typing import Dict, List
from fastapi import FastAPI, APIRouter, HTTPException, Request, Response # type: ignore
from fastapi.responses import JSONResponse, RedirectResponse, HTMLResponse # type: ignore
from datetime import datetime, timedelta
from fastapi.templating import Jinja2Templates
from app.services import api
from app.utils.constants import code_province
from app.types.Respone import DialogFlowResponseAPI
router = APIRouter()
templates = Jinja2Templates(directory="app/templates")
def to_datetime_from_Dialogflow(time: dict):
date_time = datetime(int(time["year"]), int(time["month"]), int(time["day"]))
return date_time
# Xử lý fromTime và toTime
def process_dates_to_timestamp(from_time: datetime = None, to_time: datetime = None):
if to_time is None and from_time is not None:
to_time = from_time.replace(hour=23, minute=59, second=59)
if from_time is None:
today = datetime.today().date()
from_time = datetime.combine(today, datetime.min.time())
to_time = datetime.combine(today, datetime.max.time()) - timedelta(microseconds=1)
return int(from_time.timestamp()) * 1000 , int(to_time.timestamp()) * 1000
def get_param_from_dialogflow(body: any):
session_info = body.get("sessionInfo", {})
parameters = session_info.get("parameters")
raw_date = parameters.get("date")
if raw_date is not None:
raw_date = to_datetime_from_Dialogflow(raw_date)
raw_departure_city = parameters.get("departure_city")
raw_destination_city = parameters.get("destination_city")
raw_ticket_number = parameters.get("ticket_number")
raw_time_of_day = parameters.get("time_of_day")
return raw_departure_city, raw_destination_city, raw_ticket_number, raw_date, raw_time_of_day
async def search_route_ids_from_province(departure_code: str, destination_code: str):
response = await api.get(f'/metadata/office/routes?DestCode={destination_code}&OriginCode={departure_code}')
route_ids = []
if isinstance(response, list): # Kiểm tra nếu data là danh sách
route_ids = [route.get("routeId", -1) for route in response]
return route_ids
@router.post('/routes')
async def route(request: Request):
body = await request.json()
raw_departure_city, raw_destination_city, raw_ticket_number , raw_date, _ = get_param_from_dialogflow(body)
ticket_count = int(raw_ticket_number) if raw_ticket_number else 1
if raw_date is None:
from_time, to_time = process_dates_to_timestamp()
date = datetime.today().date().strftime('%m-%d-%Y')
else:
date = raw_date.strftime('%m-%d-%Y')
from_time, to_time = process_dates_to_timestamp(raw_date)
departure_code = code_province.get(raw_departure_city)
destination_code = code_province.get(raw_destination_city)
route_dep_to_des = await search_route_ids_from_province(departure_code,destination_code)
route_des_to_dep = await search_route_ids_from_province(destination_code,departure_code)
routes_ids = list(set(route_dep_to_des + route_des_to_dep))
payload = {
"from_time": from_time,
"to_time": to_time,
"route_ids": routes_ids,
"ticket_count": 1,
"sort_by": ["price", "departure_time"]
}
try:
respone = await api.post("/search/trips", payload=payload)
data = respone["data"]["items"]
total = respone["data"]["total"]
if total > 0:
price = data[0]["price"]
list_raw_departure_times = sorted(list(set([ trip["raw_departure_time"] for trip in data])))
list_raw_seat_type = list(set([ trip["seat_type_name"] for trip in data]))
seat_type_trip_string = "**" + "** | **".join(map(str, list_raw_seat_type)) + "**"
schedule_time_trip = "**" + "** | **".join(map(str, list_raw_departure_times)) + "**"
duration = data[0]["duration"]
link = f'https://stag.futabus.vn/dat-ve?from={departure_code}&fromTime={date}&isReturn=false&ticketCount={ticket_count}&to={destination_code}&toTime='
text = [f"Tuyến xe **{raw_departure_city}** - **{raw_destination_city}**\n \
Loại xe: {seat_type_trip_string} \n \
Thời gian hành trình: {duration} giờ \n \
Giá vé: **{price}** VND"]
payload = {
"richContent": [
[
{
"type": "chips",
"options": [
{"text": "Tìm chuyến xe"},
{"text": "Xem lịch trình khác"},
{"text": "Không, cảm ơn"}
]
}
]
]
}
return DialogFlowResponseAPI(text=text, payload=payload)
text = [f"Hệ thống không tìm thấy tuyến xe **{raw_departure_city}** - **{raw_destination_city}**.\n Quý khách vui lòng thử lại với lộ trình khác hoặc liên hệ Trung tâm tổng đài 1900 6067 để được hỗ trợ."]
payload = {
"richContent": [
[
{
"type": "chips",
"options": [
{"text": "Xem lịch trình khác"},
{"text": "Không, cảm ơn"}
]
}
]
]
}
return DialogFlowResponseAPI(text=text, payload=payload)
# return DialogFlowResponeAPI(text=['Hello'])
except Exception as e:
return DialogFlowResponseAPI(text=["Hệ thống xảy ra lỗi. Quý khách vui lòng thử lại sau hoặc liên hệ Trung tâm tổng đài 1900 6067 để được hỗ trợ."])
@router.post('/price')
async def price(request: Request):
body = await request.json()
raw_departure_city, raw_destination_city, _, raw_date, _ = get_param_from_dialogflow(body)
if raw_date is None:
from_time, to_time = process_dates_to_timestamp()
from_time, to_time = process_dates_to_timestamp(raw_date)
departure_code = code_province.get(raw_departure_city)
destination_code = code_province.get(raw_destination_city)
route_dep_to_des = await search_route_ids_from_province(departure_code,destination_code)
route_des_to_dep = await search_route_ids_from_province(destination_code,departure_code)
routes_ids = list(set(route_dep_to_des + route_des_to_dep))
payload = {
"from_time": from_time,
"to_time": to_time,
"route_ids": routes_ids,
"ticket_count": 1,
"sort_by": ["price", "departure_time"]
}
try:
respone = await api.post("/search/trips", payload=payload)
total = respone["data"]["total"]
if total > 0:
price = respone["data"]["items"][0]["price"]
text = [f"Tuyến xe **{raw_departure_city}** - **{raw_destination_city}**\n"
f"Giá vé: **{price}** VND.\n \
Bạn có muốn đặt vé không?"
]
payload = {
"richContent": [
[
{
"type": "chips",
"options": [
{"text": "Có, tôi muốn đặt vé"},
{"text": "Xem giá vé tuyến xe khác"},
{"text": "Không, cảm ơn"}
]
}
]
]
}
return DialogFlowResponseAPI(text=text, payload=payload)
text = [f"Hệ thống không tìm thấy tuyến xe **{raw_departure_city}** - **{raw_destination_city}**.\n Quý khách vui lòng thử lại với lộ trình khác hoặc liên hệ Trung tâm tổng đài 1900 6067 để được hỗ trợ."]
payload={
"richContent": [
[
{
"type": "chips",
"options": [
{"text": "Xem giá vé lịch trình khác"},
{"text": "Không, cảm ơn"}
]
}
]
]
}
return DialogFlowResponseAPI(text=text, payload=payload)
except:
return DialogFlowResponseAPI(text=["Hệ thống xảy ra lỗi. Quý khách vui lòng thử lại sau hoặc liên hệ Trung tâm tổng đài 1900 6067 để được hỗ trợ."])
@router.post('/trip/list')
async def booking_trip(request: Request) -> Response:
body = await request.json()
raw_departure_city, raw_destination_city, raw_ticket_number, raw_date, raw_time_of_day = get_param_from_dialogflow(body)
date = raw_date.strftime('%m-%d-%Y')
from_time, to_time = process_dates_to_timestamp(raw_date)
ticket_count = int(raw_ticket_number) if raw_ticket_number else 1
departure_code = code_province.get(raw_departure_city)
destination_code = code_province.get(raw_destination_city)
route_dep_to_des = await search_route_ids_from_province(departure_code,destination_code)
route_des_to_dep = await search_route_ids_from_province(destination_code,departure_code)
routes_ids = list(set(route_dep_to_des + route_des_to_dep))
payload = {
"from_time": from_time,
"to_time": to_time,
"route_ids": routes_ids,
"ticket_count": ticket_count,
"sort_by": ["price", "departure_time"]
}
try:
response = await api.post("/search/trips", payload=payload)
if response.get('status') == 200:
data = response["data"]["items"]
total = response["data"]["total"]
if total > 0:
list_raw_departure_times = sorted(list(set([ trip["raw_departure_time"] for trip in data])))
schedule_time_trip = "**" + "** | **".join(map(str, list_raw_departure_times)) + "**"
trips = []
routes_name = []
for trip in data:
if trip["route"] and trip["route"]["name"] not in routes_name:
routes_name.append(trip["route"]["name"])
trips.append({
"route_name": trip["route"]["name"],
"route_id": trip["route_id"],
"id": trip["id"],
"departure_date": trip["raw_departure_date"],
"departure_time": trip["raw_departure_time"],
"kind": trip["seat_type_name"]
})
text = ["\n".join(f"{i+1}. {name}" for i, name in enumerate(routes_name))]
payload={
"richContent": [
[
{
"type": "chips",
"options": [
{"text": name} for name in (routes_name)
]
}
]
]
}
parameters = {
"trip_list": trips,
"routes_name": routes_name
}
return DialogFlowResponseAPI(text=text, payload=payload,parameters=parameters)
text = [f"Hệ thống không tìm thấy tuyến xe **{raw_departure_city}** - **{raw_destination_city}**.\n Quý khách vui lòng thử lại với lộ trình khác hoặc liên hệ Trung tâm tổng đài 1900 6067 để được hỗ trợ."]
payload={
"richContent": [
[
{
"type": "chips",
"options": [
{"text": "Xem tuyến xe khác"},
{"text": "Không, cảm ơn"}
]
}
]
]
}
return DialogFlowResponseAPI(text=text, payload=payload)
except Exception as e:
print(e)
return JSONResponse(
{
"fulfillment_response": {
"messages": [
{
"text": {
"text": ["Hệ thống xảy ra lỗi. Quý khách vui lòng thử lại sau hoặc liên hệ Trung tâm tổng đài 1900 6067 để được hỗ trợ."]
}
}
]
},
}
)
@router.post('/trip/check-trip-select')
async def is_valid_select_trip(request: Request) -> Response:
body = await request.json()
raw_input = body.get("text", "")
print('raw input:', raw_input)
session_info = body.get("sessionInfo", {})
parameters = session_info.get("parameters")
routes_name = parameters.get("routes_name")
if raw_input in routes_name:
trip_list: List[Dict[str, any]] = parameters.get("trip_list")
for trip in trip_list:
if trip["route_name"] == raw_input:
route_id = int(trip["route_id"])
break
parameters = {
"is_valid_trip": True,
"route_name": raw_input,
"route_id": route_id
}
else:
parameters = {
"is_valid_trip": False,
}
return DialogFlowResponseAPI(parameters=parameters)
@router.post('/trip/time-trip-list')
async def time_trip(request: Request) -> Response:
try:
body = await request.json()
session_info = body.get("sessionInfo", {})
parameters = session_info.get("parameters")
trip_list: List[Dict[str, any]] = parameters.get("trip_list", [])
raw_route_id = parameters.get("route_id", None)
route_id = int(raw_route_id) if raw_route_id else None
time_list = []
for trip in trip_list:
if trip["route_id"] == route_id:
time_list.append(trip["departure_time"])
parameters = {
"time_list": time_list
}
text = [" | ".join(map(str, time_list))]
return DialogFlowResponseAPI(text=text, parameters=parameters)
except Exception as e:
print(e)
return DialogFlowResponseAPI(text=["Hệ thống xảy ra lỗi. Quý khách vui lòng thử lại sau hoặc liên hệ Trung tâm tổng đài 1900 6067 để được hỗ trợ."])
@router.post('/trip/check-time-select')
async def is_valid_select_time(request: Request) -> Response:
try:
body = await request.json()
session_info = body.get("sessionInfo", {})
parameters = session_info.get("parameters")
time_list: List[Dict[str, any]] = parameters.get("time_list")
time = parameters.get("time")
print(time)
raw_input = body.get("text","")
if raw_input in time_list:
parameters = {
"is_valid_time": True,
"departure_time": raw_input
}
else:
parameters = {
"is_valid_time": False
}
text = ["Bạn đã chọn thời gian: " + raw_input]
return DialogFlowResponseAPI(text=text, parameters=parameters)
except Exception as e:
print(e)
return DialogFlowResponseAPI(text=["Hệ thống xảy ra lỗi. Quý khách vui lòng thử lại sau hoặc liên hệ Trung tâm tổng đài 1900 6067 để được hỗ trợ."])
@router.get("/")
def home():
return "Hello World!"
@router.get('/chatbot', response_class=HTMLResponse)
async def index(request: Request):
return templates.TemplateResponse("index.html", {"request": request, "title": "Dawi Chatbot"})