Collecting approval from multiple parties (group chat?)

This topic is the opposite from the beginner call-action component, instead of calling an external API, I want to call Botpress from outside, or connect users in the same conversation:

I’d like to implement an action, that triggers a notice to another user “APPROVER”, which he first has to approve before the action is executed. I’ll call them “ASK” and “CONFIRM” for now, and they may occur on different channels, e.g. WebChat & Email

Dream draft, fully integrated into MS Teams:
When I call ASK on the bot in it’s channel, it responds with a widget showing approval state while displaying a similar widget for my APPROVER, when he CONFIRMs with a button press, I get notified and my widget changes and I can now really go through with the action.
Or my APPROVER is invited to join the conversation (but not like HITL)…? How does Botpress even handle group chats^^?

Well with teams there are no widgets yet so this might stay a dream forever…
Blog entry calls chat widgets - integrated webviews - still a bit clunky

POC draft, without widgets - WebChat & Email:
When I ASK, an email is generated for me and sent to my APPROVER. When he clicks CONFIRM, I get notified via email (and or in chat).
Since I cannot be sure how long it may take to CONFIRM, both parties should be able to rejoin or continue the conversion via email.

More questions, please help me evaluate the feasibility of my ideas:

  • Is it easy to extend the API of the Botpress Application Server to receive and forward CONFIRM calls for different chats, for a widget or confirmation storage?
  • It would be great to be able to rejoin the chat session via email link, can I attach data, e.g. filling a Slot through the link?
  • How to best store the state of approval? Can I attach it to a conversation or do I have to build a new service for it?
  • Can I just create a token encoding all data concerning the confirmation to be easily forwarded to CONFIRM?

Behind my Botpress instance, I have a custom API proxy to access other services, but it is not exposed to the internet, that’s why I am asking here for different ways to carry/save the confirmation through/in Botpress.
I think the last question is the right direction. My APPROVER could just reply to me with the mail having signed confirm data in it, then I could paste that back into chat if it can’t be carried by link back into the conversation. If there are multiple APPROVERs I have to collect multiple tokens from them.

What do you think, am I on the right path? Do you have other ideas, easier to implement? Am I missing any pitfalls or useful building blocks? Have you already implemented a similar flow involving multiple parties, how?

1 Like

Hey @JustusNBB

My idea is the following: the bot displays a widget to the Asking user. The Asking user clicks on the widget, which in turns calls an Action that sends a link (via email) to the Approver.

That link will point back to a custom public API endpoint that you will have created using a after_server_start hook and the http.createrouterforbot() function of the SDK. Make sure to set checkAuthentication to false in the options. You can find an example here.

That link can contain a JWT token as a parameter. That JWT token can be signed using a EXPOSED_SECRET_VARIABLE=someSecretString that you control in your deployment (environment variables starting with EXPOSED_ are exposed to the Actions/Hooks runtime). The jsonwebtoken library is available from within Actions/Hooks:

function action(bp: typeof sdk, event: sdk.IO.IncomingEvent, args: any, { user, temp, session } = event.state) {
  const jwt = require('jsonwebtoken')

  const myAction = async (name, value) => {
    const jwtToken = jwt.sign('data to encrypt', process.env.EXPOSED_SECRET_VARIABLE))
  }

  return myAction(args.name, args.value)
}

When the Approver clicks on the link, it will issue a GET request to your custom API endpoint. The endpoint then receives the JWT token, and verifies the token using the EXPOSED_SECRET_VARIABLE (jwt.verify(...)). Now, you can trust that the received payload is safe.

Now, about your specific questions:

Is it easy to extend the API of the Botpress Application Server to receive and forward CONFIRM calls for different chats, for a widget or confirmation storage?
Yes, use a custom HTTP API endpoint (detailed above)

It would be great to be able to rejoin the chat session via email link, can I attach data, e.g. filling a Slot through the link?

Since you’ll be using a JWT token, you can include any data you want in the JWT payload. As for joining back the chat, Botpress was designed for 1 user - 1 bot conversations. I don’t think it’s possible for 2 users to chat at the same time with a bot. In your particular case, your custom API endpoint could redirect the Approver user to the Asking user’s conversation, but then the Approver would impersonate the Asking user, which may be a security concern.

How to best store the state of approval? Can I attach it to a conversation or do I have to build a new service for it?

You can store any data in the event.state.session variable. Bear in mind that sessions expire after a set amount of time (configurable through the Botpress config). For permanent storage, I suggest you use the KVS.

Can I just create a token encoding all data concerning the confirmation to be easily forwarded to CONFIRM?

Yes, see JWT solution detailed above.

I hope this was helpful. Have a great day!

1 Like

Thank you @spgin for references and details, this confirms that I am already on the right track!
Let’s go through some more details…

I think the APPROVER should just reply to the email (I’ll be sending it in the name of the user or with reply-to header). Then the user actually gets the link allowing him to add data from the approval to his chat conversation - no security issues because the token is not linked to the conversation, it just contains the approval for a preconfigured action, which can only be triggered by the ASKING authenticated user with approval token. Of course it would be even better if the APPROVER clicks a link, and after authentication then the signed approval (token) is generated (in another chat, or the same groupchat).
Can I reuse Botpress Socket PubSub to inform the user instanously about approval being done?

If I want the approver also to join a chat (not necessarily the same one), I need data persistence to connect between the user sessions, a shared storage like described with KVS - this is an interesting detail, is there more documentation about it (SDK docs are pretty bare), maybe some example usage?

When the user clicks on the link, it will issue a GET request to your custom API endpoint

And I just forward the user to his chat afterwards? Can I trigger an action, prefill message text, or fill a slot while redirecting via GET param?

Botpress was designed for 1 user - 1 bot conversations

How does Botpress currently handle being added into a group conversation with e.g. Telegram integration, do users share a conversation session (data) or does the bot treat them in multiple sessions in the same channel?