wingbot 3.67.22 → 3.67.25

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.
Files changed (31) hide show
  1. package/package.json +1 -1
  2. package/src/Ai.js +8 -2
  3. package/src/AiMatching.js +18 -8
  4. package/src/BotApp.js +23 -14
  5. package/src/OrchestratorClient.js +127 -0
  6. package/src/Request.js +1 -1
  7. package/src/Tester.js +10 -2
  8. package/src/fuzzy/factoryFuzzySearch.js +1 -1
  9. package/plugins/ai.wingbot.clearMessageSequences/README.md +0 -1
  10. package/plugins/ai.wingbot.conditionIfGoBackPossible/README.md +0 -7
  11. package/plugins/ai.wingbot.disambiguation/README.md +0 -12
  12. package/plugins/ai.wingbot.goBack/README.md +0 -9
  13. package/plugins/ai.wingbot.goToLastBreadcrumb/README.md +0 -8
  14. package/plugins/ai.wingbot.ifImageDetected/README.md +0 -10
  15. package/plugins/ai.wingbot.ifStickerDetected/README.md +0 -10
  16. package/plugins/ai.wingbot.jumpBack/README.md +0 -9
  17. package/plugins/ai.wingbot.jumpTo/README.md +0 -9
  18. package/plugins/ai.wingbot.keepInInteraction/README.md +0 -12
  19. package/plugins/ai.wingbot.keepInInteractionJustOnce/README.md +0 -13
  20. package/plugins/ai.wingbot.keepPreviousHandlers/README.md +0 -17
  21. package/plugins/ai.wingbot.keepPreviousHandlersJustOnce/README.md +0 -15
  22. package/plugins/ai.wingbot.oneTimeNotificationRequest/README.md +0 -5
  23. package/plugins/ai.wingbot.openai/README.md +0 -1
  24. package/plugins/ai.wingbot.passThreadToBot/README.md +0 -19
  25. package/plugins/ai.wingbot.putABreadcrumb/README.md +0 -8
  26. package/plugins/ai.wingbot.regexp/README.md +0 -1
  27. package/plugins/ai.wingbot.setState/README.md +0 -1
  28. package/plugins/ai.wingbot.setStateFromInput/README.md +0 -1
  29. package/plugins/ai.wingbot.stopResponding/README.md +0 -7
  30. package/plugins/ai.wingbot.trackingEvent/README.md +0 -3
  31. package/plugins/ai.wingbot.waitASecond/README.md +0 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wingbot",
3
- "version": "3.67.22",
3
+ "version": "3.67.25",
4
4
  "description": "Enterprise Messaging Bot Conversation Engine",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
package/src/Ai.js CHANGED
@@ -553,9 +553,15 @@ class Ai {
553
553
  };
554
554
  }
555
555
 
