botpress / v12

Botpress OSS – v12
https://v12.botpress.com
GNU Affero General Public License v3.0
83 stars 91 forks source link

Event properties in renderer #358

Closed phgimenez closed 6 years ago

phgimenez commented 6 years ago

Make sure these checkboxes are checked before raising an issue, thank you!

Please also fill in these fields:


Botpress version: 10.24.4

Channels: web, messenger

Hi,

I would like to use event.nlu and the builtin actions (through event.bp) inside a renderer. Is there any reason why this information is filtered out from the event before sending it to the renderer?

Here´s extract from sendContent in renderers/index.js (lines 151-158):

const fullContext = Object.assign(initialData,{ user: incomingEvent.user, event: _.pick(incomingEvent, ['raw', 'text', 'type', 'platform', 'user'])}, additionalData )

Could those 2 properties (nlu and bp) be included? Or the entire incomingEvent?

epaminond commented 6 years ago

@slvnperron, @emirotin , do you think it makes sense to remove that restriction?

emirotin commented 6 years ago

I have no opinion, would like to hear Sylvain as he's the author of that code

slvnperron commented 6 years ago

@phgimenez We removed those properties to prevent people from misusing the renderers. What is your use case for needing those?

phgimenez commented 6 years ago

@slvnperron thanks for your answers The three following use cases are in the context where I have a renderer which calls an external API based on some parameters set in the content form and shows a carousel to the user.

1) I'm using NLU results as parameters to an external API call inside the renderer but I solved that using an action that copies NLU entities as state properties. In this case, maybe it´s cleaner this way.

2) I would like to save in a user conversation variable which contents I have already shown to the user, so the next time he pass by that step I won´t repeat them.

3) Finally if there´s an error calling the external API (let´s say it isn´t available by some reason), I would like to save somewhere the error status to change the flow in the next steps.

slvnperron commented 6 years ago

@phgimenez makes much more sense to me now. I think all these things would be solved if you had access to the conversation stateId (and the State API via the global bp instance) inside the renderer, right? This way you could read and save the state and take appropriate actions in the flow.

phgimenez commented 6 years ago

Yes. I guess that would be enough.

Thanks!

epaminond commented 6 years ago

@phgimenez , actually state is already available in your renderers as data.state. You can check an example of usage at https://botpress.io/docs/latest/recipes/i18n/.

Would it resolve your issue?

phgimenez commented 6 years ago

@epaminond But the data.state in the renderer is a copy for readonly use. If I write a new property to the state there, like for example "data.state = {...data.state, modifiedState: true};", it isn´t saved.

epaminond commented 6 years ago

@phgimenez , yes, state is immutable and you have to setState something like this:

await bp.dialogEngine.stateManager.setState(data.state._stateId, { ...data.state, modifiedState: true })
phgimenez commented 6 years ago

@epaminond

Thanks! But how can I import 'bp' inside a renderer? Using a require? Is that OK? 'data.event.bp' is filtered out before calling the renderer.

epaminond commented 6 years ago

@phgimenez , as a workaround you could pass it from action given you are triggering event.reply from actions. Otherwise I don't see any options.

@slvnperron , do you think we should make bp available at renderers or even pass the original event there for this case?

slvnperron commented 6 years ago

@epaminond @phgimenez Renderers shouldn't mutate the state, this is the anti-pattern that we're trying to avoid here. Actions should be used to mutate the state (even if just conditionally), and renderers consume the state to render to the different platforms (but it's important they don't introduce any side-effects).

In your scenario, I think what you are looking for is an action which alters the state and even potentially calls the renderers itself with custom data (though the event.reply method).

Does that make sense?

phgimenez commented 6 years ago

@epaminond @slvnperron Yes. I understand the pattern. My main problem here is that I have a lot of parameters for my API call. When I'm using Renderers Forms I have a lot of flexibility and user (flow designer) friendliness. If I switch to an Action and I call event.reply at the end I loose that since Actions Forms have only a key-value map for parameters (even using JSDoc in my actions to autocomplete fields and default values).

It would be really great if the Actions could have a content as input. In example I create a content-type called "My API Parameters" and then a content of that type called "My API Parameters Instance" and then use it as a parameter to my Action.

epaminond commented 6 years ago

@phgimenez , you aren't forced to use event.reply in action. But you can use actions to modify state and use modified state in renderers (or other places).

It would be really great if the Actions could have a content as input. In example I create a content-type called "My API Parameters" and then a content of that type called "My API Parameters Instance" and then use it as a parameter to my Action.

What do you mean by having content as input? Is it that you want to be able send custom content-types? But that's possible like this: event.reply('#my_api_parameters', { someParam: 'some value' })

phgimenez commented 6 years ago

In the Flow Designer, selecting a Node and choosing "Execute Code" you can see your Actions. When you select one, it gets the parameters info from JSDocs and auto fills names and default values. There it would be great to have one of your own contents as Input for your action. Maybe specifying content-type in the JSDocs and showing a combox in the UI with the contents of that content-type.

2018-08-13 1:59 GMT-03:00 Alex Pletnov notifications@github.com:

@phgimenez https://github.com/phgimenez , you aren't forced to use event.reply in action. But you can use actions to modify state and use modified state in renderers (or other places).

It would be really great if the Actions could have a content as input. In example I create a content-type called "My API Parameters" and then a content of that type called "My API Parameters Instance" and then use it as a parameter to my Action.

What do you mean by having content as input? Is it that you want to be able send custom content-types? But that's possible like this: event.reply('#my_api_parameters', { someParam: 'some value' })

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/botpress/v12/issues/358, or mute the thread https://github.com/notifications/unsubscribe-auth/AA1XSgsmelmvAH3nqhcx8dAOKkB-ti3jks5uQQejgaJpZM4VZYa1 .

--

Pablo Hernán Gimenez

CBO

Cel: +54 911 5862 6251

Email: pablo.gimenez@e-saurio.com

http://www.e-saurio.com/

Este correo electrónico (incluyendo cualquier archivo adjunto) es estrictamente confidencial y está destinado exclusivamente a su destinatario original. Si usted no es el destinatario, no debe revelar, copiar, o tomar cualquier otra acción sobre este mensaje.

Si usted ha recibido este mensaje por error, por favor notifique al remitente inmediatamente y elimine todas las copias.

This Email (including any attachments) is strictly confidential and intended solely for the addressee. If you are not the intended addressee, you must not disclose, copy, or take any action on account of this message. If you have received this message in error, please notify the sender immediately and delete all copies.

epaminond commented 6 years ago

@phgimenez , for now actions only support strings as inputs. Are you suggesting to support other types? Like which?

Since this isn't related to original request, closing this for now.

ThiliSew commented 5 years ago

Hello, I’m new to the botpress and I need to develop a product. I have to get data from the JSON file and show it in the chat. I’m in trouble to access data using the skill API call feature. I’m thankful if anyone can explain the process in detail. In my product, I cannot pass the parameters. Additionally, I cant understand how to do an auth request from API and get a token as a response.

Thank You.