@scout9/admin 1.0.0-alpha.0 → 1.0.0-alpha.0.0.2
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/README.md +349 -33
- package/build/api.d.ts +89 -101
- package/build/api.js +163 -163
- package/build/index.d.ts +1 -0
- package/build/index.js +1 -0
- package/build/webhooks.d.ts +11 -0
- package/build/webhooks.js +50 -0
- package/package.json +1 -1
- package/src/api.ts +159 -171
- package/src/index.ts +2 -1
- package/src/webhooks.ts +30 -0
- package/tsconfig.tsbuildinfo +1 -1
package/README.md
CHANGED
|
@@ -1,58 +1,374 @@
|
|
|
1
|
-
# Scout9 API
|
|
1
|
+
# Scout9's Pocket Scout API
|
|
2
2
|
|
|
3
|
-
Node.js API for [Scout9](https://
|
|
3
|
+
Pocket Scout Node.js API for [Scout9](https://pocket-guide.vercel.app/) - mimics you over your personal phone and email
|
|
4
|
+
for common tasks like scheduling meetings, answering questions, and more.
|
|
5
|
+
|
|
6
|
+
**⚠️ Danger**: Avoid using a Pocket Scout to autopilot your job and personal relationships, this tool is designed for
|
|
7
|
+
workplace productivity and not a substitute for human interaction.
|
|
8
|
+
|
|
9
|
+
## Setup
|
|
10
|
+
|
|
11
|
+
1. Register and grab an API key from [Scout9](https://pocket-guide.vercel.app/)
|
|
12
|
+
2. (Optional) [Purchase](https://pocket-guide.vercel.app/) a Scout9 email or phone number if you prefer
|
|
4
13
|
|
|
5
14
|
```bash
|
|
6
15
|
npm install @scout9/admin --save
|
|
7
16
|
```
|
|
8
17
|
|
|
9
18
|
```typescript
|
|
10
|
-
import { Configuration,
|
|
19
|
+
import { Configuration, PocketScoutApi } from '@scout9/admin';
|
|
11
20
|
|
|
12
21
|
const configuration = new Configuration({
|
|
13
22
|
apiKey: '', // Your API key
|
|
14
23
|
});
|
|
15
24
|
|
|
16
|
-
const
|
|
25
|
+
const pocketScout = new PocketScoutApi(configuration);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Step 1: Register yourself as an agent
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import fs from 'fs/promises';
|
|
32
|
+
import path from 'path';
|
|
33
|
+
|
|
34
|
+
// Registered your self as an agent within the Pocket Scout context
|
|
35
|
+
const agentId = await pocketScout
|
|
36
|
+
.agentRegister({
|
|
37
|
+
firstName: 'Tony',
|
|
38
|
+
lastName: 'Sopranos',
|
|
39
|
+
title: 'Boss',
|
|
40
|
+
|
|
41
|
+
// A brief description of yourself to set the tone
|
|
42
|
+
context: 'I\'m Tony. Look, this life, it ain\'t for the faint-hearted. I got responsibilities - to my family and my crew. Loyalty, respect, that\'s everything. When I deal with my associates, I\'m direct. I expect them to come to me straight, no BS. Some might call me tough, even ruthless, but it\'s the world we\'re in. You show weakness, you\'re done. I\'ve got a code, though. If you\'re loyal to me, I\'ll have your back. But cross me? That\'s something you\'ll regret. It\'s business, but it\'s also personal. We\'re a family.',
|
|
43
|
+
|
|
44
|
+
// Must provide one of the following...
|
|
45
|
+
forwardPhone: '+15555555544', // my personal phone number to get notified of in coming messages
|
|
46
|
+
forwardEmail: 'tonyboss@gmail.com', // my personal email to get notified of in coming messages
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* (optional) either a provided Scout9 phone number or your personal
|
|
51
|
+
* ⚠️ Note: If a personal number, you'll be asked to download the Pocket Scout app to enable Pocket Scout auto responses
|
|
52
|
+
*/
|
|
53
|
+
programmablePhoneNumber: '+15555555555',
|
|
17
54
|
|
|
18
|
-
|
|
55
|
+
/**
|
|
56
|
+
* (optional) either a provided Scout9 email or your personal
|
|
57
|
+
* ⚠️ Note: If a personal email, you'll be asked to authenticate your Pocket Scout onto your email account
|
|
58
|
+
*/
|
|
59
|
+
programmableEmail: `tonyboss@gmail.com`,
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Optional conversation data to help your Pocket Scout capture your tone
|
|
64
|
+
* See ../examples/samples to see coversation text format or enter JSON manually
|
|
65
|
+
*/
|
|
66
|
+
conversations: [
|
|
67
|
+
await pocketScout.fileCreate(await fs.readFile('./conversation1.txt'), 'conversation with Chris')
|
|
68
|
+
.then(res => res.data.id),
|
|
69
|
+
await pocketScout.fileCreate(await fs.readFile('./conversation2.txt'), 'conversation with Paulie')
|
|
70
|
+
.then(res => res.data.id),
|
|
71
|
+
],
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* (optional) audio data to help your Pocket Scout capture your tone
|
|
75
|
+
* (Eventually your Pocket Scout can use this to generate voice responses, but for now its more of a way to capture your tone/character)
|
|
76
|
+
*/
|
|
77
|
+
audio: [
|
|
78
|
+
await pocketScout.fileCreate(await fs.readFile('./audio.mp3'),
|
|
79
|
+
'Secret Audio of me talking to Dr. Melfi (no one can know about this)').then(res => res.data.id),
|
|
80
|
+
]
|
|
81
|
+
})
|
|
82
|
+
.then((res) => res.data.id);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Step 2: Register customers
|
|
86
|
+
|
|
87
|
+
You can register customers by adding their email or phone.
|
|
88
|
+
|
|
89
|
+
**⚠️ Note:** If you are using a provided Scout9 email or phone number, customers must opt-in to receive messages or
|
|
90
|
+
initiate conversations with you.
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
// Create 1 customer
|
|
94
|
+
const customerId = await pocketScout.createCustomer({
|
|
19
95
|
firstName: 'Hi',
|
|
20
96
|
lastName: 'Jack',
|
|
21
97
|
email: 'hi@example.com',
|
|
22
98
|
phone: '+15555555555',
|
|
23
99
|
})
|
|
24
|
-
.then((res) =>
|
|
25
|
-
console.log('Success', res);
|
|
26
|
-
})
|
|
27
|
-
.catch((err) => {
|
|
28
|
-
console.error('Error', err);
|
|
29
|
-
});
|
|
100
|
+
.then((res) => res.data.id);
|
|
30
101
|
|
|
102
|
+
// Or create multiple customers
|
|
103
|
+
const customers: Customer[] = [
|
|
104
|
+
{
|
|
105
|
+
// scout9 internal values
|
|
106
|
+
name: 'Tony Soprano',
|
|
107
|
+
phone: null,
|
|
108
|
+
email: null,
|
|
31
109
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
console.error('Error', err);
|
|
43
|
-
});
|
|
110
|
+
// customer properties
|
|
111
|
+
role: 'boss',
|
|
112
|
+
customId: 'tony-soprano',
|
|
113
|
+
fun_fact: 'I love my ducks'
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
// scout9 internal values
|
|
117
|
+
name: 'Carmela Soprano',
|
|
118
|
+
phone: null,
|
|
119
|
+
email: null,
|
|
44
120
|
|
|
121
|
+
// customer properties
|
|
122
|
+
favorite_drink: 'lillet blanc',
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
name: 'Salvatore Bonpensiero',
|
|
126
|
+
firstName: 'Salvatore',
|
|
127
|
+
phone: null,
|
|
128
|
+
email: null,
|
|
129
|
+
$agent: 'skip_lipari', // agent id
|
|
45
130
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
131
|
+
// customer properties
|
|
132
|
+
rat: true,
|
|
133
|
+
location: 'New Jersey coast',
|
|
134
|
+
nickname: 'Big 🐈',
|
|
135
|
+
lastSeason: 'season 1'
|
|
136
|
+
}
|
|
137
|
+
];
|
|
138
|
+
await pocketScout.customersCreate({customers});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Step 3: Initiate a conversation
|
|
142
|
+
|
|
143
|
+
Initiate a default generic conversation with an existing customer, use the optional **initialMessage** to provide some
|
|
144
|
+
guidance.
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
const initialMessage = `Hey there, would you like a free pizza?`;
|
|
148
|
+
|
|
149
|
+
const conversation = await pocketScout.conversationCreate({
|
|
150
|
+
customer: customerId,
|
|
151
|
+
agent: agentId,
|
|
152
|
+
environment: 'phone', // This will attempt to contact via SMS
|
|
153
|
+
// Add some initial contexts to the conversation to help the agent get started
|
|
154
|
+
initialContexts: [
|
|
155
|
+
'We are offering free pizzas to the first 100 hundred customers for today only',
|
|
156
|
+
'We have pepperoni, cheese, meat lovers, and vegan pizzas available',
|
|
157
|
+
'We do not have gluten free pizzas available at this time',
|
|
158
|
+
'We are only offering free pizzas, nothing else',
|
|
159
|
+
'You must pick up the free pizza at 255 W Alameda St, Tucson, AZ 85701',
|
|
160
|
+
'We close at 10pm tonight',
|
|
161
|
+
'If the customer is not interested or serious in receiving a free pizza, disengage and direct them to our website (https://azpizzatime.com) for future orders'
|
|
162
|
+
]
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Send a message
|
|
166
|
+
await pocketScout.message({convo: conversation.data.id, message: initialMessage});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Step 4: Test your conversation
|
|
170
|
+
|
|
171
|
+
Test your conversation before you send a message.
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
const initialMessage = `Hey there, would you like a free pizza?`;
|
|
175
|
+
|
|
176
|
+
const conversationId = await pocketScout.conversationCreate({
|
|
177
|
+
customer: customerId,
|
|
178
|
+
agent: agentId,
|
|
179
|
+
environment: 'phone', // This will attempt to contact via SMS
|
|
180
|
+
// Add some initial contexts to the conversation to help the agent get started
|
|
181
|
+
initialContexts: [
|
|
182
|
+
'We are offering free pizzas to the first 100 hundred customers for today only',
|
|
183
|
+
'We have pepperoni, cheese, meat lovers, and vegan pizzas available',
|
|
184
|
+
'We do not have gluten free pizzas available at this time',
|
|
185
|
+
'We are only offering free pizzas, nothing else',
|
|
186
|
+
'You must pick up the free pizza at 255 W Alameda St, Tucson, AZ 85701',
|
|
187
|
+
'We close at 10pm tonight',
|
|
188
|
+
'If the customer is not interested or serious in receiving a free pizza, disengage and direct them to our website (https://azpizzatime.com) for future orders'
|
|
189
|
+
]
|
|
190
|
+
}).then((res) => res.data.id);
|
|
191
|
+
|
|
192
|
+
const anticipatedCustomerResponses = [
|
|
193
|
+
'Yes please!',
|
|
194
|
+
'No thanks',
|
|
195
|
+
'What kind of pizza are we talking about?',
|
|
196
|
+
'I\'m vegan, do you have vegan pizza?',
|
|
197
|
+
'I hate you, stop texting me',
|
|
198
|
+
'I love you, keep texting me',
|
|
199
|
+
];
|
|
200
|
+
for (const customerResponse of anticipatedCustomerResponses) {
|
|
201
|
+
const generatedResponse = await pocketScout.generate({
|
|
202
|
+
convo: conversationId,
|
|
203
|
+
mocks: {
|
|
204
|
+
messages: [
|
|
205
|
+
{
|
|
206
|
+
role: 'customer',
|
|
207
|
+
content: customerResponse
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
}
|
|
54
211
|
})
|
|
55
|
-
|
|
56
|
-
|
|
212
|
+
.then((res) => res.data.content);
|
|
213
|
+
|
|
214
|
+
console.log(`\n\tCustomer: "${customerResponse}"\n\tAgent: "${generatedResponse}"\n`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
console.log(`Looks good 👍 - sending messing to customer`);
|
|
218
|
+
await pocketScout.message({convo: conversation.data.id, message: initialMessage});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Step 5: View your conversation
|
|
222
|
+
|
|
223
|
+
Messages and customer responses can be viewed in the [Scout9 UI](https://pocket-guide.vercel.app/). You can also
|
|
224
|
+
configure webhooks in the account portal to listen to incoming messages on your own server.
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
const messages = await pocketScout.messages(conversationId);
|
|
228
|
+
console.log(`Retrieved ${messages.data.length} messages from the conversation`);
|
|
229
|
+
|
|
230
|
+
for (const message of messages.data) {
|
|
231
|
+
console.log(`\t${message.role}: ${message.content}`);
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Advanced Examples
|
|
236
|
+
|
|
237
|
+
### Schedule a conversation
|
|
238
|
+
|
|
239
|
+
See [simple-schedule-conversation.ts](../../examples/simple-schedule-conversation.ts) on how to test a conversation before its
|
|
240
|
+
created.
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
const initialMessage = `Hey there, would you like a free pizza?`;
|
|
244
|
+
|
|
245
|
+
const conversation = await pocketScout.scheduleConversation({
|
|
246
|
+
customer: customerId,
|
|
247
|
+
agent: agentId,
|
|
248
|
+
environment: 'phone', // This will attempt to contact via SMS
|
|
249
|
+
// Add some initial contexts to the conversation to help the agent get started
|
|
250
|
+
initialContexts: [
|
|
251
|
+
'We are offering free pizzas to the first 100 hundred customers for today only',
|
|
252
|
+
'We have pepperoni, cheese, meat lovers, and vegan pizzas available',
|
|
253
|
+
'We do not have gluten free pizzas available at this time',
|
|
254
|
+
'We are only offering free pizzas, nothing else',
|
|
255
|
+
'You must pick up the free pizza at 255 W Alameda St, Tucson, AZ 85701',
|
|
256
|
+
'We close at 10pm tonight',
|
|
257
|
+
'If the customer is not interested or serious in receiving a free pizza, disengage and direct them to our website (https://azpizzatime.com) for future orders'
|
|
258
|
+
]
|
|
57
259
|
});
|
|
58
260
|
```
|
|
261
|
+
|
|
262
|
+
### Define workflows
|
|
263
|
+
|
|
264
|
+
Conversations by default use a generic **workflow** procedure that has a stated goal to guide your Pocket Scout in a
|
|
265
|
+
conversation. Initiate a conversation with a clear specific objective using the **workflow** api.
|
|
266
|
+
|
|
267
|
+
See [full workflow example](../../examples/create-workflow.ts)
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
const workflow: CreateWorkflowRequest = {
|
|
271
|
+
name: 'Order Pizza',
|
|
272
|
+
|
|
273
|
+
// Define the goal of the workflow
|
|
274
|
+
context: 'When a customer wants to order a pizza, I will determine what pizza they need and when, then determine if it needs to be picked up or delivered to their address.',
|
|
275
|
+
|
|
276
|
+
// fields follow this boolean structure -> (a || b) && (c || d), if true then the context will be inserted into the conversation.
|
|
277
|
+
fields: contextFields,
|
|
278
|
+
|
|
279
|
+
// Custom context and how this workflow will be triggered from a customer conversation
|
|
280
|
+
initiators: {
|
|
281
|
+
// We need to describe the fields that we want to collect from the customer in this workflow
|
|
282
|
+
// entity fields such as firstName, address, location, etc are built in and will be provided by default
|
|
283
|
+
entities: customEntities,
|
|
284
|
+
documents: workflowTriggerStatements
|
|
285
|
+
},
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
const workflowId = await pocketScout.workflowCreate(workflow).then(res => res.data.id);
|
|
289
|
+
|
|
290
|
+
console.log(`Created workflow with id: ${workflowId}`);
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Use the `.fields` property to guide the conversation to accomplish the goal. In this example we ask the user for the
|
|
294
|
+
pizza size, sauce, toppings, when, delivery or take out, and if delivery then the address.
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
const contextFields: ConversationContextField[] = [
|
|
298
|
+
{
|
|
299
|
+
id: 'determineSize',
|
|
300
|
+
context: 'Determine what size pizza the customer wants, we have small, medium, and large',
|
|
301
|
+
conditions: [
|
|
302
|
+
{
|
|
303
|
+
conditions: [
|
|
304
|
+
{
|
|
305
|
+
key: 'pizzaSize', // If we don't know the pizzaSize, then insert this context
|
|
306
|
+
operator: 'notExists',
|
|
307
|
+
value: true
|
|
308
|
+
}
|
|
309
|
+
]
|
|
310
|
+
}
|
|
311
|
+
]
|
|
312
|
+
},
|
|
313
|
+
// ... other field definitions
|
|
314
|
+
]
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
In the `.initiators.entities` we can define custom fields that the Pocket Scout can search for and store in the
|
|
318
|
+
conversation
|
|
319
|
+
|
|
320
|
+
In this example we include a custom entity field `pizzaSize` which can be described as a small or personal pizza.
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
const customEntities = [
|
|
324
|
+
{
|
|
325
|
+
utteranceId: 'pizzaSize',
|
|
326
|
+
option: 'small',
|
|
327
|
+
languages: ['en'],
|
|
328
|
+
text: [
|
|
329
|
+
'small',
|
|
330
|
+
'personal',
|
|
331
|
+
'individual',
|
|
332
|
+
'6-inch',
|
|
333
|
+
'8-inch',
|
|
334
|
+
]
|
|
335
|
+
},
|
|
336
|
+
// ... other custom entities or pizza sizes
|
|
337
|
+
]
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Then we need some statements that can trigger the workflow and context fields that get stored in `.initiators.documents`.
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
const workflowTriggerStatements = [
|
|
344
|
+
{text: 'I would like to order a %pizzaSize% %pizzaType%', id: 'request'},
|
|
345
|
+
// ... more examples that might trigger the workflow
|
|
346
|
+
];
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Respond to a customer
|
|
350
|
+
|
|
351
|
+
If a customer triggers one of your active **workflows**, then by default your Pocket Scout will respond to the customer.
|
|
352
|
+
If you respond manually, then the Pocket Scout will stop responding to the customer for the entire conversation.
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
await pocketScout.message({convo: conversationId, message: 'Hey there, would you like a free pizza?'});
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Available Platforms
|
|
359
|
+
|
|
360
|
+
Customers can interact with you (and your Pocket Scout) on any of the connected platforms
|
|
361
|
+
|
|
362
|
+
| Platforms | Supported | |
|
|
363
|
+
|--------------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
364
|
+
| Android | ⚠️ (pending) | (free) An android app is in development to enable your Pocket Scout to respond to SMS text |
|
|
365
|
+
| iOS | ⚠️ (pending) | (free) An ios app is in development to enable your Pocket Scout to respond to iMessages |
|
|
366
|
+
| Web | ✅ | (free) We generate conversation links for you and your customers to quickly connect, conversations expire in 1 day |
|
|
367
|
+
| Gmail | ✅ | (free) Provide Scout9 authorization access to your gmail account for read/write capabilities so your Pocket Scout can respond to emails |
|
|
368
|
+
| Outlook | ⚠️ (pending) | (free) Provide Scout9 authorization access to your outlook account for read/write capabilities so your Pocket Scout can respond to emails |
|
|
369
|
+
| Native Email | ❌ | For security and privacy concerns we currently cannot support native email systems at this time |
|
|
370
|
+
| Discord | ⚠️ (pending) | (free) Download the Pocket Scout Discord bot and configure workflows to respond to messages accordingly |
|
|
371
|
+
| Slack | ⚠️ (pending) | (free) Download the Pocket Scout Slack agent and configure workflows to respond to messages accordingly |
|
|
372
|
+
| Teams | ⚠️ (pending) | (free) Download the Pocket Scout Teams add-on |
|
|
373
|
+
| Scout9 Phone | ✅ | $5/month we provide a generated phone number you can use for your Pocket Scout to text, messages will be relayed back to your personal phone number |
|
|
374
|
+
| Scout9 Email | ✅ | $5/month We provide a generated email with your name (e.g. patrick.opie@scout9.com) you can use for your Pocket Scout |
|