@gentour/dedge-support-widget 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,163 @@
1
+ # D-EDGE Support Agent Widget
2
+
3
+ Widget SDK pour intégrer l'assistant support D-EDGE sur l'extranet Availpro.
4
+
5
+ ## Installation
6
+
7
+ ### Via CDN (Production)
8
+
9
+ ```html
10
+ <script src="https://dedgesupport.gentour.ai/widget.js"></script>
11
+ <script>
12
+ DEdgeSupportWidget.init({
13
+ frontendUrl: 'https://dedgesupport.gentour.ai',
14
+ credentials: 'xxxEncodedBase64xxx', // Fourni par Gentour
15
+ });
16
+ </script>
17
+ ```
18
+
19
+ ### Via NPM
20
+
21
+ ```bash
22
+ npm install @dedge/support-agent-widget
23
+ ```
24
+
25
+ ## Configuration
26
+
27
+ ### Options
28
+
29
+ | Option | Type | Default | Description |
30
+ |--------|------|---------|-------------|
31
+ | `frontendUrl` | string | `https://dedgesupport.gentour.ai` | URL du frontend chat |
32
+ | `apiUrl` | string | `frontendUrl + /api` | URL de l'API |
33
+ | `credentials` | string | - | Credentials Base64 `btoa("email:password")` |
34
+ | `mode` | `"sidebar"` \| `"popup"` \| `"inline"` | `"sidebar"` | Mode d'affichage |
35
+ | `position` | `"right"` \| `"left"` | `"right"` | Position du widget |
36
+ | `theme` | `"light"` \| `"dark"` \| `"auto"` | `"light"` | Thème |
37
+ | `buttonText` | string | `"Need help?"` | Texte du bouton |
38
+ | `primaryColor` | string | `"#0066CC"` | Couleur principale |
39
+
40
+ ### Callbacks
41
+
42
+ ```javascript
43
+ DEdgeSupportWidget.init({
44
+ // ...
45
+ onOpen: () => console.log('Widget opened'),
46
+ onClose: () => console.log('Widget closed'),
47
+ onAuthStateChange: (user) => console.log('Auth:', user),
48
+ onContextExtracted: (ctx) => console.log('D-EDGE context:', ctx),
49
+ });
50
+ ```
51
+
52
+ ## D-EDGE Context
53
+
54
+ Le widget extrait automatiquement le contexte utilisateur depuis `dataLayer.dEdgeContext`:
55
+
56
+ ```javascript
57
+ {
58
+ userName: "Clemence DOUAY",
59
+ userEmail: "clemence.douay@availpro.com",
60
+ userId: 14695,
61
+ hotelId: 13673,
62
+ groupId: 9791
63
+ }
64
+ ```
65
+
66
+ Ce contexte est envoyé au backend pour le tracking/analytics dans Langfuse.
67
+
68
+ ## Development
69
+
70
+ ### Build
71
+
72
+ ```bash
73
+ # Install dependencies
74
+ npm install
75
+
76
+ # Build
77
+ SUPABASE_URL=https://xxx.supabase.co \
78
+ SUPABASE_ANON_KEY=eyJ... \
79
+ npm run build
80
+
81
+ # Watch mode
82
+ npm run dev
83
+
84
+ # Serve locally
85
+ npm run serve # Serves on http://localhost:3001
86
+ ```
87
+
88
+ ### Test sur l'extranet Availpro
89
+
90
+ Injecter dans la console navigateur:
91
+
92
+ ```javascript
93
+ const script = document.createElement('script');
94
+ script.src = 'http://localhost:3001/widget.js';
95
+ document.head.appendChild(script);
96
+
97
+ script.onload = () => {
98
+ DEdgeSupportWidget.init({
99
+ frontendUrl: 'http://localhost:3000',
100
+ credentials: btoa('widget@dedge.gentour.ai:yourPassword'),
101
+ });
102
+ };
103
+ ```
104
+
105
+ ## API
106
+
107
+ ### Instance Methods
108
+
109
+ ```javascript
110
+ const widget = DEdgeSupportWidget.init({ ... });
111
+
112
+ widget.open(); // Ouvrir le widget
113
+ widget.close(); // Fermer le widget
114
+ widget.toggle(); // Toggle open/close
115
+ widget.isOpen(); // Vérifier si ouvert
116
+ widget.getContext(); // Obtenir le contexte D-EDGE
117
+ widget.destroy(); // Détruire le widget
118
+ ```
119
+
120
+ ## Setup: Supabase Technical User
121
+
122
+ The widget requires a technical Supabase user for authentication. Follow these steps:
123
+
124
+ ### 1. Create the user in Supabase
125
+
126
+ Go to your Supabase Dashboard > Authentication > Users, and create a new user:
127
+
128
+ - **Email:** `widget@dedge.gentour.ai` (or your preferred email)
129
+ - **Password:** Generate a strong password
130
+
131
+ ### 2. Add agent permissions (if not using default)
132
+
133
+ If `dedge-support-agent` is not in the `DEFAULT_ALLOWED_AGENTS` list in auth-proxy, add it to the user's `app_metadata`:
134
+
135
+ ```sql
136
+ -- Run in Supabase SQL Editor
137
+ UPDATE auth.users
138
+ SET raw_app_meta_data = raw_app_meta_data || '{"allowed_agents": ["dedge-support-agent"]}'::jsonb
139
+ WHERE email = 'widget@dedge.gentour.ai';
140
+ ```
141
+
142
+ ### 3. Configure the widget
143
+
144
+ Encode the credentials and use them in the widget initialization:
145
+
146
+ ```javascript
147
+ // Generate credentials (do this once, securely)
148
+ const credentials = btoa('widget@dedge.gentour.ai:yourPassword');
149
+ console.log('Credentials:', credentials);
150
+
151
+ // Use in widget
152
+ DEdgeSupportWidget.init({
153
+ frontendUrl: 'https://dedgesupport.gentour.ai',
154
+ credentials: credentials,
155
+ });
156
+ ```
157
+
158
+ ### Security Notes
159
+
160
+ - The Base64 encoding is for obfuscation, not encryption
161
+ - If credentials are compromised, change the password and rebuild/redeploy the widget
162
+ - The worst-case scenario is someone consuming LLM tokens
163
+ - Consider rate limiting at the API level for additional protection
package/dist/auth.d.ts ADDED
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Authentication module for the widget
3
+ * Handles Supabase authentication within the widget
4
+ */
5
+ import type { User, Session } from "@supabase/supabase-js";
6
+ export interface AuthState {
7
+ user: User | null;
8
+ session: Session | null;
9
+ loading: boolean;
10
+ }
11
+ export declare class WidgetAuth {
12
+ private supabase;
13
+ private authState;
14
+ private listeners;
15
+ constructor(url: string, anonKey: string);
16
+ private initialize;
17
+ private updateState;
18
+ private notifyListeners;
19
+ subscribe(listener: (state: AuthState) => void, skipInitialCall?: boolean): () => void;
20
+ getState(): AuthState;
21
+ getAccessToken(): string | null;
22
+ signIn(email: string, password: string): Promise<{
23
+ user: User;
24
+ session: Session;
25
+ weakPassword?: import("@supabase/supabase-js").WeakPassword;
26
+ }>;
27
+ signOut(): Promise<void>;
28
+ }
29
+ /**
30
+ * Decode Base64 credentials
31
+ * @param credentials Base64-encoded "email:password" string
32
+ * @returns Object with email and password, or null if invalid
33
+ */
34
+ export declare function decodeCredentials(credentials: string): {
35
+ email: string;
36
+ password: string;
37
+ } | null;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Build-time configuration for the widget
3
+ * These values are injected at build time from environment variables
4
+ *
5
+ * Usage: Set SUPABASE_URL and SUPABASE_ANON_KEY environment variables before building
6
+ * Example: SUPABASE_URL=https://xxx.supabase.co SUPABASE_ANON_KEY=eyJ... npm run build
7
+ */
8
+ /**
9
+ * Get Supabase configuration if available
10
+ * Returns undefined if not configured (auth will be disabled)
11
+ */
12
+ export declare function getSupabaseConfig(): {
13
+ url: string;
14
+ anonKey: string;
15
+ } | undefined;
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Types for the D-EDGE Support Agent Widget SDK
3
+ */
4
+ export type WidgetMode = "sidebar" | "popup" | "inline";
5
+ export type WidgetPosition = "right" | "left";
6
+ export type WidgetTheme = "light" | "dark" | "auto";
7
+ /**
8
+ * D-EDGE context extracted from the Availpro extranet dataLayer
9
+ * Used for tracking/analytics purposes (NOT for authentication)
10
+ */
11
+ export interface DEdgeContext {
12
+ /**
13
+ * User's display name from Availpro
14
+ */
15
+ userName: string;
16
+ /**
17
+ * User's email from Availpro
18
+ */
19
+ userEmail: string;
20
+ /**
21
+ * User's ID in Availpro system
22
+ */
23
+ userId: number;
24
+ /**
25
+ * Hotel ID the user is currently viewing
26
+ */
27
+ hotelId: number;
28
+ /**
29
+ * Group ID the hotel belongs to
30
+ */
31
+ groupId: number;
32
+ }
33
+ /**
34
+ * Widget initialization options
35
+ */
36
+ export interface DEdgeSupportWidgetOptions {
37
+ /**
38
+ * URL of the Next.js chat frontend where the /widget page is hosted.
39
+ * @example "https://dedgesupport.gentour.ai"
40
+ */
41
+ frontendUrl?: string;
42
+ /**
43
+ * URL of the Next.js API proxy (frontendUrl + /api).
44
+ * If not provided, defaults to frontendUrl + "/api".
45
+ * @example "https://dedgesupport.gentour.ai/api"
46
+ */
47
+ apiUrl?: string;
48
+ /**
49
+ * ID of the LangGraph assistant.
50
+ * @default "dedge-support-agent"
51
+ */
52
+ assistantId?: string;
53
+ /**
54
+ * Base64-encoded credentials for Supabase authentication.
55
+ * Format: btoa("email:password")
56
+ * @example btoa("widget@dedge.gentour.ai:secretPassword")
57
+ */
58
+ credentials?: string;
59
+ /**
60
+ * Widget display mode.
61
+ * @default "sidebar"
62
+ */
63
+ mode?: WidgetMode;
64
+ /**
65
+ * Widget position (for sidebar mode).
66
+ * @default "right"
67
+ */
68
+ position?: WidgetPosition;
69
+ /**
70
+ * Widget theme.
71
+ * @default "light"
72
+ */
73
+ theme?: WidgetTheme;
74
+ /**
75
+ * Button text.
76
+ * @default "Need help?"
77
+ */
78
+ buttonText?: string;
79
+ /**
80
+ * Primary color (hex).
81
+ * @default "#0066CC" (D-EDGE blue)
82
+ */
83
+ primaryColor?: string;
84
+ /**
85
+ * Container ID (for inline mode).
86
+ */
87
+ containerId?: string;
88
+ /**
89
+ * Widget width.
90
+ * @default "50vw" for sidebar, "400px" for popup
91
+ */
92
+ width?: string;
93
+ /**
94
+ * Widget height.
95
+ * @default "100vh" for sidebar
96
+ */
97
+ height?: string;
98
+ /**
99
+ * Callbacks
100
+ */
101
+ onOpen?: () => void;
102
+ onClose?: () => void;
103
+ onAuthStateChange?: (user: {
104
+ id: string;
105
+ email?: string;
106
+ } | null) => void;
107
+ onContextExtracted?: (context: DEdgeContext | null) => void;
108
+ }
109
+ /**
110
+ * Widget instance interface
111
+ */
112
+ export interface DEdgeSupportWidgetInstance {
113
+ /**
114
+ * Open the widget.
115
+ */
116
+ open: () => void;
117
+ /**
118
+ * Close the widget.
119
+ */
120
+ close: () => void;
121
+ /**
122
+ * Toggle open/close.
123
+ */
124
+ toggle: () => void;
125
+ /**
126
+ * Check if the widget is open.
127
+ */
128
+ isOpen: () => boolean;
129
+ /**
130
+ * Get the extracted D-EDGE context.
131
+ */
132
+ getContext: () => DEdgeContext | null;
133
+ /**
134
+ * Update configuration.
135
+ */
136
+ updateConfig: (config: Partial<DEdgeSupportWidgetOptions>) => void;
137
+ /**
138
+ * Destroy the widget.
139
+ */
140
+ destroy: () => void;
141
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * D-EDGE Support Agent Widget SDK
3
+ */
4
+ import type { DEdgeSupportWidgetInstance, DEdgeSupportWidgetOptions, DEdgeContext } from "./types";
5
+ /**
6
+ * Main initialization function for the widget.
7
+ */
8
+ declare function initDEdgeSupportWidget(config: DEdgeSupportWidgetOptions): DEdgeSupportWidgetInstance;
9
+ export { initDEdgeSupportWidget };
10
+ export type { DEdgeContext };