scrapinghub / slackbot

A chat bot for Slack (https://slack.com).

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bot conversation with user

forgettableEgg opened this issue · comments

commented

I am looking to see if it is possible to have a bot have a conversation with the user. it would start with a respond_to and then the bot would ask a question the user would respond and so forth until all questions are answered. I don't want to have separate functions for responding to "yes" or "no" since they can be said normally and it would allow users to skip certain parts of the conversation. I would prefer it to be part of the initial "help me? " prompt. Is this possible? An example below...

user: "Help Me?"
bot: "What do you need help with 1,2,3,4, or 5?
user: "3"
bot" "Are you sure you need help with 3?"
user: yes
.....

I wrote a library to do this but it needs some polish and a little help from slackbot itself if I'm going to release it. Good idea though, it's a pretty useful use case.

+1 for this type of "chat session" concept. A very basic implementation can be a list of questions the bot can ask the user and the user need to answer.

The hard part I see is the bot need to maintain a tuple of (user, channel/group/DM, current_step) in memory, and use that to decide what the bot should do next when receiving user input.

For more advanced session support, we can support conditional execution, e.g. one of question Q2/Q3 is asked/skipped based on the answer from question Q1.

It would be ideal if it's implemented via plugin. And add ACL to it, so the ones that can add predefine question are only the bot admins.

Commands like:

Adding new question

User: !kb add-q admin-test-credentials
Bot: Question admin-test-credentials, added

User: !kb list-q
Bot: Here are the listed questions I know the answers.
+-----------------------------+
+ ID    |      Question   +
+-----------------------------+
+ 1     | admin-test...   +
+-----------------------------+

User: !kb add-a admin-test-credentials "admin-user:passwordhere"
Bot: Answer for admin-test-credntials, added

Unauth-User:!kb add-q sample-note-for-all
Bot: I only serve my master! Be a bot_admin so I can serve you...

Asking question to the bot.

User: Help me?
Bot: What can I help you with? 1, 2, 3, 4 or 5?
User: 1
Bot: admin-test-credential is admin-user:passwordhere

NOTE: It's ideal to add questions and answers via PM. And show what's been added either via PM or Channel. This might be possible via SQLite.

Hi @upbeta01, what you're suggesting could be written in slackbot today without any kind of conversation module. Python has sqlite built in. Storing and retrieving data within a plugin should be pretty easy.

As for permissions, you can examine the sender in the message object passed in. I use a decorator that checks to see if the user is an authorized user by comparing the user ID to a list.

The idea behind this bug is to have a conversation where each successive message maintains some state of the conversation. In other words, if you do something like:

user: @bot serious command
bot: are you sure?
user: yes
bot: executing serious command

With a conversation module, the bot should maintain some state about the first thing the user said. The user's next reply would come into a function with context set by the previous message. The bot would need to understand that user saying yes is different from user2 saying yes since user was the one that initiated the conversation.

+1 on the direct message - what's the status?

I started some code to support this. It's in a branch at the moment because I wanted to get some feedback on the design. First, you can see how a plugin author would implement this in a plugin at https://github.com/jtatum/slackbot/blob/eb9cd906d6016799cc6621186421dd7c74546c41/slackbot/plugins/state.py

Here's a conversation:

user: create widget
bot: How many widget(s) would you like to create?
user: 3
bot: Making 3 widget(s), are you sure? (yes/no)
user: yes
bot: Creating 3 widget(s)!

Each time new_state() is called or the message matches any state action, any previous state is discarded:

user: create widget
bot: How many widget(s) would you like to create?
user: 2
bot: Making 2 widget(s), are you sure? (yes/no)
user: create widget
bot: How many widget(s) would you like to create?
user: 3
bot: Making 3 widget(s), are you sure? (yes/no)
user: 4
bot: <displays unknown_response message>
user: yes
bot: Creating 3 widget(s)!
user: yes
bot: <displays unknown_response message>
user: no
bot: <displays unknown_response message>

State has a timeout, which defaults to 5 minutes. If the user tries to perform a state action after this amount of time, they'll get an error. (Should it have a timeout? Is that timeout too long/short? Should you be able to disable the timeout?)

State is tied to a specific user in a specific channel. You can't start a conversation in a channel/DM and continue it in a second channel/DM. Additionally, since each call to new_state() discards previous state, a user can only have one conversation in a channel. Invoking another command that calls new_state will abort the previous conversation. You can, however, start two distinct conversations in two distinct channels. (Are these limitations sound? Is any of this behavior undesirable?)

How does the API look? Any comments/suggestions welcome.

Timeout should be configurable. If the new conversation overrides the old, is the user informed of the override? Or is it just logged somewhere? For what you're doing, looks good.

I've been working on this functionality as well. At the present time, I've added a helpfile.txt file that is read in and then presented to the channel to assist people with the commands it can run.

For example:

user: help
bot: sends a snip-it with the help file for users to see examples and know how to interact with bot commands

I'm really interested in a means of being able to lock down who can speak with the bot. I'm using saltstack as an orchestration piece and have written plugins to interface with remediating events. I'm really looking at a means to parse additional slack-based alerts to have it fully remediate and validate things are working.

@jeffbildz or @jtatum

Has anyone got a working sample besides the widget code?

Also can someone explain the subtle difference between listen_to vs. repsond_to - I don't don't see how listen_to is even necessary when you can always use respond_to ? I'm trying to create conversations based on finding key words/phrases in the message.body["text"] but listen_to nor respond_to are able to catch key words within a multiline message, it always has to be the exact command.

Appreciate the clarification / update if any.

is it possible to use message threading concept to achieve ?

@nafets33 in the testing I've done, I've only been able to get it to respond when speaking directly to the bot, or by using @botName to ask questions in a channel. Given slack's reliability, I've moved away from having the bot auto remediate, unless told to do so :) . Happy to answer any additional questions.