# JavaScript Custom Events

This document describes all custom events dispatched by **Joinchat** and **Joinchat Premium** with its addons. These events can be listened to using `document.addEventListener()` to extend functionality or integrate with third-party tools.

## Core (Joinchat) Events

These events are used internally by Joinchat and can be listened to for tracking or custom integrations.

### joinchat:starting

Dispatched before Joinchat initialization begins.

> **Internal Use:** This event is primarily for internal communication between Joinchat and Premium addons.

**File:** `joinchat/public/js/joinchat.js`

**Detail:** None

**Example:**

```
document.addEventListener('joinchat:starting', () => {
  console.log('Joinchat is starting...');
});
Code language: JavaScript (javascript)
```

### joinchat:start

Dispatched when Joinchat has finished initialization and is ready.

**File:** `joinchat/public/js/joinchat.js`

**Detail:** None

**Note:** After this event, `joinchat_obj.is_ready` will be `true`.

**Example:**

```
document.addEventListener('joinchat:start', () => {
  console.log('Joinchat is ready');
  console.log('Settings:', window.joinchat_obj.settings);
});
Code language: JavaScript (javascript)
```

### joinchat:show

Dispatched when the chat dialog is opened.

**File:** `joinchat/public/js/joinchat.js`, Multiple (listened in tracking)

**Detail:**

```
{
  trigger: string // How the dialog was triggered
}
Code language: CSS (css)
```

**Trigger values:**

