forked from LivePersonInc/node-agent-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
MyCoolAgent.js
144 lines (131 loc) · 6.45 KB
/
MyCoolAgent.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
'use strict';
/*
* This demo try to use most of the API calls of the mssaging agent api. It:
*
* 1) Registers the agent as online
* 2) Accepts any routing task (== ring)
* 3) Publishes to the conversation the consumer info when it gets new conversation
* 4) Gets the content of the conversation
* 5) Emit 'MyCoolAgent.ContentEvnet' to let the developer handle contentEvent responses
* 6) Mark as 'read' the handled messages
*
*/
const Agent = require('./../../lib/AgentSDK');
class MyCoolAgent extends Agent {
constructor(conf) {
super(conf);
this.conf = conf;
this.init();
this.CONTENT_NOTIFICATION = 'MyCoolAgent.ContentEvnet';
this.consumerId = undefined;
}
init() {
let openConvs = {};
this.on('connected', msg => {
console.log('connected...', this.conf.id || '', msg);
this.setAgentState({availability: 'ONLINE'});
this.subscribeExConversations({
'agentIds': [this.agentId],
'convState': ['OPEN']
}, (e, resp) => console.log('subscribeExConversations', this.conf.id || '', resp || e));
this.subscribeRoutingTasks({});
this._pingClock = setInterval(this.getClock, 30000);
});
// Accept any routingTask (==ring)
this.on('routing.RoutingTaskNotification', body => {
body.changes.forEach(c => {
if (c.type === 'UPSERT') {
c.result.ringsDetails.forEach(r => {
if (r.ringState === 'WAITING') {
this.updateRingState({
'ringId': r.ringId,
'ringState': 'ACCEPTED'
}, (e, resp) => console.log(resp));
}
});
}
});
});
// Notification on changes in the open consversation list
this.on('cqm.ExConversationChangeNotification', notificationBody => {
notificationBody.changes.forEach(change => {
if (change.type === 'UPSERT' && !openConvs[change.result.convId]) {
// new conversation for me
openConvs[change.result.convId] = {};
// demonstraiton of using the consumer profile calls
this.consumerId = change.result.conversationDetails.participants.filter(p => p.role === 'CONSUMER')[0].id;
this.getUserProfile(this.consumerId, (e, profileResp) => {
this.publishEvent({
dialogId: change.result.convId,
event: {
type: 'ContentEvent',
contentType: 'text/plain',
message: `Just joined to conversation with ${JSON.stringify(profileResp)}`
}
});
});
this.subscribeMessagingEvents({dialogId: change.result.convId});
} else if(change.type === 'UPSERT' && openConvs[change.result.convId] && change.result.conversationDetails.participants.filter(p => p.role === 'CONSUMER')[0].id !== this.consumerId) {
// ConsumerID changed. Typically, a Step Up from an unauthenticated to an authenticated user.
this.consumerId = change.result.conversationDetails.participants.filter(p => p.role === 'CONSUMER')[0].id;
this.getUserProfile(this.consumerId, (e, profileResp) => {
this.publishEvent({
dialogId: change.result.convId,
event: {
type: 'ContentEvent',
contentType: 'text/plain',
message: `Consumer stepped up in conversation with ${JSON.stringify(profileResp)}`
}
});
});
} else if (change.type === 'DELETE') {
// conversation was closed or transferred
delete openConvs[change.result.convId];
}
});
});
// Echo every unread consumer message and mark it as read
this.on('ms.MessagingEventNotification', body => {
const respond = {};
body.changes.forEach(c => {
// In the current version MessagingEventNotification are recived also without subscription
// Will be fixed in the next api version. So we have to check if this notification is handled by us.
if (openConvs[c.dialogId]) {
// add to respond list all content event not by me
if (c.event.type === 'ContentEvent' && c.originatorId !== this.agentId) {
respond[`${body.dialogId}-${c.sequence}`] = {
dialogId: body.dialogId,
sequence: c.sequence,
message: c.event.message
};
}
// remove from respond list all the messages that were already read
if (c.event.type === 'AcceptStatusEvent' && c.originatorId === this.agentId) {
c.event.sequenceList.forEach(seq => {
delete respond[`${body.dialogId}-${seq}`];
});
}
}
});
// publish read, and echo
Object.keys(respond).forEach(key => {
let contentEvent = respond[key];
this.publishEvent({
dialogId: contentEvent.dialogId,
event: {type: 'AcceptStatusEvent', status: 'READ', sequenceList: [contentEvent.sequence]}
});
this.emit(this.CONTENT_NOTIFICATION, contentEvent);
});
});
// Tracing
//this.on('notification', msg => console.log('got message', msg));
this.on('error', err => console.log('got an error', err));
this.on('closed', data => {
// For production environments ensure that you implement reconnect logic according to
// liveperson's retry policy guidelines: https://developers.liveperson.com/guides-retry-policy.html
console.log('socket closed', data);
clearInterval(this._pingClock);
});
}
}
module.exports = MyCoolAgent;