PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.14.1
Yatra – Travel Booking & Tour Operator Software v3.0.14.1
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
yatra / resources / js / api / whatsapp-api.ts

whatsapp-api.ts in Yatra – Travel Booking & Tour Operator Software 3.0.14.1, at resources/js/api/whatsapp-api.ts

276 lines 8.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { apiClient } from "../lib/api-client";
2
3 /** WhatsApp module meta — drives gate states on the settings page. */
4 export interface WhatsappMeta {
5 is_eligible: boolean;
6 is_module_enabled: boolean;
7 is_configured: boolean;
8 providers: Array<{ id: string; label: string; disabled?: boolean }>;
9 /** Meta webhook setup info — operator pastes these into WhatsApp
10 * Business Manager → Webhooks subscription. `app_secret_configured`
11 * is a visibility flag only; the secret itself is encrypted at rest
12 * and never sent to the client. */
13 webhook: {
14 url: string;
15 verify_token: string;
16 app_secret_configured: boolean;
17 };
18 upgrade_url: string;
19 docs_url: string;
20 }
21
22 /** Public-facing click-to-WhatsApp widget configuration. */
23 export interface WhatsappWidgetSettings {
24 enabled: boolean;
25 /** E.164 phone the widget opens against. */
26 contact_phone: string;
27 /** Pre-filled message body. Supports `{{trip_name}}` on trip pages. */
28 prefilled_message: string;
29 /** 'all' = every frontend page, 'trips_only' = single-trip pages only. */
30 display_on: "all" | "trips_only";
31 position: "bottom-right" | "bottom-left";
32 /** Pill label next to the WhatsApp icon. Empty = icon only. */
33 label: string;
34 /** Render an in-page CTA inside the single-trip sidebar. */
35 show_on_trip_sidebar: boolean;
36 }
37
38 /** Non-template settings (provider config + opt-in + admin phone). */
39 export interface WhatsappSettings {
40 active_provider: string;
41 phone_number_id: string;
42 business_account_id: string;
43 sender_display_name: string;
44 default_country_code: string;
45 /** Destination phone for templates with recipient_type=admin. E.164. */
46 admin_phone: string;
47 opt_in_required: boolean;
48 opt_in_copy: string;
49 reminder_hours_before: number;
50 review_hours_after: number;
51 widget: WhatsappWidgetSettings;
52 }
53
54 export interface WhatsappCredentialStatus {
55 configured: boolean;
56 hint: string;
57 }
58
59 export interface WhatsappSettingsResponse {
60 settings: WhatsappSettings;
61 credentials: Record<string, Record<string, WhatsappCredentialStatus>>;
62 }
63
64 /** One row from /whatsapp/events — drives the Trigger Event dropdown. */
65 export interface WhatsappEvent {
66 key: string;
67 name: string;
68 description: string;
69 kind: "action" | "time";
70 wp_hook: string | null;
71 /** Per-event variables. Each `{ key, description }` becomes a sidebar button. */
72 variables: Array<{ key: string; description: string }>;
73 }
74
75 /** A DB row from `yatra_whatsapp_templates`. */
76 export interface WhatsappTemplate {
77 id: number;
78 template_key: string;
79 event_key: string;
80 is_system: boolean;
81 is_active: boolean;
82 name: string;
83 description: string | null;
84 body: string | null;
85 recipient_type: "customer" | "admin";
86 /** Flattened Cloud-API specifics for convenience (also in settings JSON). */
87 meta_template_name: string;
88 language_code: string;
89 settings: Record<string, unknown>;
90 created_at: string;
91 updated_at: string;
92 }
93
94 export interface WhatsappMessageRow {
95 id: number;
96 direction: "outbound" | "inbound";
97 phone: string;
98 customer_id: number | null;
99 booking_id: number | null;
100 template_key: string | null;
101 body: string | null;
102 status: string;
103 provider_message_id: string | null;
104 error_message: string | null;
105 created_at: string;
106 updated_at: string;
107 }
108
109 export interface WhatsappOptInRow {
110 phone: string;
111 opted_in: boolean;
112 source: string;
113 updated_at: string;
114 }
115
116 export interface WhatsappTestSendResult {
117 ok: boolean;
118 provider_message_id?: string;
119 error?: string;
120 }
121
122 export const whatsappApi = {
123 getMeta: () => apiClient.get("/whatsapp/meta") as Promise<WhatsappMeta>,
124
125 getSettings: () =>
126 apiClient.get("/whatsapp/settings") as Promise<WhatsappSettingsResponse>,
127
128 updateSettings: (patch: Partial<WhatsappSettings>) =>
129 apiClient.put("/whatsapp/settings", { settings: patch }) as Promise<{
130 settings: WhatsappSettings;
131 message: string;
132 }>,
133
134 updateCredential: (provider: string, field: string, value: string) =>
135 apiClient.put("/whatsapp/credentials", {
136 provider,
137 field,
138 value,
139 }) as Promise<{
140 credentials: Record<string, Record<string, WhatsappCredentialStatus>>;
141 message: string;
142 }>,
143
144 listEvents: () =>
145 apiClient.get("/whatsapp/events") as Promise<{ data: WhatsappEvent[] }>,
146
147 listTemplates: () =>
148 apiClient.get("/whatsapp/templates") as Promise<{
149 data: WhatsappTemplate[];
150 }>,
151
152 getTemplate: (id: number) =>
153 apiClient.get(`/whatsapp/templates/${id}`) as Promise<{
154 data: WhatsappTemplate;
155 }>,
156
157 createTemplate: (payload: Partial<WhatsappTemplate>) =>
158 apiClient.post("/whatsapp/templates", payload) as Promise<{
159 data: WhatsappTemplate;
160 message: string;
161 }>,
162
163 updateTemplate: (id: number, payload: Partial<WhatsappTemplate>) =>
164 apiClient.put(`/whatsapp/templates/${id}`, payload) as Promise<{
165 data: WhatsappTemplate;
166 message: string;
167 }>,
168
169 deleteTemplate: (id: number) =>
170 apiClient.delete(`/whatsapp/templates/${id}`) as Promise<{
171 message: string;
172 }>,
173
174 /**
175 * Re-seed the bundled defaults. Useful when the operator has missed
176 * a system template (deleted accidentally pre-lockdown, or a
177 * first-install race left them with none).
178 */
179 restoreDefaults: () =>
180 apiClient.post("/whatsapp/templates/restore-defaults", {}) as Promise<{
181 data: WhatsappTemplate[];
182 message: string;
183 }>,
184
185 testSendTemplate: (
186 id: number,
187 params: { phone?: string; booking_id?: number },
188 ) =>
189 apiClient.post(
190 `/whatsapp/templates/${id}/test-send`,
191 params,
192 ) as Promise<WhatsappTestSendResult>,
193
194 /**
195 * Paginated message log. Returns `total` so the UI can render correct
196 * page counts without local slicing. `page` is 1-indexed.
197 */
198 listMessages: (
199 params: {
200 page?: number;
201 per_page?: number;
202 status?: string;
203 phone?: string;
204 } = {},
205 ) =>
206 apiClient.get("/whatsapp/messages", {
207 params: {
208 page: params.page ?? 1,
209 per_page: params.per_page ?? 20,
210 ...(params.status ? { status: params.status } : {}),
211 ...(params.phone ? { phone: params.phone } : {}),
212 },
213 }) as Promise<{
214 data: WhatsappMessageRow[];
215 total: number;
216 page: number;
217 per_page: number;
218 }>,
219
220 listOptIns: () =>
221 apiClient.get("/whatsapp/opt-ins") as Promise<{ data: WhatsappOptInRow[] }>,
222
223 /* ----------------------- template versions ----------------------- */
224 /**
225 * Append-only edit history for a template. Returned newest-first.
226 * Operators restore from this list when a recent edit needs rollback.
227 */
228 listTemplateVersions: (id: number) =>
229 apiClient.get(`/whatsapp/templates/${id}/versions`) as Promise<{
230 data: WhatsappTemplateVersion[];
231 }>,
232
233 /**
234 * Restore the template to a prior snapshot. Server snapshots the
235 * CURRENT state first so the chain stays linear ("undo this restore"
236 * is just another restore from the most-recent row).
237 */
238 restoreTemplateVersion: (id: number, versionId: number) =>
239 apiClient.post(
240 `/whatsapp/templates/${id}/versions/${versionId}/restore`,
241 {},
242 ) as Promise<{
243 data: WhatsappTemplate;
244 message: string;
245 }>,
246 };
247
248 /* -------------------------------------------------------------------------- */
249 /* Template version-history shape */
250 /* -------------------------------------------------------------------------- */
251
252 /** One snapshot of a template at a moment in time. */
253 export interface WhatsappTemplateVersion {
254 id: number;
255 template_id: number;
256 /** Monotonic per template — UI displays as "v3". */
257 version_number: number;
258 /** Frozen copy of the row state at the time of the change. Subset
259 * of the fields on WhatsappTemplate plus settings as plain object. */
260 snapshot: {
261 name?: string;
262 description?: string;
263 body?: string;
264 event_key?: string;
265 recipient_type?: "customer" | "admin";
266 is_active?: boolean;
267 settings?: Record<string, unknown>;
268 is_system?: boolean;
269 };
270 /** Short human hint of what changed in THIS edit (e.g. "edited:
271 * body, is_active") or "Restored from vN" for restore rows. */
272 change_summary: string | null;
273 created_by: number | null;
274 created_at: string;
275 }
276