- `'button'` - User clicked the main button
- `'contact'` - User clicked contact/open button inside chat
- `'auto'` - Automatically opened after delay
- `'hover'` - Mouse hover trigger (desktop only)
- `'url'` - Opened via URL parameter or anchor (#joinchat)
- `'trigger'` - Triggered by custom element click
- `'screen'` - Triggered by scroll (element visible on screen)
- `'agent'` - Clicked on support agent (Support Agents addon)
- `'unknown'` - Unknown source

**Example:**

```
document.addEventListener('joinchat:show', (e) => {
  console.log('Chat opened via:', e.detail.trigger);
});
Code language: JavaScript (javascript)
```

### joinchat:hide

Dispatched when the chat dialog is closed.

**File:** `joinchat/public/js/joinchat.js`, Multiple (listened internally)

**Detail:** None

**Example:**

```
document.addEventListener('joinchat:hide', () => {
  console.log('Chat dialog closed');
});
Code language: JavaScript (javascript)
```

### joinchat:bubbles

Dispatched when all chat bubbles have been shown (after animation completes).

> **Internal Use:** This event is primarily for internal communication between Joinchat and Premium addons.

**File:** `joinchat/public/js/joinchat.js`

**Detail:** None

**Example:**

```
document.addEventListener('joinchat:bubbles', () => {
  console.log('All chat bubbles have been displayed');
});
Code language: JavaScript (javascript)
```

### joinchat:optin

Dispatched when the user toggles the opt-in checkbox.

**File:** `joinchat/public/js/joinchat.js`, Multiple (listened in tracking)

**Detail:**

```
{
  optin: boolean // true if user accepts, false if rejects
}
Code language: CSS (css)
```

**Example:**

```
document.addEventListener('joinchat:optin', (e) => {
  console.log('Opt-in status:', e.detail.optin ? 'accepted' : 'rejected');
});
Code language: JavaScript (javascript)
```

### joinchat:event

Dispatched before sending analytics events. This event is **cancelable**.

**File:** `joinchat/public/js/joinchat.js`

**Detail:**

```
{
  event_category: string,  // Event category (default: 'JoinChat')
  event_label: string,     // Destination URL or label
  event_action: string,    // Action description (format: "channel: id")
  chat_channel: string,    // Channel name (e.g., 'whatsapp')
  chat_id: string,         // Channel contact (phone, username)
  is_mobile: string,       // 'yes' or 'no'
  page_location: string,   // Current page URL
  page_title: string       // Page title
}
Code language: CSS (css)
```

**Cancelable:** Yes. Return `false` to prevent analytics events from being sent.

**Note:** You can modify the `params` object to customize analytics data before it's sent.

**Example:**

```
document.addEventListener('joinchat:event', (e) => {
  console.log('Analytics event:', e.detail);

  // Modify params before sending
  e.detail.event_label = 'Custom Label';

  // Or cancel the event
  if (someCondition) {
    e.preventDefault();
    return false;
  }
});
Code language: JavaScript (javascript)
```

### joinchat:open

Dispatched when about to open a WhatsApp link or chat channel. This event is **cancelable**.

**File:** `joinchat/public/js/joinchat.js`, `addons/omnichannel/public/js/joinchat-omnichannel.js`

**Detail:**

```
{
  link: string,         // WhatsApp or channel link URL
  chat_channel: string, // Channel app name (e.g., 'whatsapp', 'telegram')
  chat_id: string,      // Channel ID (phone number or username)
  chat_message: string, // Message to send
  trigger: string       // How the action was triggered (see trigger values above)
}
Code language: JavaScript (javascript)
```

**Cancelable:** Yes. Return `false` to prevent the link from opening.

**Note:** You can modify the `params` object to customize the link or message before opening.

**Example:**

```
document.addEventListener('joinchat:open', (e) => {
  console.log('Opening channel:', e.detail.chat_channel);
  console.log('Message:', e.detail.chat_message);
  console.log('Triggered by:', e.detail.trigger);

  // Modify params before opening
  e.detail.chat_message = 'Custom message';

  // Or cancel if certain condition
  if (someCondition) {
    e.preventDefault();
    return false;
  }
});
Code language: JavaScript (javascript)
```

## Chat Funnels Events

Events dispatched by the Chat Funnels addon.

### joinchat:funnel

Dispatched to load a specific chat funnel.

> **Internal Use:** This event is primarily for internal communication between Joinchat and Premium addons.

**File:** `addons/chat-funnels/public/js/joinchat-chat-funnels.js` (listened)

**Detail:**

```
{
  funnel: number,  // Funnel ID to load
  start_at: number, // Step number to start at (default: 0)
  reset: boolean    // Whether to reset chat log and inputs (default: false)
}
Code language: CSS (css)
```

**Example:**

```
// Trigger loading a funnel
document.dispatchEvent(new CustomEvent('joinchat:funnel', {
  detail: { funnel: 1, start_at: 0, reset: true }
}));
Code language: JavaScript (javascript)
```

### joinchat:bubble

Dispatched when a new chat bubble is added to the conversation.

**File:** `addons/chat-funnels/public/js/joinchat-chat-funnels.js`

**Detail:**

```
{
  bubble: HTMLElement, // The bubble DOM element
  message: string      // The message content (HTML)
}
Code language: CSS (css)
```

**Example:**

```
document.addEventListener('joinchat:bubble', (e) => {
  console.log('New message:', e.detail.message);
  console.log('Bubble element:', e.detail.bubble);
});
Code language: JavaScript (javascript)
```

### joinchat:goto

Dispatched when a user selects a "goto" option in a chat funnel.

**File:** `addons/chat-funnels/public/js/joinchat-chat-funnels.js`

**Detail:**

```
{
  text: string, // Option text selected by user ([direct] if no text)
  step: string  // Step identifier in format "funnel_id-step_number"
}
Code language: CSS (css)
```

**Example:**

```
document.addEventListener('joinchat:goto', (e) => {
  console.log('User selected:', e.detail.text);
  console.log('Going to step:', e.detail.step);
});
Code language: JavaScript (javascript)
```

### joinchat:input

Dispatched when a user submits input in a chat funnel.

**File:** `addons/chat-funnels/public/js/joinchat-chat-funnels.js`

**Detail:**

```
{
  name: string,  // Input field name
  value: string, // Input value entered by user
  input: string, // Input type ('text', 'email', 'phone', 'number', 'date', 'time', 'select')
  text: string   // Display text (only for 'select' type)
}
Code language: CSS (css)
```

**Example:**

```
document.addEventListener('joinchat:input', (e) => {
  console.log(`<span class="javascript">Field "${e.detail.name}" (${e.detail.input}):`, e.detail.value);
});
</span>Code language: JavaScript (javascript)
```

### joinchat:link

Dispatched when a user clicks a link option in a chat funnel.

**File:** `addons/chat-funnels/public/js/joinchat-chat-funnels.js`

**Detail:**

```
{
  link: string,     // The link URL
  type: string,     // Link type: 'anchor', 'external', or 'internal'
  text: string      // Link display text
}
Code language: CSS (css)
```

**Example:**

```
document.addEventListener('joinchat:link', (e) => {
  console.log('Link clicked:', e.detail.link);
  console.log('Link type:', e.detail.type);
});
Code language: JavaScript (javascript)
```

### joinchat:contact

Dispatched when contact options are enabled in the chat.

**File:** `addons/chat-funnels/public/js/joinchat-chat-funnels.js`

**Detail:**

```
{
  mode: string // Contact mode: 'default', 'custom', or 'custom_message'
}
Code language: CSS (css)
```

**Example:**

```
document.addEventListener('joinchat:contact', (e) => {
  console.log('Contact enabled with mode:', e.detail.mode);
});
Code language: JavaScript (javascript)
```

### joinchat:ai

Dispatched when control is passed to an AI agent.

**File:** `addons/chat-funnels/public/js/joinchat-chat-funnels.js`

**Detail:**

```
{
  chat: Array,    // Chat log with role and content
  inputs: Object, // User inputs collected so far
  metas: Object   // Metadata (url, title, date, time, lang, etc.)
}
Code language: JavaScript (javascript)
```

**Example:**

```
document.addEventListener('joinchat:ai', (e) => {
  console.log('AI agent activated');
  console.log('Chat history:', e.detail.chat);
  console.log('User inputs:', e.detail.inputs);
  console.log('Metadata:', e.detail.metas);
});
Code language: JavaScript (javascript)
```

### joinchat:submitPrepare

Dispatched before the submission payload is sent to the server. Third parties can mutate the payload in place to add or edit parameters.

**File:** `addons/chat-funnels/public/js/joinchat-chat-funnels.js`

**Detail:**

```
{
  submission: Object, // Read-only snapshot for context
  data: Object,       // Mutable submission data object
  meta: Object,       // Mutable submission metadata object
  webhook: boolean    // True when triggered by a webhook step with server endpoint
}
Code language: JavaScript (javascript)
```

**Example:**

```
document.addEventListener('joinchat:submitPrepare', (e) => {
  if (e.detail.webhook) {
    console.log('Prepare payload for server-side webhook submit');
  }
  e.detail.submission.data.source = 'newsletter';
  e.detail.submission.meta.integration = 'crm-x';
});
Code language: JavaScript (javascript)
```

### joinchat:submitSuccess

Dispatched when data submission to the server succeeds.

**File:** `addons/chat-funnels/public/js/joinchat-chat-funnels.js`

**Detail:**

```
{
  response: any,   // Server response (parsed JSON or text)
  data: Object     // Submission data sent to server
  webhook: boolean // True when triggered by a webhook step with server endpoint
}
Code language: JavaScript (javascript)
```

**Example:**

```
document.addEventListener('joinchat:submitSuccess', (e) => {
  console.log('Data submitted successfully');
  console.log('Server response:', e.detail.response);
});
Code language: JavaScript (javascript)
```

### joinchat:submitError

Dispatched when data submission to the server fails.

**File:** `addons/chat-funnels/public/js/joinchat-chat-funnels.js`

**Detail:**

```
{
  error: Error,  // Error object with message
  data: Object   // Submission data that failed
  webhook: boolean // True when triggered by a webhook step with server endpoint
}
Code language: JavaScript (javascript)
```

**Example:**

```
document.addEventListener('joinchat:submitError', (e) => {
  console.error('Submission failed:', e.detail.error.message);
  console.log('Failed data:', e.detail.data);
});
Code language: JavaScript (javascript)
```

### joinchat:webhookSuccess

Dispatched when a webhook call succeeds.

**File:** `addons/chat-funnels/public/js/joinchat-chat-funnels.js`

**Detail:**

```
{
  response: any,   // Webhook response (parsed JSON or text)
  payload: Object  // Payload sent to webhook
}
Code language: CSS (css)
```

**Example:**

```
document.addEventListener('joinchat:webhookSuccess', (e) => {
  console.log('Webhook called successfully');
  console.log('Response:', e.detail.response);
});
Code language: JavaScript (javascript)
```

### joinchat:webhookError

Dispatched when a webhook call fails.

**File:** `addons/chat-funnels/public/js/joinchat-chat-funnels.js`

**Detail:**

```
{
  error: Error,    // Error object with message
  payload: Object  // Payload that failed to send
}
Code language: JavaScript (javascript)
```

**Example:**

```
document.addEventListener('joinchat:webhookError', (e) => {
  console.error('Webhook failed:', e.detail.error.message);
  console.log('Failed payload:', e.detail.payload);
});
Code language: JavaScript (javascript)
```

### joinchat:qr

Internal event to regenerate QR codes with updated parameters.

> **Internal Use:** This event is primarily for internal communication between Joinchat and Premium addons.

**File:** `addons/chat-funnels/public/js/joinchat-chat-funnels.js`

**Detail:**

```
{
  id: string,      // Phone ID (empty for rebuild with same phone)
  message: string  // Custom message for QR
}
Code language: CSS (css)
```

## Support Agents Events

Events dispatched by the Support Agents addon.

### joinchat:agents

Dispatched when support agents are initialized or status changes.

> **Internal Use:** This event is primarily for internal communication between Joinchat and Premium addons.

**File:** `addons/support-agents/public/js/joinchat-support-agents.js`

**Detail:**

```
{
  agents: Array,  // Array of agent objects with name, phone, role, online status
  status: string  // Overall status: 'online', 'offline', or 'none'
}
Code language: CSS (css)
```

**Example:**

```
document.addEventListener('joinchat:agents', (e) => {
  console.log('Agents status:', e.detail.status);
  console.log('Agents:', e.detail.agents);

  e.detail.agents.forEach(agent => {
    console.log(`${agent.name}: ${agent.online ? 'online' : 'offline'}`);
  });
});
Code language: JavaScript (javascript)
```

### joinchat:expand\_agents

Dispatched when the collapsed agents list is expanded.

**File:** `addons/support-agents/public/js/joinchat-support-agents.js`

**Detail:**

```
{
  agents_count: number,  // Total number of agents
  agents_online: number  // Number of online agents
}
Code language: CSS (css)
```

**Example:**

```
document.addEventListener('joinchat:expand_agents', (e) => {
  console.log(`<span class="javascript">Showing ${e.detail.agents_count} agents`);
  console.log(`<span class="javascript">${e.detail.agents_online} are online`);
});
</span></span>Code language: JavaScript (javascript)
```

## Omnichannel Events

No additional events beyond `joinchat:open` documented in Core Events.

## Media Events

Events related to embedded media like videos.

### joinchat:video

Dispatched when a video is played or paused in the chat.

**File:** `public/js/joinchat-premium-embeds.js`

**Detail:**

```
{
  action: string,  // Video action: 'play' or 'pause'
  service: string, // Video service: 'vimeo' or 'youtube'
  id: string       // Video ID
}
Code language: CSS (css)
```

**Example:**

```
document.addEventListener('joinchat:video', (e) => {
  console.log(`<span class="javascript">Video ${e.detail.action}:`, e.detail.id);
  console.log('Service:', e.detail.service);
});
</span>Code language: JavaScript (javascript)
```

## Event Usage Patterns

### Listening to Multiple Events

```
// Track all funnel interactions
['joinchat:goto', 'joinchat:input', 'joinchat:link'].forEach(eventName => {
  document.addEventListener(eventName, (e) => {
    console.log(`Event: ${eventName}`, e.detail);
    // Send to analytics
  });
});
Code language: JavaScript (javascript)
```

### Triggering Events

```
// Load a specific funnel
document.dispatchEvent(new CustomEvent('joinchat:funnel', {
  detail: {
    funnel: 2,
    start_at: 5,
    reset: false
  }
}));

// Regenerate QR codes with custom message
document.dispatchEvent(new CustomEvent('joinchat:qr', {
  detail: {
    id: '',
    message: 'Custom WhatsApp message'
  }
}));
Code language: JavaScript (javascript)
```

### Canceling Events

`joinchat:open` and `joinchat:event` are cancelable:

```
// Cancel opening WhatsApp
document.addEventListener('joinchat:open', (e) => {
  if (!userHasPermission) {
    e.preventDefault();
    return false;
  }
});

// Cancel analytics events
document.addEventListener('joinchat:event', (e) => {
  if (privacyMode) {
    e.preventDefault();
    return false;
  }
});
Code language: JavaScript (javascript)
```

## Notes

- All events are dispatched on the `document` object
- Event details can be accessed via `event.detail`
- Most events are for listening/tracking purposes
- Internal events (primarily for Core-Premium communication): `joinchat:starting`, `joinchat:bubbles`, `joinchat:funnel`, `joinchat:agents`, `joinchat:qr`
- Events that can be triggered externally (though primarily internal): `joinchat:funnel`, `joinchat:qr`
- Cancelable events: `joinchat:open`, `joinchat:event` (return `false` or call `preventDefault()`)
- `joinchat:start` indicates Joinchat is fully initialized and ready (`joinchat_obj.is_ready === true`)
- Trigger values for `joinchat:show` and `joinchat:open`: `'button'`, `'contact'`, `'auto'`, `'hover'`, `'url'`, `'trigger'`, `'screen'`, `'agent'`, `'unknown'`