Hot to use channel-web API with own middleware and frontend?

Hi,

we have our own middleware and frontend which has also connectors to Rocket.Chat for example and we have a lot of selfmade outputs like a weather graphic.

Now I try to send a message with a payload to Botpress.

With the Botpress converse API it was not possible, this accepts only text.
So I did a bit reverse engineering and send my message to the channel-web API.

let msg = {
    "type": "text",
    "text": "hi"
};

axios({
    method: 'post',
    headers: {"Content-Type": "application/json"},
    url: botpressURL+'/api/v1/bots/mybot-dev/mod/channel-web/messages/'+token,
    data: msg
}).then(resp => {
   console.log("botpress Response Data",resp.data);
})
.catch(function (error) {
    console.log(error);
});

That works fine and I see my message in the HITL module as well, but I receive only an “ok” as response and not the answer of the bot.

Could someone help me with that?

thanks in advance
Frank

I found the answer on my own. I will post it here, so maybe it will help other as well:

In my example I used for the websocket connection socket.io-client in a nodejs middleware:

Socket Connection:

let connectionString = this.host+'/guest';
          
        const socket = io.connect(connectionString,{
            query: {
                visitorId: token
            },
            path: '/socket.io',
            transports:['websocket', 'polling'],
            rejectUnauthorized: false,
            reconnect: true
        });
       socket.on('event',(msg)=>{
                console.log('got event',msg);        
       });

Post a message:

let msg = JSON.stringify({
            'type' : 'text',
            'text' : 'hi'
});

axios({
    method: 'post',
    headers: {"Content-Type": "application/json"},
    url: this.host+'/api/v1/bots/'+botName+'/mod/channel-web/messages/'+token,
    data: msg
})

Token must be the same for the socket connection and each time you send a message. I my case I generate the token randomly before making the connection.

The bot answers with something like that:

{
   name: 'guest.webchat.message',
   data: {
     id: 'b0d11746-63db-474d-886e-541219b2707a',
     conversationId: '174',
     incomingEventId: '159915021162482020',
     full_name: 'Bot',
     message_type: 'text',
     message_text: 'A bot could ask questions that are similar but have different meanings. To differentiate between the meanings of these questions, we use Contexts.',
     payload: {
       type: 'text',
       text: 'A bot could ask questions that are similar but have different meanings. To differentiate between the meanings of these questions, we use Contexts.'
     },
     sent_on: '2020-09-03T16:23:32.214Z',
     __room: 'visitor:Z35NP9Top9Ag6lWciFI6DW2Z28dihqOh'
   }
 }

Hi, @ FrankDaze - firstly, thank You a lot for sharing the solution You found as we are currently struggling with the same situation - self-made frontend for which we would like to receive replies from bot in a form of a bare JSON. Our attempts at opening a websocket connection currently ends up with botpress closing the connection after a few seconds without giving a reason for that.

May i ask, where did You put the code which connects to botpress socket.io /guest endpoint? Was it in a botpress middleware (using Your own custom module), or - a middleware from a node.js front-end client code of Your own?

Best regards,
Artūrs

Moreover, i would gladly stay in touch if You happen to stumble upon some other obstacles on the way of implementing You solution as i am likely to do a lot of deep diving in botpress source code in the following weeks an may be can help with one aspect or another in integrating botpress chat with a custom front end - feel free to drop me a line at arturs.gailitis@gmail.com.

Hi,

I had the same socket closing problem issue until I started using socket.io-client whith other socket tools it was easy to connect, but then the connection closed all the time.

The url is like “https://www.mysuperbot/guest” , the “/socket.io” is the namespace which I declared as “path: ‘/socket.io’” in the connection parameters.

Then I had to find out hot to give my visitor ID to the socket connection. You can add it as querystring to “/guest?visitorID=myuniqueid” or you add it as parameter:

query: {
                visitorId: token
            },

I’m not using a self made botpress module, I just use my own nodejs middleware.
In my middleware I use a socket.io server connection to the chat frontend and a socket.io-client connection to botpress.

Thanks, @FrankDaze, for Your follow-up - guided by this post, we were able to create a socket.io connection from our frontend side to botpress and received successfully message from bot. It saved a day, and not one to us :slight_smile:

May i clarify a bit on the middleware You mentioned - did i get it right, that the middleware is functioning a bit like a proxy - maintaining one socket.io channel with Your bot frontend software (passing on client messages to botpress, and passing back botpress replies / messages, received from another socket.io connection, which is maintained between the middleware module and botpress)? So, for the frontend side it looks like a single, bi-directional socket.io channel where messages are both received and sent, and - middleware translates client messages to POST requests to botpress channel-web messages API endpoint, and - passes on bot reactions to frontend side?

All the best for today,

Artūrs

I hope this diagram will help you to understand the middleware. But yes it’s like a proxy.
Middleware is both server and client. Server for the frontend connection and client for the Botpress connection.

@FrankDaze - a single picture is worth a thousand words as the saying goes :slight_smile: Thank You again for sharing Your solution and taking extra time for elaborating on details - it seems that our team are all set now and is able to move forward again after being blocked for some time thanks to Your post and ongoing support!

@arcijsg I know what you mean, we had the same problem and had to figure this out on our own. :slight_smile: