@scout9/admin 1.0.0-alpha.0.0.26 → 1.0.0-alpha.0.0.28

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