Web SDKs
Angular
@primoia/vocall-angular -- Services, NgZone, RxJS
Angular SDK
The Angular SDK provides a root-level service with RxJS observables and synchronous getters for integrating Vocall into Angular 18+ applications.
Installation
npm install @primoia/vocall-angular
Peer dependencies: @angular/common ^18 || ^19, rxjs ^7.8
VocallService
VocallService is provided in root and can be injected into any component or service.
import { VocallService } from '@primoia/vocall-angular';
constructor(private vocall: VocallService) {}
Methods
| Method | Signature | Description |
|---|---|---|
| connect | connect(url: string, token: string, visitorId?: string): void | Opens a WebSocket connection to the Vocall engine. |
| disconnect | disconnect(): void | Closes the active connection. |
| sendText | sendText(text: string): void | Sends a text message to the engine. |
| registerField | registerField(screenId: string, fieldId: string, entry: FieldEntry): void | Registers a DOM element as a bindable field. |
| registerAction | registerAction(screenId: string, actionId: string, callback: () => void): void | Registers a callback for an action trigger. |
Observables
| Observable | Type | Description |
|---|---|---|
| status$ | Observable<VocallStatus> | Current engine status. |
| connected$ | Observable<boolean> | Whether the WebSocket is connected. |
| messages$ | Observable<Message[]> | Chat message history. |
| sessionId$ | Observable<string \| null> | Active session identifier. |
| rawMessage$ | Observable<any> | Raw WebSocket frames for advanced use. |
Synchronous Getters
For template guards or imperative code you can read the latest value directly.
| Getter | Type |
|---|---|
| status | VocallStatus |
| connected | boolean |
| messages | Message[] |
| sessionId | string \| null |
Navigation and UI Callbacks
Assign handlers on the service instance to react to engine-driven UI actions.
| Callback | Signature |
|---|---|
| onNavigate | (path: string) => void |
| onToast | (message: string, type?: string) => void |
| onConfirm | (message: string) => Promise<boolean> |
| onOpenModal | (modalId: string) => void |
| onCloseModal | (modalId: string) => void |
FieldEntry
The object passed to registerField describes how the engine reads and writes a form element.
interface FieldEntry {
element: HTMLElement;
setValue: (value: string) => void;
getValue: () => string;
}
VocallStatus
enum VocallStatus {
disconnected = 'disconnected',
idle = 'idle',
listening = 'listening',
recording = 'recording',
thinking = 'thinking',
speaking = 'speaking',
executing = 'executing',
}
Full Example
import { Component, ViewChild, ElementRef, OnInit, OnDestroy } from '@angular/core';
import { VocallService, VocallStatus } from '@primoia/vocall-angular';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-invoice',
standalone: true,
template: `
<input #nameInput placeholder="Client name" />
<p>Status: {{ vocall.status }}</p>
<button (click)="vocall.sendText('Fill the client name')">Ask</button>
`,
})
export class InvoiceComponent implements OnInit, OnDestroy {
@ViewChild('nameInput', { static: true }) nameInput!: ElementRef<HTMLInputElement>;
private sub = new Subscription();
constructor(public vocall: VocallService) {}
ngOnInit(): void {
this.vocall.connect('wss://engine.example.com/connect', 'my-token');
this.vocall.registerField('invoice', 'clientName', {
element: this.nameInput.nativeElement,
setValue: (v) => (this.nameInput.nativeElement.value = v),
getValue: () => this.nameInput.nativeElement.value,
});
this.vocall.onNavigate = (path) => {
// integrate with Angular Router
console.log('Navigate to', path);
};
this.sub.add(
this.vocall.status$.subscribe((s) => {
if (s === VocallStatus.executing) {
console.log('Engine is executing commands...');
}
})
);
}
ngOnDestroy(): void {
this.sub.unsubscribe();
this.vocall.disconnect();
}
}
Manifest Structure
The field and action identifiers used in registerField and registerAction must match entries defined in your application manifest. See the Manifest Reference for the full schema.