Skip to content

Commit 9b1f66e

Browse files
authored
Merge pull request #4 from sipgate-io/dev
merge: dev into master
2 parents 16ed943 + 7958b17 commit 9b1f66e

File tree

23 files changed

+897
-558
lines changed

23 files changed

+897
-558
lines changed

README.md

Lines changed: 263 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,247 @@ async function setLog(value: boolean): Promise<void>;
319319
The `setLog` function toggles, the function to display all incoming and outgoing events, which have been sent to your `Incoming` and `Outgoing` Url.
320320
These parameters can be set using these functions: `setIncomingUrl` and `setOutgoingUrl`.
321321

322+
### Webhooks (PUSH-API)
323+
324+
The webhook module provides the following features:
325+
326+
- subscribing to **newCall** events
327+
- replying to **newCall** events with XML
328+
- subscribing to **answer** events
329+
- subscribing to **data** events
330+
- subscribing to **hangup** events
331+
332+
**Please note:** The feature is only available in node.js environments and not available in browser environments
333+
334+
#### Structure
335+
336+
```typescript
337+
interface WebhookModule {
338+
createServer: (port: number) => Promise<WebhookServer>;
339+
}
340+
341+
type HandlerCallback<T, U> = (event: T) => U;
342+
343+
interface WebhookServer {
344+
onNewCall: (fn: HandlerCallback<NewCallEvent, string>) => void;
345+
onAnswer: (fn: HandlerCallback<AnswerEvent, void>) => void;
346+
onHangup: (fn: HandlerCallback<HangupEvent, void>) => void;
347+
onData: (fn: HandlerCallback<DataEvent, void>) => void;
348+
stop: () => void;
349+
}
350+
```
351+
352+
#### Creating the webhook server
353+
354+
By passing a `port` to the `createServer` method, you receive a `Promise<WebhookServer>`.
355+
After the server has been instantiated, you can subscribe to various `Events` (`NewCallEvent`,`AnswerEvent`,`HangupEvent`,`DataEvent`) which are described below.
356+
357+
#### Subscribing to _newCall_ events
358+
359+
After creating the server, you can subscribe to newCall events by passing a callback function to the `.onNewCall` method. This callback function will receive a `NewCallEvent` (described below) when called and expects a valid XML response to be returned.
360+
To receive any further `Events`, you can subscribe to them with the following XML:
361+
**Keep in mind:** you have to replace `https://www.sipgate.de/` with your server URL
362+
363+
```xml
364+
<?xml version="1.0" encoding="UTF-8"?>
365+
<Response onAnswer="https://www.sipgate.de/" onHangup="https://www.sipgate.de/">
366+
</Response>
367+
```
368+
369+
```typescript
370+
enum Direction {
371+
IN = 'in',
372+
OUT = 'out',
373+
}
374+
375+
interface NewCallEvent {
376+
event: EventType;
377+
callId: string;
378+
direction: Direction;
379+
from: string;
380+
to: string;
381+
xcid: string;
382+
event: EventType.NEW_CALL;
383+
originalCallId: string;
384+
user: string[];
385+
userId: string[];
386+
fullUserId: string[];
387+
}
388+
```
389+
390+
#### Replying to _newCall_ events with valid XML
391+
392+
You can return different `XML-Responses` in your callback, which will be passed to the PUSH-API:
393+
394+
##### Redirecting a call:
395+
396+
You can redirect the call to a specific phone number using the following XML:
397+
398+
```xml
399+
<?xml version="1.0" encoding="UTF-8"?>
400+
<Response>
401+
<Dial>
402+
<Number>4915799912345</Number>
403+
</Dial>
404+
</Response>
405+
```
406+
407+
##### Sending a call to the voicemail:
408+
409+
Redirecting a call to the voicemail can be achieved by using the following XML snippet:
410+
411+
```xml
412+
<?xml version="1.0" encoding="UTF-8"?>
413+
<Response>
414+
<Dial>
415+
<Voicemail />
416+
</Dial>
417+
</Response>
418+
```
419+
420+
##### Supressing your phone number and redirecting the call
421+
422+
The snippet mentioned below supresses your phone number and redirects you to a different number:
423+
424+
```xml
425+
<?xml version="1.0" encoding="UTF-8"?>
426+
<Response>
427+
<Dial anonymous="true">
428+
<Number>4915799912345</Number>
429+
</Dial>
430+
</Response>
431+
```
432+
433+
##### Set custom callerId and redirect the call
434+
435+
The custom `callerId` can be set to any validated number in your sipgate account:
436+
437+
```xml
438+
<?xml version="1.0" encoding="UTF-8"?>
439+
<Response>
440+
<Dial callerId="492111234567">
441+
<Number>4915799912345</Number>
442+
</Dial>
443+
</Response>
444+
```
445+
446+
##### Playing a sound file
447+
448+
**Please note:** Currently the sound file needs to be a mono 16bit PCM WAV file with a sampling rate of 8kHz. You can use conversion tools like the open source audio editor Audacity to convert any sound file to the correct format.
449+
450+
```xml
451+
<?xml version="1.0" encoding="UTF-8"?>
452+
<Response>
453+
<Play>
454+
<Url>http://example.com/example.wav</Url>
455+
</Play>
456+
</Response>
457+
```
458+
459+
##### Gathering DTMF sounds
460+
461+
**Please note:** If you want to gather DTMF sounds, no future `onAnswer` and `onHangup` events will be pushed for the specific call.
462+
463+
```xml
464+
<?xml version="1.0" encoding="UTF-8"?>
465+
<Response>
466+
<Gather onData="http://localhost:3000/dtmf" maxDigits="3" timeout="10000">
467+
<Play>
468+
<Url>https://example.com/example.wav</Url>
469+
</Play>
470+
</Gather>
471+
</Response>
472+
```
473+
474+
##### Rejecting a call
475+
476+
```xml
477+
<?xml version="1.0" encoding="UTF-8"?>
478+
<Response>
479+
<Reject />
480+
</Response>
481+
```
482+
483+
##### Rejecting a call like you are busy
484+
485+
```xml
486+
<?xml version="1.0" encoding="UTF-8"?>
487+
<Response>
488+
<Reject reason="busy"/>
489+
</Response>
490+
```
491+
492+
##### Hangup calls
493+
494+
```xml
495+
<?xml version="1.0" encoding="UTF-8"?>
496+
<Response>
497+
<Hangup />
498+
</Response>
499+
```
500+
501+
#### Subscribing to _onAnswer_ events
502+
503+
After creating the server, you can subscribe to onAnswer events by passing a callback function to the `.onAnswer` method. This callback function will receive a `AnswerEvent` (described below) when called and expects nothing to be returned.
504+
To receive this event you have to subscribe to them with the XML mentioned in [Subscribing to **newCall** Events](#subscribing-to-newcall-events)
505+
506+
```typescript
507+
interface AnswerEvent {
508+
callId: string;
509+
direction: Direction;
510+
from: string;
511+
to: string;
512+
xcid: string;
513+
event: EventType.ANSWER;
514+
user: string;
515+
userId: string;
516+
fullUserId: string;
517+
answeringNumber: string;
518+
diversion?: string;
519+
}
520+
```
521+
522+
#### Subscribing to _data_ events
523+
524+
After creating the server, you can subscribe to onData events by passing a callback function to the `.onData` method. This callback function will receive a `DataEvent` (described below) when called and expects nothing to be returned.
525+
To receive this event you have to subscribe to them with the XML mentioned in [Subscribing to **newCall** Events](#subscribing-to-newcall-events)
526+
527+
```typescript
528+
interface DataEvent {
529+
callId: string;
530+
event: EventType.DATA;
531+
dtmf: string;
532+
}
533+
```
534+
535+
#### Subscribing to _hangup_ events
536+
537+
After creating the server, you can subscribe to onHangup events by passing a callback function to the `.onHangup` method. This callback function will receive a `HangupEvent` (described below) when called and expects nothing to be returned.
538+
To receive this event you have to subscribe to them with the XML mentioned in [Subscribing to **newCall** Events](#subscribing-to-newcall-events)
539+
540+
```typescript
541+
enum HangupCause {
542+
NORMAL_CLEARING = 'normalClearing',
543+
BUSY = 'busy',
544+
CANCEL = 'cancel',
545+
NO_ANSWER = 'noAnswer',
546+
CONGESTION = 'congestion',
547+
NOT_FOUND = 'notFound',
548+
FORWARDED = 'forwarded',
549+
}
550+
551+
interface HangupEvent {
552+
callId: string;
553+
direction: Direction;
554+
from: string;
555+
to: string;
556+
xcid: string;
557+
event: EventType.HANGUP;
558+
cause: HangupCause;
559+
answeringNumber: string;
560+
}
561+
```
562+
322563
### Contacts
323564

324565
The contacts module provides the following functions:
@@ -337,9 +578,10 @@ interface ContactsModule {
337578
import: (contact: ContactImport, scope: Scope) => Promise<void>;
338579
importFromCsvString: (csvContent: string) => Promise<void>;
339580
importVCardString: (vcardContent: string, scope: Scope) => Promise<void>;
340-
exportAsCsv: (scope: ExportScope) => Promise<string>;
581+
exportAsCsv: (scope: ExportScope, delimiter?: string) => Promise<string>;
341582
exportAsVCards: (scope: ExportScope) => Promise<string[]>;
342583
exportAsSingleVCard: (scope: ExportScope) => Promise<string>;
584+
exportAsObjects: (scope: ExportScope) => Promise<ContactRequest[]>;
343585
}
344586
```
345587

@@ -377,7 +619,8 @@ It takes a valid VCard 4.0 string, containing at least the following fields:
377619

378620
#### The `exportAsCsv` method:
379621

380-
It returns a csv strings containing all contacts for the given scope
622+
It returns a csv strings containing all contacts for the given scope.
623+
You can also add a specific delimiter for the csv format.
381624

382625
#### The `exportAsVCards` method:
383626

@@ -387,6 +630,23 @@ It returns mulitple vCard-strings containing all contacts for the given scope
387630

388631
It returns a vCard-address-book containing all contacts for the given scope
389632

633+
#### The `exportAsObjects` method:
634+
635+
It returns a list of contacts for the given scope as described in the following interface.
636+
637+
```typescript
638+
interface ContactRequest {
639+
id: string;
640+
name: string;
641+
picture: string;
642+
emails: { email: string; type: string[] }[];
643+
numbers: { number: string; type: string[] }[];
644+
addresses: Address[];
645+
organization: string[][];
646+
scope: Scope;
647+
}
648+
```
649+
390650
#### Scopes
391651

392652
The `PRIVATE` Scope contains all contacts created by yourself and not shared with other people.
@@ -401,9 +661,7 @@ You can only save **one** address and **one** number using the Format.
401661

402662
## Examples
403663

404-
For some examples on how to use the library, please refer to the [examples folder](./examples).
405-
406-
[npx](https://www.npmjs.com/package/npx) can be used to run the code examples:
664+
For some examples on how to use the library, please refer to this repository: [sipgateio-node-examples](https://github.com/sipgate-io/sipgateio-node-examples/)
407665

408666
```
409667
npx ts-node some_example.ts

examples/call/call.ts

Lines changed: 0 additions & 23 deletions
This file was deleted.

examples/client/client.ts

Lines changed: 0 additions & 24 deletions
This file was deleted.

examples/contacts/contacts.csv

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)