File size: 7,920 Bytes
14829b0
46de342
14829b0
1177692
 
 
 
 
 
460daa1
1177692
 
0fd2793
748bce1
106be9f
0fd2793
1177692
 
4ad7e4c
1177692
0fd2793
 
1177692
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
07cf938
1177692
07cf938
1177692
07cf938
1177692
 
0fd2793
1177692
f8c9cb6
1177692
0fd2793
46de342
fc793c4
3a56f2d
fc793c4
999e1a0
46de342
846464b
20e8126
0fd2793
3a56f2d
748bce1
999e1a0
0fd2793
59153f0
0fd2793
846464b
0fd2793
 
4b24988
80df51e
 
4b24988
0fd2793
 
46de342
0fd2793
a19c73b
7cabd4a
46de342
7cabd4a
 
0fd2793
 
 
 
 
 
46de342
c12eddb
9ed1f61
c283c6b
9ed1f61
 
 
 
 
 
7cabd4a
9ed1f61
 
 
 
 
 
 
 
 
 
 
 
 
 
90e6ae1
4b24988
1c44e05
748bce1
e5a6ec4
46de342
c283c6b
865dea0
c283c6b
 
 
 
46de342
865dea0
c283c6b
2bca53f
c283c6b
865dea0
2bca53f
c283c6b
865dea0
2bca53f
c283c6b
865dea0
2bca53f
c283c6b
 
 
865dea0
 
 
 
46de342
0fd2793
 
 
 
 
f8c9cb6
0fd2793
3a56f2d
46de342
0fd2793
 
 
 
 
 
 
3a56f2d
0fd2793
3a56f2d
0fd2793
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# ================================
# api-data.py
# ================================

import json
import asyncio
import os
import re
import requests
import chainlit as cl
from dotenv import load_dotenv

# --------------------------------=== API URL ===-----------------------------------
API_URL = "https://firmahytte.daysoff.no/api/bookings"

# --------------------------------=== environment ===-------------------------------
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
token = os.environ.get("DAYSOFF_API_TOKEN")

# ----------------------------=== API error-handling ===--------------------------------

class APIConnectionError(Exception):
    """Raised when API connection fails"""
    pass

class APIResponseError(Exception):
    """Raised when API returns an invalid response"""
    pass

class BookingNotFoundError(Exception):
    """Raised when booking ID is not found"""
    pass

async def async_post_request(url, headers, data):
    try:
        response = await asyncio.to_thread(requests.post, url, headers=headers, json=data)
        response.raise_for_status()
        return response
    except requests.ConnectionError:
        raise APIConnectionError("Failed to connect to booking service")
    except requests.Timeout:
        raise APIConnectionError("Request timed out")
    except requests.RequestException as e:
        raise APIResponseError(f"API request failed: {str(e)}")


# ----------------------------=== booking_agent_system ===------------------------------

