@vogent/vogent-web-client 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VogentCall.ts +160 -0
- package/__generated__/gql.ts +63 -0
- package/__generated__/graphql.ts +2691 -0
- package/__generated__/index.ts +1 -0
- package/codegen.ts +29 -0
- package/devices/VogentDevice.ts +12 -0
- package/devices/VonageDevice.ts +103 -0
- package/package.json +15 -0
- package/queries.ts +64 -0
- package/utils.ts +16 -0
package/VogentCall.ts
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { ApolloClient, InMemoryCache, NormalizedCacheObject, split } from '@apollo/client';
|
|
2
|
+
import { setContext } from '@apollo/client/link/context';
|
|
3
|
+
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
|
|
4
|
+
import { getMainDefinition, ObservableSubscription } from '@apollo/client/utilities';
|
|
5
|
+
import {
|
|
6
|
+
BrowserDialTokenType,
|
|
7
|
+
Dial,
|
|
8
|
+
DialsUpdatedMessage,
|
|
9
|
+
SessionMessageType,
|
|
10
|
+
} from './__generated__/graphql';
|
|
11
|
+
import {
|
|
12
|
+
AI_CONNECT_SESSION,
|
|
13
|
+
AI_GET_TOKEN,
|
|
14
|
+
AI_HANGUP_CALL,
|
|
15
|
+
AI_START_DIAL_SESSION,
|
|
16
|
+
} from './queries';
|
|
17
|
+
import { createClient } from 'graphql-ws';
|
|
18
|
+
import { VogentDevice } from './devices/VogentDevice';
|
|
19
|
+
import { VonageDevice } from './devices/VonageDevice';
|
|
20
|
+
import { dialStatusIsComplete } from './utils';
|
|
21
|
+
|
|
22
|
+
export class VogentCall {
|
|
23
|
+
client: ApolloClient<NormalizedCacheObject>;
|
|
24
|
+
sessionId: string;
|
|
25
|
+
subscription?: ObservableSubscription;
|
|
26
|
+
dial?: Dial;
|
|
27
|
+
_handlers: {
|
|
28
|
+
ev: 'status';
|
|
29
|
+
fn: (...args: any[]) => void;
|
|
30
|
+
}[];
|
|
31
|
+
|
|
32
|
+
constructor(id: string, token: string) {
|
|
33
|
+
this._handlers = [];
|
|
34
|
+
this.sessionId = id;
|
|
35
|
+
const authLink = setContext((_, { headers }) => {
|
|
36
|
+
return {
|
|
37
|
+
headers: {
|
|
38
|
+
...headers,
|
|
39
|
+
Authorization: `Bearer ${token}`,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const httpLink = createClient({
|
|
45
|
+
url: `https://api.getelto.com/query`,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const wsLink = new GraphQLWsLink(
|
|
49
|
+
createClient({
|
|
50
|
+
url: `wss://api.getelto.com/query`,
|
|
51
|
+
connectionParams: () => ({
|
|
52
|
+
authToken: token,
|
|
53
|
+
}),
|
|
54
|
+
})
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const splitLink = split(
|
|
58
|
+
({ query }) => {
|
|
59
|
+
const definition = getMainDefinition(query);
|
|
60
|
+
return definition.kind === 'OperationDefinition' && definition.operation === 'subscription';
|
|
61
|
+
},
|
|
62
|
+
wsLink,
|
|
63
|
+
// @ts-ignore
|
|
64
|
+
authLink.concat(httpLink)
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
this.client = new ApolloClient({
|
|
68
|
+
cache: new InMemoryCache(),
|
|
69
|
+
link: splitLink,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
on(ev: 'status', fn: (...args: any[]) => void) {
|
|
74
|
+
this._handlers.push({
|
|
75
|
+
ev,
|
|
76
|
+
fn,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
updateDial(dial: Dial) {
|
|
81
|
+
if (!this.dial || dial.status !== this.dial.status) {
|
|
82
|
+
this._handlers.forEach((h) => {
|
|
83
|
+
h.fn(dial.status);
|
|
84
|
+
});
|
|
85
|
+
} else {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (dialStatusIsComplete(dial.status)) {
|
|
90
|
+
this.subscription?.unsubscribe();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
this.dial = {
|
|
94
|
+
...this.dial,
|
|
95
|
+
...dial,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async start() {
|
|
100
|
+
const token = await this.client.mutate({
|
|
101
|
+
mutation: AI_GET_TOKEN,
|
|
102
|
+
variables: {
|
|
103
|
+
input: {
|
|
104
|
+
type: BrowserDialTokenType.DialSession,
|
|
105
|
+
dialSessionId: this.sessionId,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const d: VogentDevice = await VonageDevice.getDevice(token.data!.browserDialToken.token, true);
|
|
111
|
+
|
|
112
|
+
// setDevice(d);
|
|
113
|
+
|
|
114
|
+
this.subscription = this.client
|
|
115
|
+
.subscribe({
|
|
116
|
+
query: AI_CONNECT_SESSION,
|
|
117
|
+
variables: {
|
|
118
|
+
sessionId: this.sessionId,
|
|
119
|
+
},
|
|
120
|
+
})
|
|
121
|
+
.subscribe(({ data }) => {
|
|
122
|
+
switch (data?.connectSession.messageType) {
|
|
123
|
+
case SessionMessageType.GlobalCallConnect:
|
|
124
|
+
this.client.mutate({
|
|
125
|
+
mutation: AI_START_DIAL_SESSION,
|
|
126
|
+
variables: {
|
|
127
|
+
sessionId: this.sessionId,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
break;
|
|
132
|
+
case SessionMessageType.SessionContactUpdate: {
|
|
133
|
+
const content = data?.connectSession.content as DialsUpdatedMessage;
|
|
134
|
+
if (content.dials.length != 1) {
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
this.updateDial(content.dials[0]);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
const c = await d.connect({
|
|
144
|
+
params: { EltoDialSessionID: this.sessionId },
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async hangup() {
|
|
149
|
+
if (!this.dial) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
await this.client.mutate({
|
|
154
|
+
mutation: AI_HANGUP_CALL,
|
|
155
|
+
variables: {
|
|
156
|
+
dialId: this.dial.id,
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import * as types from './graphql';
|
|
3
|
+
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Map of all GraphQL operations in the project.
|
|
7
|
+
*
|
|
8
|
+
* This map has several performance disadvantages:
|
|
9
|
+
* 1. It is not tree-shakeable, so it will include all operations in the project.
|
|
10
|
+
* 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle.
|
|
11
|
+
* 3. It does not support dead code elimination, so it will add unused operations.
|
|
12
|
+
*
|
|
13
|
+
* Therefore it is highly recommended to use the babel or swc plugin for production.
|
|
14
|
+
* Learn more about it here: https://the-guild.dev/graphql/codegen/plugins/presets/preset-client#reducing-bundle-size
|
|
15
|
+
*/
|
|
16
|
+
const documents = {
|
|
17
|
+
"\nmutation CreateAdHocDialSession($input: CreateAdHocDialSessionInput!) {\n createAdHocDialSession(input: $input) {\n id\n telephonyProvider\n }\n}": types.CreateAdHocDialSessionDocument,
|
|
18
|
+
"\n mutation StartDialSession($sessionId: ID!) {\n startDialSession(dialSessionId: $sessionId)\n }\n": types.StartDialSessionDocument,
|
|
19
|
+
"\n mutation HangupCall($dialId: ID!, $dropVoicemail: Boolean, $transferNumber: String) {\n hangupCall(dialId: $dialId, dropVoicemail: $dropVoicemail, transferNumber: $transferNumber)\n }\n": types.HangupCallDocument,
|
|
20
|
+
"\n mutation BrowserDialToken($input: BrowserDialTokenInput!) {\n browserDialToken(input: $input) {\n token\n iceConfig\n }\n }\n": types.BrowserDialTokenDocument,
|
|
21
|
+
"\n subscription ConnectSession($sessionId: ID!) {\n connectSession(sessionId: $sessionId) {\n messageType\n content {\n __typename\n ... on DialsUpdatedMessage {\n contactId\n dials {\n id\n status\n answerType\n phoneField\n callDispositionId\n systemResultType\n toNumber\n }\n contactComplete\n }\n ... on DialConnectMessage {\n dialId\n }\n ... on SessionUpdatedMessage {\n dialSession {\n id\n status\n }\n reason\n }\n }\n }\n }\n": types.ConnectSessionDocument,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
26
|
+
*
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const query = gql(`query GetUser($id: ID!) { user(id: $id) { name } }`);
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* The query argument is unknown!
|
|
34
|
+
* Please regenerate the types.
|
|
35
|
+
*/
|
|
36
|
+
export function gql(source: string): unknown;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
40
|
+
*/
|
|
41
|
+
export function gql(source: "\nmutation CreateAdHocDialSession($input: CreateAdHocDialSessionInput!) {\n createAdHocDialSession(input: $input) {\n id\n telephonyProvider\n }\n}"): (typeof documents)["\nmutation CreateAdHocDialSession($input: CreateAdHocDialSessionInput!) {\n createAdHocDialSession(input: $input) {\n id\n telephonyProvider\n }\n}"];
|
|
42
|
+
/**
|
|
43
|
+
* The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
44
|
+
*/
|
|
45
|
+
export function gql(source: "\n mutation StartDialSession($sessionId: ID!) {\n startDialSession(dialSessionId: $sessionId)\n }\n"): (typeof documents)["\n mutation StartDialSession($sessionId: ID!) {\n startDialSession(dialSessionId: $sessionId)\n }\n"];
|
|
46
|
+
/**
|
|
47
|
+
* The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
48
|
+
*/
|
|
49
|
+
export function gql(source: "\n mutation HangupCall($dialId: ID!, $dropVoicemail: Boolean, $transferNumber: String) {\n hangupCall(dialId: $dialId, dropVoicemail: $dropVoicemail, transferNumber: $transferNumber)\n }\n"): (typeof documents)["\n mutation HangupCall($dialId: ID!, $dropVoicemail: Boolean, $transferNumber: String) {\n hangupCall(dialId: $dialId, dropVoicemail: $dropVoicemail, transferNumber: $transferNumber)\n }\n"];
|
|
50
|
+
/**
|
|
51
|
+
* The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
52
|
+
*/
|
|
53
|
+
export function gql(source: "\n mutation BrowserDialToken($input: BrowserDialTokenInput!) {\n browserDialToken(input: $input) {\n token\n iceConfig\n }\n }\n"): (typeof documents)["\n mutation BrowserDialToken($input: BrowserDialTokenInput!) {\n browserDialToken(input: $input) {\n token\n iceConfig\n }\n }\n"];
|
|
54
|
+
/**
|
|
55
|
+
* The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
56
|
+
*/
|
|
57
|
+
export function gql(source: "\n subscription ConnectSession($sessionId: ID!) {\n connectSession(sessionId: $sessionId) {\n messageType\n content {\n __typename\n ... on DialsUpdatedMessage {\n contactId\n dials {\n id\n status\n answerType\n phoneField\n callDispositionId\n systemResultType\n toNumber\n }\n contactComplete\n }\n ... on DialConnectMessage {\n dialId\n }\n ... on SessionUpdatedMessage {\n dialSession {\n id\n status\n }\n reason\n }\n }\n }\n }\n"): (typeof documents)["\n subscription ConnectSession($sessionId: ID!) {\n connectSession(sessionId: $sessionId) {\n messageType\n content {\n __typename\n ... on DialsUpdatedMessage {\n contactId\n dials {\n id\n status\n answerType\n phoneField\n callDispositionId\n systemResultType\n toNumber\n }\n contactComplete\n }\n ... on DialConnectMessage {\n dialId\n }\n ... on SessionUpdatedMessage {\n dialSession {\n id\n status\n }\n reason\n }\n }\n }\n }\n"];
|
|
58
|
+
|
|
59
|
+
export function gql(source: string) {
|
|
60
|
+
return (documents as any)[source] ?? {};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never;
|