Search code examples
javascriptbotframeworkrestify

Access specific chat via restify API having conversationId


I'm having the issue finding a way to access the Specific Chat for Bot to process from outside API call in order to integrate with internal messaging systems for operators to kick in the conversation.

Generally my idea is: if user wants to talk with human - he triggers the flow (in CustomBot.js for example) and initiates the communication. However in order to send messages from different system - I need to access this very specific user & chat via outside API call to route the message to correct user.

So I'm getting the conversationId from the context of the bot, but I need the handle to find a way to get the very same context via restift API.

I'd like to write smth like that:

server.post('/api/route_messages', (req, res) => {
    context = adapter.getContextById(req.conversationId)
    context.sendActivity(req.message)
})

Unfortunatelly I can't find a proper method like "adapter.getContextById".

Can you advice a way to do so?

Thank you


Solution

  • If you want to expose an API for sending messages to specific conversation from external services , you can use a way juts like notify/proactive message to do it . This is the official demo for it .But if you want to send messages to a specific conversation , you should do some modifies: replace the content in index.js with code below :

    const path = require('path');
    const restify = require('restify');
    const restifyBodyParser = require('restify-plugins').bodyParser;
    // Import required bot services. See https://aka.ms/bot-services to learn more about the different parts of a bot.
    const { BotFrameworkAdapter } = require('botbuilder');
    
    // This bot's main dialog.
    const { ProactiveBot } = require('./bots/proactiveBot');
    
    // Note: Ensure you have a .env file and include the MicrosoftAppId and MicrosoftAppPassword.
    const ENV_FILE = path.join(__dirname, '.env');
    require('dotenv').config({ path: ENV_FILE });
    
    // Create adapter.
    // See https://aka.ms/about-bot-adapter to learn more about adapters.
    const adapter = new BotFrameworkAdapter({
        appId: process.env.MicrosoftAppId,
        appPassword: process.env.MicrosoftAppPassword
    });
    
    // Catch-all for errors.
    adapter.onTurnError = async (context, error) => {
        // This check writes out errors to console log
        // NOTE: In production environment, you should consider logging this to Azure
        //       application insights.
        console.error(`\n [onTurnError]: ${ error }`);
        // Send a message to the user
        await context.sendActivity(`Oops. Something went wrong!`);
    };
    
    // Create the main dialog.
    const conversationReferences = {};
    const bot = new ProactiveBot(conversationReferences);
    
    // Create HTTP server.
    const server = restify.createServer();
    server.use(restifyBodyParser());
    
    server.listen(process.env.port || process.env.PORT || 3978, function() {
        console.log(`\n${ server.name } listening to ${ server.url }`);
        console.log(`\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator`);
    });
    // Listen for incoming activities and route them to your bot main dialog.
    server.post('/api/messages', (req, res) => {
        adapter.processActivity(req, res, async (turnContext) => {
            // route to main dialog.
            await bot.run(turnContext);
        });
    });
    
    // Listen for incoming notifications and send proactive messages to users.
    server.post('/api/notify', async (req, res) => {
        const conversationId = req.body.conversationId;
        const message = req.body.message;
    
        for (const conversationReference of Object.values(conversationReferences)) {
            if (conversationReference.conversation.id === conversationId) {
                await adapter.continueConversation(conversationReference, async turnContext => {
                    await turnContext.sendActivity(message);
                });
            }
        }
    
        res.setHeader('Content-Type', 'text/html');
        res.writeHead(200);
        res.write('<html><body><h1>Proactive messages have been sent.</h1></body></html>');
        res.end();
    });
    

    Run the demo and post a message by postman or restclient as below : enter image description here

    As you can see I opened two conversations but only the conversation I specified received the message : enter image description here

    This is a sample demo only , you can modify the request and logic based on your won requirement such as changing the url as /api/route_messages.

    Of course pls mark me if it is helpful : )