async def booking_agent_system(message: cl.Message, msg: cl.Message) -> bool:

    user_message = message.content  # -- doc: extract message text
    booking_pattern = r'\b[A-Z]{6}\d{6}\b' # -- raw string (r'')
    match = re.search(booking_pattern, user_message)

    if match:
        preliminary = (
            f"Takk for bookingnummer ๐Ÿ‘๐Ÿป "
            "Jeg skal sjekke dette for deg nรฅ. Vennligst et รธyeblikk bare..\n"
        )
        for token in preliminary.split():
            await msg.stream_token(token + " ")  # --โ€”โ€”> streams each token
            await asyncio.sleep(0.05)  # --โ€”โ€”> simulates d/-streaming delay
            await msg.send()

        bookingnumber = match.group()
        headers = {
            'Authorization': f"Bearer {token}",
            "Content-Type": "application/json"
        }
        payload = {
            "token": "0v8mYvhh22REJidE2foWvlu2YQd",
            "bookingnumber": bookingnumber
        }

        try:

            response = await async_post_request(API_URL, headers, payload)
            response.raise_for_status()
            response_data = response.json()
            booking_data = response_data.get('data', {})

            print("API Response Data:", json.dumps(booking_data, indent=2))

            if not booking_data:
                raise BookingNotFoundError("Ingen booking funnet med dette bookingnummeret.")
            if "error" in booking_data:
                raise APIResponseError(booking_data["error"])

            table = (
                "\n\n## ๐˜ฝ๐™ค๐™ค๐™ ๐™ž๐™ฃ๐™œ ๐™ž๐™ฃ๐™›๐™ค๐™ง๐™ข๐™–๐™จ๐™Ÿ๐™ค๐™ฃ\n\n"
                f"| ๐ต๐‘œ๐‘œ๐‘˜๐‘–๐‘›๐‘”๐‘›๐‘ข๐‘š๐‘š๐‘’๐‘Ÿ | {booking_data.get('order_number', 'N/A')} |\n"
                f"|:-----|:------------------|\n"
                f"| ๐™‰๐™–๐™ข๐™š          | {booking_data.get('name', 'N/A')} |\n"
                f"| ๐™๐™ž๐™ข๐™š ๐™๐™ง๐™ค๐™ข     | {booking_data.get('time_from', 'N/A')} |\n"
                f"| ๐˜ผ๐™ง๐™ง๐™ž๐™ซ๐™–๐™ก ๐™๐™ž๐™ข๐™š  | {booking_data.get('timearrival', 'N/A')} |\n"
                f"| ๐™๐™ž๐™ข๐™š ๐™๐™ค       | {booking_data.get('time_to', 'N/A')} |\n"
                f"| ๐˜ฟ๐™š๐™ฅ๐™–๐™ง๐™ฉ๐™ช๐™ง๐™š ๐™๐™ž๐™ข๐™š| {booking_data.get('timedeparture', 'N/A')} |\n"
                f"| ๐™๐™ž๐™ข๐™š๐™ฏ๐™ค๐™ฃ๐™š     | {booking_data.get('timezone', 'N/A')} |\n"
                f"| ๐˜ผ๐™™๐™ง๐™š๐™จ๐™จ      | {booking_data.get('adress', 'N/A')} |\n"
                f"| ๐™•๐™ž๐™ฅ ๐˜พ๐™ค๐™™๐™š     | {booking_data.get('zip', 'N/A')} |\n"
                f"| ๐™‹๐™ก๐™–๐™˜๐™š        | {booking_data.get('place', 'N/A')} |\n"
                f"| ๐˜พ๐™ค๐™ช๐™ฃ๐™ฉ๐™ง๐™ฎ      | {booking_data.get('country', 'N/A')} |\n"
                f"| ๐™‡๐™ค๐™˜๐™–๐™ฉ๐™ž๐™ค๐™ฃ      | Lat: {booking_data.get('lat', 'N/A')}, Long: {booking_data.get('long', 'N/A')} |\n"
                f"| ๐™‚๐™ช๐™š๐™จ๐™ฉ๐™จ        | {booking_data.get('guests', 'N/A')} |\n"
                f"| ๐™‚๐™ช๐™š๐™จ๐™ฉ ๐™Ž๐™ช๐™ข    | {booking_data.get('guest_sum', 'N/A')} |\n"
                f"| ๐˜พ๐™ค๐™ข๐™ฅ๐™–๐™ฃ๐™ฎ ๐˜พ๐™ค๐™ฃ๐™ฉ๐™ง.| {booking_data.get('company_contribution', 'N/A')} |\n"
                f"| ๐™‹๐™–๐™ž๐™™         | {booking_data.get('paid', 'N/A')} |\n"
                f"| ๐˜ผ๐™˜๐™˜๐™š๐™ฅ๐™ฉ๐™š๐™™      | {booking_data.get('accepted', 'N/A')} |\n"
                f"| ๐˜พ๐™–๐™ฃ๐™˜๐™š๐™ก๐™ก๐™š๐™™     | {'Yes' if booking_data.get('cancelled', 0) else 'No'} |\n"
                f"| ๐˜พ๐™ค๐™ฃ๐™ฉ๐™–๐™˜๐™ฉ ๐™‰๐™–๐™ข๐™š | {booking_data.get('contactname', 'N/A')} |\n"
                f"| ๐˜พ๐™ค๐™ฃ๐™ฉ๐™–๐™˜๐™ฉ ๐™€๐™ข๐™–๐™ž๐™ก| {booking_data.get('contactemail', 'N/A')} |\n"
                f"| ๐˜พ๐™ค๐™ฃ๐™ฉ๐™–๐™˜๐™ฉ ๐™‹๐™๐™ค๐™ฃ๐™š| {booking_data.get('contactphone', 'N/A')} |\n"
                f"| ๐˜พ๐™ค๐™ช๐™ฃ๐™ฉ๐™ง๐™ฎ ๐˜พ๐™ค๐™™๐™š | {booking_data.get('country_code', 'N/A')} |\n"
            )

            await msg.stream_token(table)
            await asyncio.sleep(0.07)
            await msg.send()

            header = (
                "\n\n# ๐—ฉ๐—ถ๐—ธ๐˜๐—ถ๐—ด ๐—œ๐—ป๐—ณ๐—ผ๐—ฟ๐—บ๐—ฎ๐˜€๐—ท๐—ผ๐—ป ๐—ผ๐—บ ๐—ข๐—ฝ๐—ฝ๐—ต๐—ผ๐—น๐—ฑ๐—ฒ๐˜\n\n"
            )
            await msg.stream_token(header)
            await asyncio.sleep(0.07)
            await msg.send()

            # ๐˜ฟ๐™š๐™จ๐™˜๐™ง๐™ž๐™ฅ๐™ฉ๐™ž๐™ค๐™ฃ
            markdown = (
                "\n\n# ๐Ÿ‡ฉ ๐Ÿ‡ช ๐Ÿ‡ธ ๐Ÿ‡จ ๐Ÿ‡ท ๐Ÿ‡ฎ ๐Ÿ‡ต ๐Ÿ‡น ๐Ÿ‡ฎ ๐Ÿ‡ด ๐Ÿ‡ณ\n\n"
                f"{booking_data.get('description', 'N/A')}\n\n"
                f"โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”"
                "\n\n# ๐Ÿ‡ฆ ๐Ÿ‡ท ๐Ÿ‡ท ๐Ÿ‡ฎ ๐Ÿ‡ป ๐Ÿ‡ฆ ๐Ÿ‡ฑ\n\n"
                f"{booking_data.get('arrival', 'N/A')}\n\n"
                f"โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”"
                "\n\n# ๐Ÿ‡ฉ ๐Ÿ‡ช ๐Ÿ‡ต ๐Ÿ‡ฆ ๐Ÿ‡ท ๐Ÿ‡น ๐Ÿ‡บ ๐Ÿ‡ท ๐Ÿ‡ช\n\n"
                f"{booking_data.get('departure', 'N/A')}\n\n"
                f"โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”"
                "\n\n# ๐Ÿ‡ง ๐Ÿ‡ช ๐Ÿ‡ฉ ๐Ÿ‡ฉ ๐Ÿ‡ฎ ๐Ÿ‡ณ ๐Ÿ‡ฌ\n\n"
                f"{booking_data.get('bedding', 'N/A')}"
            )

            await msg.stream_token(markdown)
            await asyncio.sleep(0.07)
            await msg.send()


        except (APIConnectionError, APIResponseError, BookingNotFoundError) as e:
            error_msg = (
                f"๐Ÿ™„ {str(e)} "
            )
            for token in error_msg.split():
                await msg.stream_token(token + " ")
                #await asyncio.sleep(0.01)
            await msg.send()
            return True

        except requests.exceptions.RequestException as e:
            unexpected = (
                f"๐Ÿคฏ {str(e)} "
                "En uventet feil oppstod. Vennligst kontakt Daysoff tech support"
            )
            for token in unexpected.split():
                await msg.stream_token(token + " ")
                #await asyncio.sleep(0.01)
            await msg.send()
            return True