Open gkspranger opened 4 years ago
so a couple of ideas i have around the functionality and the implementation (<< gulp) ..
functionality :: wouldn't it be cool if i, a normal user, could create a "dialog" using commands ?? so this would be a runtime dialog vs code-base .. obviously the end result would have to be useful, and i think a multi-stepped collection of user input that is then sent off to some "external" API could be valuable .. the final "send" action might be code-based -- but the collection of that user input could be defined by users .. THE PROBLEM i see with this is would i, the user, be able to assemble a meaningful payload that i can then send off to the "external" API .. if i can't then all of this work might not be of value ..
so just guessing at a user flow ::
user: dialog --create user-info
yb: ok, let's create a dialog .. what is your 1st question ??
user: what is your name?
yb: you said "what is your name?" .. is this correct ??
user: yes
yb: ok -- saving question .. what is your next question ??
user: how old are you?
yb: you said "how old are you?" .. is this correct ??
user: no
yb: ok -- deleting question .. what is your next question ??
user: what is your age?
yb: you said "what is your age?" .. is this correct ??
user: yes
yb: ok -- saving question .. what is your next question ??
user: stop
yb: ok -- stopping the creation of questions .. the question payload will look like:
{:question1 {:text "what is your name?"
:value <tbd>}
:question2 {:text "what is your age?"
:value <tbd>}}
yb: what is your final action?
user: http post "https://example.com/api/v1/update-user-info" -d ~{payload}
ugh -- even typing that tho seems it might limit the usefulness of this tool .. i wonder if there was a well defined EDN or YAML schema, a user could show up with said schema and just post that to YB and YB would know what to do .. let's guess what that might look like in YAML ::
dialog:
questions:
- text: what is your name?
var: name
- text: what is your age?
var: age
actions:
- command: http-post
args:
url: https://example.com/api/v1/update-user-info
# the dialog_payload in this example would/could look like {"name":"Greg","age": 45}
data: {{ dialog_payload }}
headers:
token: <secret>
^^ that makes me cringe a little because of my token reference, but typically you need some kind of auth to be able to post somewhere .. maybe that could be something that could be an "admin only" capability, and the YB user would have to ask said admin to set said secret in some var that can be referenced by these actions
..
anyhoo -- onto implementation .. i was thinking of that nasty nested pseudo code example i posted before, and it made me cringe a little .. so i was thinking that any "dialog API" that would allow me to easily implement multi-methods i think would be great .. that way i could easily loop on said multi-method and my code remains nice and flat and easy to reason about ..
(defmulti collect-user-info
...
(defmethod collect-user-info "name" [dialog-data]
...
(defmethod collect-user-info "age" [dialog-data]
...
(defmethod collect-user-info "update-user-info" [dialog-data]
...
(loop [dialog-data {:command "name"}]
(if (empty? (dialog-data :command))
dialog-data
(recur (collect-user-info dialog-data))))
ok -- i promise this is my last cup of ☕ -- will stop now ..
EMAIL could be a final action for a user defined dialog ..
# do question/answer loop here
yb: Thanks for providing information related to the USER INFO questionnaire .. We appreciate your feedback ..
# email action sends to target with questionnaire data as well as Slack/adapter user data
ok -- i promise now -- no more ☕ -- last comment of the day
Thanks for kicking this off @gkspranger!
wouldn't it be cool if i, a normal user, could create a "dialog" using commands
Would be awesome. I want to explore this direction.
I'm wondering if we could utilize yb's pipeline capabilities to compose a dialog flow out of primitives.
!ask --param name .{3,} what's your name? | ask --param age \d+ hi {{name}}, how old are you? | ask --param location .+ where do you live? | render thanks! your info is: name: {{name}}, age: {{age}}, location: {{location}}
Between every ask
yb waits for user input from the user that initiated, using threads (Slack, Mattermost) where possible.
Now obviously this is linear without branching or logic. But I'm wondering if yb's pipelines should have generic logic capabilities (currently we do have an or
command but it is very simple) that would allow the construction of a tree.
Your YAML/EDN idea is interesting. Kind of reminds me of StackStorm.
typically you need some kind of auth to be able to post somewhere
if posting via a configured command, e.g. to GitHub or JIRA, the auth would already be configured on the YB. But it does bring up a good question of how to do generic secrets in YB (have thought about this a bit before). I could see using a parameterized template that consumes configured secrets without exposing them.. kind of a separate topic though.
thinking that any "dialog API" that would allow me to easily implement multi-methods
great idea if we end up wanting to bake dialogs in via code instead of configuring them at runtime. I want to push on runtime config a bit to see how far we could take it, or determine whether it's just too unwieldy.
EMAIL could be a final action for a user defined dialog
YB does have a mail
command... I haven't used it in awhile but might be fun to dust it off.
no more ☕
🤣 😂 😆 ☕
Good stuff!! 💯 Hope you refill your ☕ stores for the next round 😂
i really like the idea of using pipelines .. i can see where i would create an alias
using ask
, pipelines, and the final "action" to create runtime dialogs .. also, this is a major differentiator compared to the other bots that exist out there ..
THAT SAID -- it would be sweet if we can somehow create a cond
associated with a previous ask
response -- and then somehow land on a final action that is appropriate for dialog when considering all io
.. not exactly what that would look like right now -- but can stew on it ..
this would be really neat if i could do this (simplistic, yes, but oh-so-powerful) ::
!alias deploy-app =
ask --param app .{3,} what app would you like to deploy? |
ask --param env (dev|qa|prod) what environment do you want to deploy to? |
jenkins --job deploy_app --params "app={{app}}&env={{env}}"
a hacky example at how we might add cond
to user input
# || states a cond is coming
# | remains a normal pipeline "forward" action, meaning it will skip any "remaining" conds
# <| means go back to previous command - in this case they are all ask commands
# |> means go forward to declared "action" ::
# problem is will YB be smart enough to know if this is a command or just some text,
#. because ideally I would like the option of both
!alias deploy-app =
ask app What app do you want to deploy? ||
cond ^stop$ |> Ending "deploy-app" dialog.
cond ^..?$ An app name typically has 3 or more characters - please try again. <|
cond ^.{3,}$ |
ask env what environment do you want to deploy to? ||
cond ^stop$ |> Ending "deploy-app" dialog.
cond ^dev|qa|prod$ |
cond .+ I'm sorry, I do not recognize the {{env}} environment - please try again. <|
jenkins --job deploy_app --params "app={{app}}&env={{env}}"
as a YB dev, i would like the ability to code multi-step dialogs, so that my users can interact with YB in a "deeper" manner ..
right now, my user interactions with YB are very "shallow" -- meaning :: a command is issued (with or without args), YB does the thing, task complete .. this is great for 80% of the commands i create ..
that said, i would like for my users to have the ability to have "deeper", multi-step dialogs with YB, such that ::
IF response =~ YES; THEN do X; ELSE do Y ENDIF;
STOP
the dialogi don't expect this to be easy, and am willing to help however i can .. if i have any say on the impl details, it is that i have used both the HUBOT version of this (https://www.npmjs.com/package/hubot-conversation) and the ERRBOT version of this (https://github.com/errbotio/err-guess-a-number) -- and i much prefer the HUBOT approach ..
please forgive my pseudo code, but it would be great if the flow of the dialog could follow something like you see below .. ONE GLARING omission is being able to have nested questions based on responses .. for example ::
anyway -- just wanted to open this and get the ball rolling .. thanks !!