@thisispamela/react
v1.1.4
Published
React components for Pamela Enterprise Voice API integration
Readme
@thisispamela/react
React component library for easy integration of Pamela Voice API into your React applications.
Installation
npm install @thisispamela/react @thisispamela/sdkQuick Start
1. Wrap your app with PamelaProvider
import { PamelaProvider } from '@thisispamela/react';
function App() {
return (
<PamelaProvider
config={{
apiKey: 'pk_live_your_api_key_here',
baseUrl: 'https://api.thisispamela.com', // Optional
}}
>
<YourApp />
</PamelaProvider>
);
}2. Use the components
import { CallButton, CallStatus } from '@thisispamela/react';
function MyComponent() {
const [callId, setCallId] = useState<string | null>(null);
return (
<div>
<CallButton
to="+1234567890"
task="Schedule a meeting for next week"
max_duration_seconds={299}
voice="female"
agent_name="Pamela"
caller_name="John from Acme"
onCallStart={(id) => setCallId(id)}
onCallComplete={(call) => console.log('Call completed:', call)}
>
Make Call
</CallButton>
{callId && (
<CallStatus
callId={callId}
showTranscript={true}
/>
)}
</div>
);
}Getting API Keys
Obtaining Your API Key
API subscription required for API access.
API keys are created and managed through the Pamela Partner Portal or via the Partner API:
- Sign up for an API subscription
- Create an API key via one of these methods:
- Developer portal at developer.thisispamela.com: Log in and navigate to the API settings panel
- Partner API:
POST /api/b2b/v1/partner/api-keys
- Save your API key immediately - the full key is only returned once during creation
- Use the key prefix (
pk_live_) to identify keys in your account
Components
CallButton
A button component that initiates a call when clicked.
<CallButton
to="+1234567890"
task="Schedule a meeting"
country="US"
locale="en-US"
instructions="Be professional and concise"
max_duration_seconds={299}
voice="female"
agent_name="Pamela"
caller_name="John from Acme"
metadata={{ customer_id: "12345" }}
variant="primary"
size="md"
pollInterval={2000}
pollTimeout={300000}
onCallStart={(callId) => console.log('Call started:', callId)}
onCallComplete={(call) => console.log('Call completed:', call)}
onError={(error) => console.error('Error:', error)}
disabled={false}
className="my-custom-class"
>
Make Call
</CallButton>Props:
to(required): Phone number in E.164 formattask(required): Task description for the callcountry: ISO country code (optional)locale: Locale string (optional, e.g., "en-US")instructions: Additional instructions (optional)max_duration_seconds: Maximum call duration in seconds (optional)voice: Voice preference"male" | "female" | "auto"(optional)agent_name: Agent name override (optional)caller_name: Name of who the agent is calling on behalf of (optional)metadata: Custom metadata object (optional)variant: Button style -"primary"|"secondary"|"danger"(default:"primary")size: Button size -"sm"|"md"|"lg"(default:"md")pollInterval: Status polling interval in ms (default: 2000)pollTimeout: Maximum polling duration in ms (default: 300000 = 5 min)onCallStart: Callback when call starts (optional)onCallComplete: Callback when call completes (optional)onError: Error callback (optional)disabled: Disable button (optional)className: Custom CSS class (optional)children: Button content (optional, defaults to "Call Now")
CallStatus
Displays the current status of a call with optional transcript and summary.
<CallStatus
callId="call_123"
pollInterval={5000}
onStatusChange={(status) => console.log('Status:', status)}
showTranscript={true}
showSummary={true}
compact={false}
className="my-custom-class"
/>Props:
callId(required): Call ID to monitorpollInterval: Polling interval in milliseconds (default: 5000)onStatusChange: Callback when status changes (optional)showTranscript: Show transcript (default: true)showSummary: Show call summary when available (default: true)compact: Use compact layout (default: false)className: Custom CSS class (optional)
TranscriptViewer
Displays a call transcript in a readable format with auto-scroll support.
<TranscriptViewer
transcript={[
{
speaker: "pamela",
text: "Hello, this is Pamela...",
timestamp: "2024-01-01T00:00:02Z"
},
{
speaker: "user",
text: "Hi Pamela!",
timestamp: "2024-01-01T00:00:05Z"
}
]}
maxHeight={400}
autoScroll={true}
className="my-custom-class"
/>Props:
transcript(required): Array of transcript entriesmaxHeight: Maximum container height (default: 400, accepts number or CSS string)autoScroll: Auto-scroll to latest message (default: true)className: Custom CSS class (optional)
VoiceOrb
Animated voice indicator orb with idle and active states. Matches the Pamela app signature visual.
import { VoiceOrb } from '@thisispamela/react';
// Idle state (breathing animation)
<VoiceOrb isActive={false} size="large" />
// Active state (pulsing animation)
<VoiceOrb isActive={true} size="medium" />Props:
isActive: Whether the orb is in active state (default: false)size: Orb size -"small"|"medium"|"large"(default:"large")className: Custom CSS class (optional)
Size CSS Variables: You can customize sizes via CSS variables:
:root {
--pamela-orb-size-small: 96px;
--pamela-orb-size-medium: 128px;
--pamela-orb-size-large: 192px;
}Features:
- Multi-layer breathing effect (idle mode)
- Pulsing animation with ripples (active mode)
- Floating/levitation effect
- Gradient rotation
- Shimmer highlights
CallHistory
Displays a list of previous calls (requires API endpoint).
<CallHistory
limit={10}
onCallSelect={(callId) => console.log('Selected:', callId)}
className="my-custom-class"
/>Props:
limit: Maximum number of calls to display (default: 10)onCallSelect: Callback when a call is selected (optional)className: Custom CSS class (optional)
Hooks
usePamela
Access the Pamela client directly for custom integrations.
import { usePamela } from '@thisispamela/react';
function MyComponent() {
const { client } = usePamela();
const handleCustomCall = async () => {
const call = await client.createCall({
to: '+1234567890',
task: 'Custom task',
});
console.log('Call created:', call);
};
return <button onClick={handleCustomCall}>Custom Call</button>;
}Styling
Components use Pamela's design system by default, matching the B2C UI:
- Colors: Orange gradient buttons (#FA931C → #fd8b74), beige borders (#e7ab84)
- 3-Color Call Status: Yellow (ringing), Green (in progress), Green with checkmark (completed)
- Message Bubbles: Orange (user), White with beige border (Pamela), Blue (call recipient)
- Fonts: Poppins, Inter
- Dark Mode: Automatic support
You can override styles with CSS classes:
.pamela-call-button {
/* Override button styles */
background: linear-gradient(to right, #your-color, #your-color);
}
.pamela-call-status {
/* Override status container */
}
.pamela-transcript-viewer {
/* Override transcript container */
}Or use the className prop on any component to add your own classes.
Examples
Complete Integration Example
import React, { useState } from 'react';
import { PamelaProvider, CallButton, CallStatus, TranscriptViewer } from '@thisispamela/react';
function App() {
return (
<PamelaProvider
config={{
apiKey: process.env.REACT_APP_PAMELA_API_KEY!,
}}
>
<CallExample />
</PamelaProvider>
);
}
function CallExample() {
const [callId, setCallId] = useState<string | null>(null);
const [callData, setCallData] = useState<any>(null);
return (
<div>
<h1>Make a Call</h1>
<CallButton
to="+1234567890"
task="Schedule a meeting for next week"
onCallStart={(id) => {
setCallId(id);
console.log('Call started:', id);
}}
onCallComplete={(call) => {
setCallData(call);
console.log('Call completed:', call);
}}
onError={(error) => {
console.error('Call error:', error);
}}
>
Call Now
</CallButton>
{callId && (
<div style={{ marginTop: '24px' }}>
<CallStatus
callId={callId}
onStatusChange={(status) => {
if (status.status === 'completed') {
setCallData(status);
}
}}
/>
</div>
)}
{callData && callData.transcript && (
<div style={{ marginTop: '24px' }}>
<TranscriptViewer transcript={callData.transcript} />
</div>
)}
</div>
);
}TypeScript Support
Full TypeScript support is included. All components and hooks are fully typed.
License
MIT