556
- ruleIsMatching (intent, req, stateless = false) {
556
+ ruleIsMatching (intent, req, stateless = false, noEntityThreshold = false) {
557
557
  const rules = this.matcher.preprocessRule(intent);
558
- const winningIntent = this.matcher.match(req, rules, stateless);
558
+ const winningIntent = this.matcher.match(
559
+ req,
560
+ rules,
561
+ stateless,
562
+ undefined,
563
+ noEntityThreshold
564
+ );
559
565
 
560
566
  if (!winningIntent || winningIntent.score < this.threshold) {
561
567
  return null;
package/src/AiMatching.js CHANGED
@@ -467,9 +467,10 @@ class AiMatching {
467
467
  * @param {PreprocessorOutput} rule
468
468
  * @param {boolean} [stateless]
469
469
  * @param {Entity[]} [reqEntities]
470
+ * @param {boolean} [noEntityThreshold]
470
471
  * @returns {Intent|null}
471
472
  */
472
- match (req, rule, stateless = false, reqEntities = req.entities) {
473
+ match (req, rule, stateless = false, reqEntities = req.entities, noEntityThreshold = false) {
473
474
  const { regexps, intents, entities } = rule;
474
475
 
475
476
  const noIntentHandicap = req.intents.length === 0 ? 0 : this.redundantIntentHandicap;
@@ -510,7 +511,10 @@ class AiMatching {
510
511
  textLength,
511
512
  entities,
512
513
  reqEntities,
513
- useState
514
+ useState,
515
+ undefined,
516
+ undefined,
517
+ noEntityThreshold
514
518
  );
515
519
 
516
520
  const allOptional = entities.every((e) => e.optional
@@ -576,7 +580,8 @@ class AiMatching {
576
580
  requestIntent,
577
581
  entities,
578
582
  req,
579
- useState
583
+ useState,
584
+ noEntityThreshold
580
585
  );
581
586
 
582
587
  if (score > max) {
@@ -610,6 +615,7 @@ class AiMatching {
610
615
  * @param {EntityExpression[]} wantedEntities
611
616
  * @param {AIRequest} req
612
617
  * @param {object} useState
618
+ * @param {boolean} [noEntityThreshold]
613
619
  * @returns {{score:number,entities:Entity[]}}
614
620
  */
615
621
  _intentMatchingScore (
@@ -618,7 +624,8 @@ class AiMatching {
618
624
  requestIntent,
619
625
  wantedEntities,
620
626
  req,
621
- useState
627
+ useState,
628
+ noEntityThreshold = false
622
629
  ) {
623
630
  if (wantedIntent !== requestIntent.intent) {
624
631
  return { score: 0, entities: [] };
@@ -644,7 +651,8 @@ class AiMatching {
644
651
  requestIntent.entities
645
652
  ? (x) => Math.atan((x - 0.76) * 40) / Math.atan((1 - 0.76) * 40)
646
653
  : (x) => x,
647
- req.entities
654
+ req.entities,
655
+ noEntityThreshold
648
656
  );
649
657
 
650
658
  // eslint-disable-next-line max-len,object-curly-newline
@@ -680,7 +688,8 @@ class AiMatching {
680
688
  * @param {Entity[]} requestEntities
681
689
  * @param {object} [requestState]
682
690
  * @param {Function} [scoreFn]
683
- * @param {Entity[]} allEntities
691
+ * @param {Entity[]} [allEntities]
692
+ * @param {boolean} [noEntityThreshold]
684
693
  *
685
694
  * @returns {EntityMatchingResult}
686
695
  */
@@ -690,7 +699,8 @@ class AiMatching {
690
699
  requestEntities = [],
691
700
  requestState = {},
692
701
  scoreFn = (x) => x,
693
- allEntities = requestEntities
702
+ allEntities = requestEntities,
703
+ noEntityThreshold = false
694
704
  ) {
695
705
  const occurences = new Map();
696
706
 
@@ -713,7 +723,7 @@ class AiMatching {
713
723
  .findIndex((e, i) => {
714
724
  if (e.entity !== wanted.entity
715
725
  || usedIndexes.includes(i)
716
- || e.score < ENTITY_OK) {
726
+ || (!noEntityThreshold && e.score < ENTITY_OK)) {
717
727
  return false;
718
728
  }
719
729
  entityExists = true;
package/src/BotApp.js CHANGED
@@ -166,24 +166,33 @@ class BotApp {
166
166
  * @param {Responder} res
167
167
  */
168
168
  afterProcessMessage (req, res) {
169
- const wasSet = req.getSetContext(true);
170
- const updatedVariables = Object.keys(res.newState)
171
- .filter((key) => key.match(/^§/) && wasSet[key] !== res.newState[key]);
172
-
173
- if (updatedVariables.length !== 0) {
174
- const setContext = updatedVariables
175
- .reduce((o, key) => Object.assign(o, {
176
- [key.replace(/^§/, '')]: res.newState[key]
177
- }), {});
178
-
179
- res.send({
180
- set_context: setContext
181
- });
182
- }
169
+ BotApp.sendContext(req, res);
183
170
  }
184
171
  };
185
172
  }
186
173
 
174
+ /**
175
+ *
176
+ * @param {Request} req
177
+ * @param {Responder} res
178
+ */
179
+ static sendContext (req, res) {
180
+ const wasSet = req.getSetContext(true);
181
+ const updatedVariables = Object.keys(res.newState)
182
+ .filter((key) => key.match(/^§/) && wasSet[key] !== res.newState[key]);
183
+
184
+ if (updatedVariables.length !== 0) {
185
+ const setContext = updatedVariables
186
+ .reduce((o, key) => Object.assign(o, {
187
+ [key.replace(/^§/, '')]: res.newState[key]
188
+ }), {});
189
+
190
+ res.send({
191
+ set_context: setContext
192
+ });
193
+ }
194
+ }
195
+
187
196
  /**
188
197
  * Get the processor instance
189
198
  *
@@ -6,6 +6,9 @@
6
6
  const { withParams } = require('webalize');
7
7
  const { default: fetch, Headers } = require('node-fetch');
8
8
  const BotAppSender = require('./BotAppSender');
9
+ const extractText = require('./transcript/extractText');
10
+
11
+ /** @typedef {import('./transcript/transcriptFromHistory').Transcript} Transcript */
9
12
 
10
13
  /**
11
14
  * @typedef OrchestratorClientOptions
@@ -60,7 +63,131 @@ class OrchestratorClient {
60
63
  expirationInSeconds,
61
64
  conversationToken
62
65
  };
66
+ }
67
+
68
+ /**
69
+ * @returns {Promise<Transcript[]>}
70
+ */
71
+ async getTranscript () {
72
+ const events = await this.getChatHistory();
73
+
74
+ return events
75
+ .map((e) => {
76
+ const text = extractText(e);
77
+
78
+ return {
79
+ fromBot: e.sender
80
+ ? e.sender.id !== this._senderId
81
+ : e.recipient.id === this._senderId,
82
+ text
83
+ };
84
+ })
85
+ .filter((ret) => !!ret.text);
86
+ }
87
+
88
+ /**
89
+ *
90
+ * @returns {Promise<object[]>}
91
+ */
92
+ async getChatHistory () {
93
+ const res = await this._send({
94
+ query: `query FetchHistory (
95
+ $pageId: String!
96
+ $senderId: String!
97
+ ) {
98
+ chat {
99
+ history (
100
+ pageId: $pageId,
101
+ senderId: $senderId
102
+ ) {
103
+ events {
104
+ sender {
105
+ id
106
+ }
107
+ recipient {
108
+ id
109
+ }
110
+ mid
111
+ timestamp
112
+ sender_action
113
+ set_context
114
+ postback {
115
+ payload
116
+ title
117
+ }
118
+ expected {
119
+ input {
120
+ type
121
+ }
122
+ }
123
+ persona {
124
+ name
125
+ profile_pic_url
126
+ }
127
+ message {
128
+ text
129
+ is_confident
130
+ attachments {
131
+ type
132
+ payload {
133
+ url
134
+ template_type
135
+ image_aspect_ratio
136
+ text
137
+ buttons {
138
+ type
139
+ title
140
+ payload
141
+ url
142
+ }
143
+ elements {
144
+ default_action {
145
+ type
146
+ title
147
+ payload
148
+ url
149
+ }
150
+ title
151
+ subtitle
152
+ image_url
153
+ buttons {
154
+ type
155
+ title
156
+ payload
157
+ url
158
+ }
159
+ }
160
+ }
161
+ }
162
+ quick_replies {
163
+ content_type
164
+ title
165
+ payload
166
+ }
167
+ }
168
+ }
169
+ nextStartAt
170
+ nextEndAt
171
+ }
172
+ }
173
+ }`,
174
+ variables: {
175
+ senderId: this._senderId,
176
+ pageId: this._pageId
177
+ }
178
+ });
179
+
180
+ if (res.errors && res.errors[0]) {
181
+ throw new Error(res.errors[0].message);
182
+ }
183
+
184
+ const events = (res.data
185
+ && res.data
186
+ && res.data.chat
187
+ && res.data.chat.history
188
+ && res.data.chat.history.events) || [];
63
189
 
190
+ return events;
64
191
  }
65
192
 
66
193
  /**
package/src/Request.js CHANGED
@@ -1649,7 +1649,7 @@ It looks like the bot isn't connected to class BotApp or the Processor is used w
1649
1649
  entity,
1650
1650
  value,
1651
1651
  score = 1,
1652
- entityScore = Math.max(score, 0.8),
1652
+ entityScore = Math.max(score, 0.835),
1653
1653
  timestamp = makeTimestamp()
1654
1654
  ) {
1655
1655
  const res = Request.text(senderId, text, timestamp);
package/src/Tester.js CHANGED
@@ -461,13 +461,21 @@ class Tester {
461
461
  * @param {string} [value]
462
462
  * @param {string} [text]
463
463
  * @param {number} [score]
464
+ * @param {number} [entityScore]
464
465
  * @returns {Promise}
465
466
  *
466
467
  * @memberOf Tester
467
468
  */
468
- intentWithEntity (intent, entity, value = entity, text = intent, score = 1) {
469
+ intentWithEntity (
470
+ intent,
471
+ entity,
472
+ value = entity,
473
+ text = intent,
474
+ score = 1,
475
+ entityScore = score
476
+ ) {
469
477
  return this.processMessage(Request
470
- .intentWithEntity(this.senderId, text, intent, entity, value, score));
478
+ .intentWithEntity(this.senderId, text, intent, entity, value, score, entityScore));
471
479
  }
472
480
 
473
481
  /**
@@ -41,7 +41,7 @@ function getIndexesToIterate (ngrams, tfEntry) {
41
41
  function searchFnFactory (indexMap, ngramCounts, entities, maxIdf, {
42
42
  stemmer = null,
43
43
  keepMultipleValues = false,
44
- threshold = 0.79,
44
+ threshold = 0.835,
45
45
  limit = undefined
46
46
  }, hasFuzzyMultiplier = false) {
47
47
  /** @type {WordEntityDetector} */
@@ -1 +0,0 @@
1
- > This plugin erases state of conversational sequences
@@ -1,7 +0,0 @@
1
- > This plugin helps you to hide "back" quick reply, when there is no interaction to go.
2
-
3
- Put it as a condition to quick reply and it will be only visible, when there is an interaction to go back to.
4
-
5
- Use it in combination with the **Go back to previous interaction** plugin.
6
-
7
- ![go back condition](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.conditionIfGoBackPossible/back.png)
@@ -1,12 +0,0 @@
1
- > Disambiguation is useful, when the bot has lot of very similar intents. When more than one intent is detected, users can decide, what was their intention.
2
-
3
- How to set up the disambiguation.
4
-
5
- 1. Put this plugin into a fallback
6
- 2. Set up the disambiguation message (disambiguation options will be added to the message as quick replies)
7
- 3. Put a regular "fallback" message behind this plugin. If the disambiguation will not occur, your bot will answer with this fallback message
8
- 4. Add a disambiguation title to all interactions, which you want to disambiguate
9
-
10
- To fine tune the disambiguation, you can also set up a custom `ai.threshold` on bot (there is `0.3` by default). Detected intent has to reach this minimum score, to be disambiguated.
11
-
12
- ![disambiguation](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.disambiguation/disambiguation.png)
@@ -1,9 +0,0 @@
1
- > This plugin helps you to drive user back to previous interaction.
2
-
3
- If the previous interaction exists and it's not a fallback or the same interaction, where the plugin is, the bot will go back and stops executing this interaction.
4
-
5
- If not, the bot will continue in execution of this interaction, so you can handle situation.
6
-
7
- It's useful to it use **Show when there is a way back** condition, so you don't have to worry about handling the situation, when there's no way to go back.
8
-
9
- ![go back condition](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.conditionIfGoBackPossible/back.png)
@@ -1,8 +0,0 @@
1
- > Breadcrumbs allows you to track some particular flow and make user able to return to previous steps in the flow.
2
-
3
- This is a example of using breadcrubms:
4
-
5
- 1. Put breadcrumbs at checkpoints - interaction, where each step begins
6
- 2. Allow user to get back to the previous step using a **Go to last breadcrumb** plugin.
7
-
8
- ![breadcrumbs](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.putABreadcrumb/breadcrumbs.png)
@@ -1,10 +0,0 @@
1
- > This plugin helps you to react, when user randomly sends an image attachment to your bot.
2
-
3
- How to set up this plugin:
4
-
5
- 1. create a new interaction in **Root dialogue** and place it before a first fallback
6
- 2. Put the plugin on top position in this interaction
7
- 3. Make the interaction to intercept all messages - the star icon should appear at it's top right corner
8
- 4. Insert your reactions under the plugin
9
-
10
- ![image detector](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.ifImageDetected/image.png)
@@ -1,10 +0,0 @@
1
- > This plugin helps you to react, when user randomly sends a sticker to your bot from Facebook Messenger.
2
-
3
- How to set up this plugin:
4
-
5
- 1. create a new interaction in **Root dialogue** and place it before a first fallback
6
- 2. Put the plugin on top position in this interaction
7
- 3. Make the interaction to intercept all messages - the star icon should appear at it's top right corner
8
- 4. Insert your reactions under the plugin
9
-
10
- ![sticker detector](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.ifStickerDetected/sticker.png)
@@ -1,9 +0,0 @@
1
- > This plugin helps you to drive user back to previous interaction.
2
-
3
- If the previous interaction exists and it's not a fallback or the same interaction, where the plugin is, the bot will go back and stops executing this interaction.
4
-
5
- If not, the bot will continue in execution of this interaction, so you can handle situation.
6
-
7
- It's useful to it use **Show when there is a way back** condition, so you don't have to worry about handling the situation, when there's no way to go back.
8
-
9
- ![go back condition](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.conditionIfGoBackPossible/back.png)
@@ -1,9 +0,0 @@
1
- > This plugin helps you to drive user back to previous interaction.
2
-
3
- If the previous interaction exists and it's not a fallback or the same interaction, where the plugin is, the bot will go back and stops executing this interaction.
4
-
5
- If not, the bot will continue in execution of this interaction, so you can handle situation.
6
-
7
- It's useful to it use **Show when there is a way back** condition, so you don't have to worry about handling the situation, when there's no way to go back.
8
-
9
- ![go back condition](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.conditionIfGoBackPossible/back.png)
@@ -1,12 +0,0 @@
1
- > Use this snippet for keeping fallback of this interaction (where the snippet is used). So the context stays in this interaction.
2
-
3
- **Most used example: Get answer from users**
4
- - At the interaction fallback to keep users at the interaction. Bot can give help to users and keep them in interaction.
5
-
6
- **About the snippet:**
7
- - The snippet is applied whenever the user gets to this point of conversation.
8
- - Should be used in the fallback of the interaction to keep the interaction's context.
9
-
10
- Check out the [tutorial here](http://docs.wingbot.ai/context/AnswerTheQuestion/AnswerTheQuestion.html).
11
-
12
- ![keep user in interaction](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.keepInInteraction/keepInInteraction.png)
@@ -1,13 +0,0 @@
1
- > Use this snippet for keeping fallback of this interaction (where the snippet is used). So the context stays in this interaction.
2
-
3
- **Most used example: Get answer from users**
4
- - At the interaction fallback to keep users at the interaction. Bot can give help to users and keep them in interaction.
5
-
6
- **About the snippet:**
7
- - The snippet is applied whenever the user gets to this point of conversation.
8
- - Should be used in the fallback of the interaction to keep the interaction's context.
9
- - This is done just once.
10
-
11
- Check out the [tutorial here](http://docs.wingbot.ai/context/AnswerTheQuestion/AnswerTheQuestion.html).
12
-
13
- ![keep user in interaction](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.keepInInteraction/keepInInteractionJustOnce.png)
@@ -1,17 +0,0 @@
1
- > Lock users in interaction, until they reply as you wish.
2
-
3
- **Most used example: Get answer from users with the same options of answers**
4
- - At the interaction fallback to keep users at the interaction. Bot can give help to users and keep them in interaction.
5
- - This snippet keeps previous NLP handlers.
6
- > This snippet is very similar to previous snippet Keep user in this interaction (use it as a fallback)]. The difference is you don't need to set NLP handlers.
7
-
8
- **About the snippet:**
9
- - Keeps previous NLP handlers and fallback.
10
- - Where to use:
11
- - At the dialogue or global fallbacks - keep NLP handlers and fallback from previous interactions.
12
- - At the interaction fallback - keep NLP handlers and fallback from this interaction (they are used again)
13
- - The snippet is applied whenever the user gets to this point of conversation.
14
-
15
- **Take a look how to use this snippet:** [here](http://docs.wingbot.ai/context/AnswerTheQuestion/AnswerTheQuestion.html)
16
-
17
- ![keep previous handlers](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.keepPreviousHandlers/image1.gif)
@@ -1,15 +0,0 @@
1
- > Give users a chance to correct their answers (at least just once)
2
-
3
- **Most used example: Give user chance to correct answer in fallback**
4
- - At the dialogue or global fallback to keep the context of previous interaction just once. So the users can correct their reaction to chatbot's utterance.
5
-
6
- **About the snippet:**
7
- - The snippet keeps previous NLP handlers and fallback.
8
- - Where to use:
9
- - At the dialogue or global fallbacks - keep NLP handlers and fallback from a previous interaction.
10
- - At the interaction fallback - keep NLP handlers and fallback from this interaction (they are used again).
11
- - This is done just once.
12
-
13
- **Take a look how to use this snippet:** [here](http://docs.wingbot.ai/context/ChanceToCorrectAnswer/ChanceToCorrectAnswer.html)
14
-
15
- ![keep previous handlers](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.keepPreviousHandlersJustOnce/image1.png)
@@ -1,5 +0,0 @@
1
- > To be able to use Facebook's one-time notification, user has to make opt-in using a one-time notification request.
2
-
3
- More here, [at Facebook Messenger Docs](https://developers.facebook.com/docs/messenger-platform/send-messages/one-time-notification/)
4
-
5
- ![one time notification](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.oneTimeNotificationRequest/notification.png)
@@ -1 +0,0 @@
1
- > This plugin allows you to use chatGPT
@@ -1,19 +0,0 @@
1
- > One of base pillars of masterbot architecture
2
-
3
- ## Passing thread to another bot
4
-
5
- The action is determined by metadata JSON string.
6
-
7
- 1. **Pass thread with text (leave action and intent fields empty)**
8
-
9
- Let the target bot's NLP to decide.
10
-
11
- 2. **Pass thread to specific action**
12
-
13
- Target bot will response with a predefined interaction
14
-
15
- 3. **Trigger a specific intent at a target bot**
16
-
17
- Intent will be enforced at target bot
18
-
19
- ![pass thread to bot](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.passThreadToBot/passThreadToBot.png)
@@ -1,8 +0,0 @@
1
- > Breadcrumbs allows you to track some particular flow and make user able to return to previous steps in the flow.
2
-
3
- This is a example of using breadcrubms:
4
-
5
- 1. Put breadcrumbs at checkpoints - interaction, where each step begins
6
- 2. Allow user to get back to the previous step using a **Go to last breadcrumb** plugin.
7
-
8
- ![breadcrumbs](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.putABreadcrumb/breadcrumbs.png)
@@ -1 +0,0 @@
1
- > This plugin detects reqular expressions
@@ -1 +0,0 @@
1
- > This plugin has been replaced with native UI.
@@ -1 +0,0 @@
1
- > This plugin has been replaced with native UI.
@@ -1,7 +0,0 @@
1
- > This plugin allows bot to just **send no response**
2
-
3
- This is useful, when you want to override the default behavior of wingbot - because **when there is no response message in an interaction, users request will fall into a fallback.
4
-
5
- Following example shows, how to use this plugin to keep following users response without reaction. Second users attempt will be processed as usual.
6
-
7
- ![stop responding](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.stopResponding/noop.png)
@@ -1,3 +0,0 @@
1
- # Track analytic event
2
-
3
- This plugin lets you easily track any analytics informations
@@ -1,5 +0,0 @@
1
- > Just to make change a rythm of conversation.
2
-
3
- This snippet will make a small delay between two messages.
4
-
5
- ![wait](https://github.com/wingbotai/wingbot/raw/master/plugins/ai.wingbot.waitASecond/wait.png)