@primexperts.co/pulse-agent
v5.8.0
Published
Embeddable Pulse floating chat agent widget.
Maintainers
Readme
@primexperts.co/pulse-agent
Pulse Agent is a browser-only customer support widget for adding Pulse Webchat and optional website error reporting to any public website, SPA, or client-rendered application.
It is designed for teams that want one lightweight install to do two jobs:
- Add a floating Pulse chat launcher to a website.
- Report browser errors and failed API calls back to Pulse when error monitoring is enabled.
The package is framework-agnostic. It works with Angular, React, Vue, static HTML, and SSR frameworks when initialized on the client side.
Quick Start
npm install @primexperts.co/pulse-agent@latestimport { createPulseAgent } from '@primexperts.co/pulse-agent';
const agent = createPulseAgent({
slug: 'your-organization-slug',
appKey: 'app_your_public_application_key',
apiBaseUrl: 'https://pulse.service.primexperts.co.za',
title: 'Support',
requireProfile: true,
visitorProfile: { name: 'Ada Lovelace', email: '[email protected]' },
autoOpen: false,
errorMonitoring: true,
captureUnhandledErrors: true,
captureUnhandledRejections: true,
captureFetchErrors: true,
environment: 'production',
release: 'web-1.0.0'
});
agent.open();Why Teams Use Pulse Agent
Pulse Agent is useful when a business has customer messages arriving through public-facing channels, but the team needs a controlled place to handle them.
Typical use cases:
- A website visitor starts a chat and any available team member can respond from Pulse.
- A support mailbox can be connected so the team manages customer email from a shared workspace instead of one person's inbox.
- Conversation history stays attached to the customer interaction, so the next team member can continue with context.
- Teams can separate customer communication by organization/application using the
slugandappKey. - Website errors can be reported into Pulse so support and operations can see when customers are affected.
The result is a team inbox model: one public channel for customers, multiple internal users for response and follow-up.
Channel Model
| Channel | Current role | What the customer sees | What the team gets in Pulse | | --- | --- | --- | --- | | Webchat | Supported through this package | Website chat launcher | Shared conversation thread, visitor profile, realtime replies, history, transcript action | | Email | Supported by Pulse integrations | Normal support email address | Shared email conversations in Pulse, independent of one person's mailbox | | WhatsApp | Planned/optional depending on deployment | WhatsApp contact path | Intended shared handling model when enabled; do not promise as active unless configured | | Error Monitoring | Supported through this package | No visible customer UI | Browser exceptions and failed request reports tied to the website/application |
Self-Service Setup
Pulse Agent is intended to be usable by any website owner who creates a Pulse workspace and enables Webchat.
Before adding the code snippet, do this in Pulse:
- Create or sign in to your Pulse account.
- Create your organization or workspace.
- Create/select the application or website you want to connect.
- Enable the Webchat integration.
- Copy the generated setup values into your website environment/config.
- Add your website origin, for example
https://www.example.com, to the allowed origins/CORS settings if your Pulse deployment exposes that setting.
Use these values in your widget config:
| Value | Example | Required | How to get it |
| --- | --- | --- | --- |
| Organization slug | acme-support | Yes | Shown in Pulse for your organization/workspace. |
| Application key | app_... | Recommended when available | Copy from your Pulse application/webchat setup. |
| API base URL | https://pulse.service.primexperts.co.za | Yes | Use the API URL shown by your Pulse environment. |
| Website origin | https://www.example.com | Required for production | Add the exact site origin where the widget will run. |
You usually do not need a widget token. Pulse Agent resolves it automatically from your organization slug; when an application key is configured, the agent also sends it for app-aware deployments and reporting context.
If your website already signs the user in, pass the authenticated user profile explicitly through visitorProfile or later via agent.update({ visitorProfile: ... }). The widget does not scrape browser pages, cookies, or DOM state to discover names or email addresses.
Configuration Keys
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| slug | string | Required | Public organization slug used to resolve the active webchat widget. |
| appKey | string | Optional but recommended | Public application key, normally starts with app_. Use this for application-specific setup and error attribution. |
| appSlug | string | Optional | Alternative application identifier when an app key is not available. |
| apiBaseUrl | string | https://pulse.service.primexperts.co.za | Pulse API host only. Do not include /api/... paths. |
| title | string | Organization/app name | Chat panel title. |
| mount | HTMLElement \| string | document.body | Element or selector where the widget root should be mounted. |
| autoOpen | boolean | false | Opens the chat panel immediately after initialization. |
| requireProfile | boolean | true | Requires visitor name/email before first message. |
| visitorProfile | { name: string; email: string } \| null | Optional | Host-supplied signed-in user profile. Prefills the gate and hides it when provided. |
| followUpEmailTo | string | Optional | Destination used by transcript/follow-up email actions. |
| dashboardUrl | string | https://pulse.primexperts.co.za | Dashboard link used in setup/error states. |
| dashboardSetupPath | string | /integrations | Dashboard path linked when setup is incomplete. |
| whatsappUrl | string | Optional | Adds a WhatsApp launcher alongside Pulse Chat. |
| widgetToken | string | Optional | Advanced bypass for resolve flow. Leave unset unless Pulse gives you a specific token. |
| errorMonitoring | boolean | false | Enables browser error reporting. Must be true before any capture happens. |
| captureUnhandledErrors | boolean | true when monitoring is enabled | Captures window.onerror events. |
| captureUnhandledRejections | boolean | true when monitoring is enabled | Captures unhandled promise rejections. |
| captureFetchErrors | boolean | true when monitoring is enabled | Wraps browser fetch to report failed requests and thrown network errors. |
| environment | string | Optional | Environment label such as production, staging, or development. |
| release | string | Optional | Application release/version label for error context. |
Environment Variables
Pulse Agent itself receives JavaScript options. For deployed apps, put values in your platform environment and generate or serve a runtime config file that passes those values to createPulseAgent.
Recommended names:
PULSE_AGENT_SLUG=your-organization-slug
PULSE_AGENT_APP_KEY=app_your_public_application_key
PULSE_AGENT_API_BASE_URL=https://pulse.service.primexperts.co.za
PULSE_AGENT_TITLE=Support
PULSE_AGENT_ENVIRONMENT=production
PULSE_AGENT_RELEASE=web-1.0.0
PULSE_AGENT_ERROR_MONITORING=true
PULSE_AGENT_CAPTURE_UNHANDLED_ERRORS=true
PULSE_AGENT_CAPTURE_UNHANDLED_REJECTIONS=true
PULSE_AGENT_CAPTURE_FETCH_ERRORS=trueOptional names:
[email protected]
PULSE_AGENT_DASHBOARD_URL=https://pulse.primexperts.co.za
PULSE_AGENT_DASHBOARD_SETUP_PATH=/integrations
PULSE_AGENT_AUTO_OPEN=false
PULSE_AGENT_REQUIRE_PROFILE=true
PULSE_AGENT_WHATSAPP_URL=https://api.whatsapp.com/send?phone=27123456789
PULSE_AGENT_WIDGET_TOKEN=Leave PULSE_AGENT_WIDGET_TOKEN unset unless Pulse Support explicitly gives you one. It is not the app_* key.
Deployment Environment Variables
Set the same values in whatever platform you deploy on. The host should provide them as environment variables during build or at runtime, and your app should expose them to the browser through a runtime config file or server-rendered bootstrap.
PULSE_AGENT_SLUG=your-organization-slug
PULSE_AGENT_APP_KEY=app_your_public_application_key
PULSE_AGENT_API_BASE_URL=https://pulse.service.primexperts.co.za
PULSE_AGENT_TITLE=Support
PULSE_AGENT_ENVIRONMENT=production
PULSE_AGENT_ERROR_MONITORING=true
PULSE_AGENT_CAPTURE_UNHANDLED_ERRORS=true
PULSE_AGENT_CAPTURE_UNHANDLED_REJECTIONS=true
PULSE_AGENT_CAPTURE_FETCH_ERRORS=trueIf your app uses a runtime-config.js file, generate that file from environment values at request time, build time, or startup depending on how your host serves assets.
Required Code Structure
Pulse Agent does not require a special framework architecture, but it does need one clear bootstrap point.
Structure your app so createPulseAgent(...) runs:
- once per page/app session;
- only in the browser, never during server-side rendering;
- as early as practical after runtime config is available;
- before the user flows you want error monitoring to observe;
- from a stable root entry point such as
main.ts,App.tsx, a root layout client component,onMounted, or a script loaded after/runtime-config.js.
Do not initialize Pulse Agent inside frequently re-rendered child components, route components that mount repeatedly, button click handlers, or server-only files. If the root component can unmount, keep the returned handle and call agent.destroy() during cleanup.
For error monitoring, timing matters: errors that happen before createPulseAgent(...) runs cannot be captured by Pulse Agent. If you want broad coverage, load runtime config first and initialize Pulse Agent before bootstrapping the rest of the application where your framework allows it.
Runtime Config Pattern
A common production-safe pattern is to load /runtime-config.js before your app bundle:
<script src="/runtime-config.js"></script>Example generated file:
window.__APP_RUNTIME_CONFIG__ = {
pulseAgent: {
slug: 'your-organization-slug',
appKey: 'app_your_public_application_key',
apiBaseUrl: 'https://pulse.service.primexperts.co.za',
title: 'Support',
errorMonitoring: true,
captureUnhandledErrors: true,
captureUnhandledRejections: true,
captureFetchErrors: true,
environment: 'production'
}
};Then initialize in your app entry point:
import { createPulseAgent, type PulseAgentOptions } from '@primexperts.co/pulse-agent';
declare global {
interface Window {
__APP_RUNTIME_CONFIG__?: {
pulseAgent?: Partial<PulseAgentOptions>;
};
}
}
const config = window.__APP_RUNTIME_CONFIG__?.pulseAgent;
if (config?.slug) {
createPulseAgent({
...config,
slug: config.slug
});
}Browser/CDN Usage
Use this when you cannot install npm packages:
<script src="https://unpkg.com/@primexperts.co/pulse-agent@latest/dist/browser/pulse-agent.global.js"></script>
<script>
window.PulseAgent.createPulseAgent({
slug: 'your-organization-slug',
appKey: 'app_your_public_application_key',
apiBaseUrl: 'https://pulse.service.primexperts.co.za',
title: 'Support',
errorMonitoring: true
});
</script>Framework Examples
Angular
Initialize in main.ts or a browser-only root component. For SSR, guard against server execution.
import { bootstrapApplication } from '@angular/platform-browser';
import { createPulseAgent } from '@primexperts.co/pulse-agent';
import { AppComponent } from './app/app.component';
if (typeof window !== 'undefined') {
createPulseAgent({
slug: 'your-organization-slug',
appKey: 'app_your_public_application_key',
apiBaseUrl: 'https://pulse.service.primexperts.co.za',
errorMonitoring: true
});
}
bootstrapApplication(AppComponent);React
import { useEffect } from 'react';
import { createPulseAgent } from '@primexperts.co/pulse-agent';
export function PulseAgentBootstrap() {
useEffect(() => {
const agent = createPulseAgent({
slug: 'your-organization-slug',
appKey: 'app_your_public_application_key',
apiBaseUrl: 'https://pulse.service.primexperts.co.za',
errorMonitoring: true
});
return () => agent.destroy();
}, []);
return null;
}Vue
import { onBeforeUnmount, onMounted } from 'vue';
import { createPulseAgent, type PulseAgentHandle } from '@primexperts.co/pulse-agent';
let agent: PulseAgentHandle | null = null;
onMounted(() => {
agent = createPulseAgent({
slug: 'your-organization-slug',
appKey: 'app_your_public_application_key',
apiBaseUrl: 'https://pulse.service.primexperts.co.za',
errorMonitoring: true
});
});
onBeforeUnmount(() => agent?.destroy());How Widget Resolution Works
At startup or first send, Pulse Agent calls:
GET /api/pulse/public/webchat/resolve?slug=<slug>[&appKey=<app_...>]Pulse returns the active widget configuration, including an internal widgetToken. The widget then uses that token for chat, history, streaming, transcript email, and error reporting.
Do not confuse these values:
| Name | Format | Purpose | User action |
| --- | --- | --- | --- |
| appKey | app_... | Public application key from Pulse Dashboard | Put in config/env. |
| widgetToken | Token generated by Pulse | Internal public webchat token used by endpoints | Usually leave unset. |
| slug | human-readable slug | Identifies organization | Put in config/env. |
Network Access and Security Scanners
Security scanners such as Socket may flag this package for network access. That is expected and intentional.
Pulse Agent is a browser widget, so it uses standard browser networking APIs to provide its features:
fetchresolves the active widget configuration.fetchsends visitor messages to Pulse.fetchloads conversation history and sends transcript/error-report requests.EventSourcekeeps the chat connected for realtime replies.- Optional
fetchwrapping reports failed website requests only whenerrorMonitoringandcaptureFetchErrorsare enabled.
The package does not run install scripts, does not start background processes, does not open arbitrary sockets, and does not use Node filesystem or shell APIs at runtime. Network calls are made from the visitor's browser after the website initializes createPulseAgent(...), and they target the configured apiBaseUrl plus optional WhatsApp links when configured.
Error Monitoring
Error monitoring is opt-in. Installing the package does not capture anything until errorMonitoring: true is passed to createPulseAgent.
When enabled, Pulse Agent can capture:
- Unhandled JavaScript errors from
window.onerror. - Unhandled promise rejections from
window.onunhandledrejection. - Failed
fetchresponses, including HTTP statuses from failed API calls. - Network errors thrown by
fetch. - Manual error reports through
agent.captureException(...).
Manual capture example:
try {
await saveOrder();
} catch (error) {
agent.captureException(error, {
source: 'checkout.saveOrder',
errorType: 'checkout-error',
endpoint: '/api/orders',
pageUrl: window.location.href
});
throw error;
}Report count example:
const reportsLastSevenDays = agent.getErrorReportCount(7);What Error Monitoring Does Not Do
Pulse Agent does not:
- Catch errors before the widget is initialized.
- Catch server-side errors unless those errors are exposed to the browser as failed requests.
- Replace backend logging, APM, or infrastructure monitoring.
- Read private app state, passwords, tokens, or request bodies intentionally.
- Automatically fix errors.
- Capture errors if
errorMonitoringis missing orfalse.
Public Backend Endpoints
The widget expects these Pulse endpoints:
GET /api/pulse/public/webchat/resolve?slug=<slug>[&appKey=<appKey>]
POST /api/pulse/public/webchat/{widgetToken}/message
GET /api/pulse/public/webchat/{widgetToken}/messages?conversationId=<id>
POST /api/pulse/public/webchat/{widgetToken}/transcript-email?conversationId=<id>
GET /api/pulse/public/webchat/{widgetToken}/stream?conversationId=<id>
POST /api/pulse/public/webchat/{widgetToken}/errorsAdmin setup endpoints are separate and should remain authenticated.
Benefits
- One package for webchat and optional browser error monitoring.
- Framework-agnostic browser integration.
- Works with npm or a script tag.
- Supports runtime configuration for static hosting, server-rendered apps, containerized apps, and other multi-environment deployments.
- Uses the organization
slug, plusappKeywhen available, so users do not need to handle internal widget tokens. - Supports visitor profile capture, history loading, transcript email requests, SSE replies, WhatsApp launcher/contact path where configured, manual open/close, and manual exception reporting.
- Supports operational workflows verified in the Pulse source: assignment, status/priority updates, internal notes, follow-ups, customer profiles, tags, notifications, activity logs, exports, and dashboard KPIs.
- Supports role-based team operation: admins manage setup and assignment, while agents work assigned conversations.
Limitations
- Browser-only. Initialize after mount/hydration in SSR frameworks.
- Requires the website origin to be allowed by Pulse CORS configuration.
- Requires an active Pulse Webchat integration for the organization/application.
- Requires
fetchandEventSourcesupport for full behavior. - SSE can be affected by proxies, corporate networks, browser extensions, and load balancer timeouts.
- Error monitoring starts only after initialization and only when enabled.
fetchmonitoring coverswindow.fetch; it does not automatically wrap Axios internals unless Axios usesfetchin that environment.widgetTokenis an advanced bypass and should not be used unless Pulse explicitly provides it.
Production Checklist
Before publishing a site with Pulse Agent:
- Confirm Pulse Webchat is enabled in the Pulse Dashboard.
- Confirm you have the correct
slug. - Confirm you have the correct
appKeybeginning withapp_. - Confirm
apiBaseUrlishttps://pulse.service.primexperts.co.za. - Confirm production origin is allowed by Pulse CORS configuration.
- Confirm
runtime-config.jsor app config is generated from deployment env values. - Confirm
errorMonitoringistrueif you expect browser error reporting. - Open the site and check browser network calls for
resolve,message,stream, anderrorswhen applicable. - Send a test chat message.
- Trigger a test error in a non-production or controlled environment and confirm it appears in Pulse.
Handle API
createPulseAgent(options) returns:
| Method | Description |
| --- | --- |
| open() | Opens the chat panel. |
| close() | Closes the chat panel. |
| destroy() | Removes DOM, listeners, and fetch wrapping installed by this instance. |
| resetConversation() | Starts a fresh local conversation. |
| update(partialOptions) | Updates runtime options such as title, WhatsApp URL, or widget token. |
| captureException(error, context) | Manually reports an error when monitoring is enabled. |
| getErrorReportCount(days) | Returns locally remembered successful error report count for the last N days. |
Troubleshooting
The widget does not appear
Check that initialization runs in the browser, the slug is present, and the mount selector exists.
Failed to resolve widget keys (401/403)
The public resolve endpoint is protected or the key is not accepted. Confirm the Pulse public webchat routes are accessible and the appKey is correct.
Failed to resolve widget keys (404)
The slug is wrong, Webchat is not enabled, or the selected organization/application has no active widget.
CORS error in the browser console
The website origin is missing from Pulse CORS configuration. Add the exact origin, including protocol and port.
Chat sends but replies do not stream
Check that EventSource is available and that proxies/load balancers allow long-lived SSE connections.
Errors are not captured
Confirm all of the following:
errorMonitoring: trueis present in runtime config.- The widget successfully resolves a widget token.
- The error happens after
createPulseAgent(...)runs. - The browser can post to
/api/pulse/public/webchat/{widgetToken}/errors.
