@sippet-ai/operator-widget
v0.0.17
Published
Sippet AI's operator widget to enable telephony calling features in any web application.
Maintainers
Readme
Sippet AI Operator Widget
A web component (with React wrappers) for embedding Sippet AI operator telephony controls.
Install
npm install @sippet-ai/operator-widgetAuth flow
- Ensure your operator exists in Sippet's 'Team members' section in the settings
- Operator logs in to your frontend.
- Your frontend calls your backend (never call Sippet mint endpoint directly from browser).
- Your backend validates the operator session and extracts the user's email.
- Your backend mints the operator token using one of these methods:
- SDK server RPC call (recommended):
issueOperatorAccessTokenviacreateServerClientfrom@sippet-ai/sdk-js/server - REST endpoint:
POST /api/operator/access
- SDK server RPC call (recommended):
- Sippet finds the operator by email in the workspace tied to that secret key and returns an access token.
- Your backend returns that token to frontend.
- Frontend passes token to widget via
access-tokenorgetAccessToken.
Minting options on your backend
Option A: SDK server RPC call (recommended)
import { createServerClient } from '@sippet-ai/sdk-js/server';
const sippet = createServerClient({
apiKey: process.env.SIPPET_SECRET_API_KEY!,
});
const result = await sippet.issueOperatorAccessToken({
input: { operatorEmail: operator.email },
});
if (!result.success) {
throw new Error(result.errors.map(error => error.message).join(', '));
}
return result.data.token;Option B: Raw REST endpoint
const response = await fetch('https://api.sippet.ai/api/operator/access', {
method: 'POST',
headers: {
'content-type': 'application/json',
'x-api-key': process.env.SIPPET_SECRET_API_KEY!,
},
body: JSON.stringify({ operator_email: operator.email }),
});
if (!response.ok) throw new Error('Failed to mint operator access token');
const body = await response.json();
return body.token;Important requirement: operator email must exist in Sippet
The operator_email must map to an existing invited/created user in your Sippet workspace (team members).
If the email is not present in that workspace, token minting fails.
Quick start (Web Component, token auth)
<script type="module">
import '@sippet-ai/operator-widget';
</script>
<sippetai-voip-widget
access-token="YOUR_OPERATOR_ACCESS_TOKEN"
api-origin="https://api.sippet.ai"
></sippetai-voip-widget>React usage (token auth)
import { SippetAIVoipWidget } from '@sippet-ai/operator-widget/react';
export function SupportWidget() {
return (
<SippetAIVoipWidget
accessToken="YOUR_OPERATOR_ACCESS_TOKEN"
apiOrigin="https://api.sippet.ai"
/>
);
}Shared SDK + widget state
Initialize one SDK client with initClient(...) and pass that same object to
the widget as a property. This keeps SIP session/call state in one place, so
SDK actions (for example joining a call) are reflected in the widget UI.
import { SippetAIVoipWidget } from '@sippet-ai/operator-widget/react';
import { initClient } from '@sippet-ai/sdk-js/client';
const sdkClient = initClient({
baseUrl: 'https://api.sippet.ai',
});
export function SupportWidget({ isWidgetOpen }: { isWidgetOpen: boolean }) {
return (
<SippetAIVoipWidget
client={sdkClient}
openWidget={isWidgetOpen}
getAccessToken={async () => {
const response = await fetch('/api/your-backend/operator-token', {
method: 'POST',
});
if (!response.ok) throw new Error('Failed to mint operator token');
const body = await response.json();
return body.token;
}}
apiOrigin="https://api.sippet.ai"
/>
);
}Token rotation with backend endpoint
import { SippetAIVoipWidget } from '@sippet-ai/operator-widget/react';
export function SupportWidget() {
return (
<SippetAIVoipWidget
apiOrigin="https://api.sippet.ai"
getAccessToken={async () => {
const response = await fetch('/api/your-backend/operator-token', {
method: 'POST',
});
if (!response.ok) throw new Error('Failed to mint operator token');
const body = await response.json();
return body.token;
}}
/>
);
}Configuration
access-token/accessToken: operator bearer token.getAccessToken(property only): async token resolver.api-origin/apiOrigin: API origin override.client(property only): shared SDK client instance from@sippet-ai/sdk-js/client.open-widget/openWidget: controls whether the panel is open.
Helper API
import { sippet } from '@sippet-ai/operator-widget';
import { initClient } from '@sippet-ai/sdk-js/client';
const sdkClient = initClient({
baseUrl: 'https://api.sippet.ai',
});
sippet.setClient(sdkClient);
sippet.setGetAccessToken(async () => {
const response = await fetch('/api/your-backend/operator-token', {
method: 'POST',
});
const body = await response.json();
return body.token;
});