microsoft / botframework-sdk

Bot Framework provides the most comprehensive experience for building conversation applications.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Proactive Messages without Prior Context

Chocrates opened this issue · comments

I know this is not for asking for help, but I went the Stack Overflow route and I did not get any (correct) answers, or I am just not smart enough to put the pieces together.

I even went as far as to try to do this with the Graph API but when I got everything together to sent the message it gave me an error that it is explicitly not allowed to post messages as the bot through that API and to use the Bot Framework SDK

Scenario

I need a service to listen for a webhook from a 3rd party and then use data from that webhook to message a information to a Team Channel in Microsoft Teams.
The message needs to come from the Bot and not a User.
The message cannot be tied to any previous conversation because ideally this should create a new channel and invite users that are needed to address whatever the event from the webhook was.

This service will eventually do normal user initiated ChatOps stuff, but this first iteration seems to be very non standard.

Sample project can be found here https://github.com/Chocrates/chatops-sample

Webhook Listener

server.post('/api/proactiveMessages', async (req, res) => {
    // Route received a request to adapter for processing
    console.log('Inside proactive"')
    await myBot.teamsCreateConversation(adapter);
    res.send(200)
});

Broken Proactive Message Code

    async teamsCreateConversation(adapter) {
        const channelId = 'snip'
        const teamId = 'snip'
            
        const reference = TurnContext.getConversationReference({
            bot: {
                id: process.env.MicrosoftAppId,
                name: 'Your Bot'
            },
            channelId: channelId,
            conversation: {
                isGroup: true,
                conversationType: 'channel',
                id: `${teamId};messageid=${channelId}`
            },
            serviceUrl: 'https://smba.trafficmanager.net/amer/',
            user: {
                id: 'user-id-placeholder',
                name: 'User'
            }
        });

        await adapter.continueConversationAsync(reference, async (turnContext) => {
            await turnContext.sendActivity('Hello, this is a proactive message from the bot!');
        });

        console.log('After sending the message')
    }

The latest error I have been getting is that TypeError: claimsIdentity.getClaimValue is not a function, but basically every change I try gives me new and different errors, so something is fundamentally wrong with my understanding of the SDK.

Does anyone have any working sample code I can look at? So far everything I have found about sending proactive messages needs a conversation reference which I will not have in this scenario.

Pulling the proactive message from this sample like so

const reference = TurnContext.getConversationReference({
            bot: {
                id: '28:' + process.env.MicrosoftAppId,
                name: 'Your Bot'
            },
            channelId: channelId,
            conversation: {
                isGroup: true,
                conversationType: 'channel',
                id: `${teamId};messageid=${channelId}`
            },
            serviceUrl: 'https://smba.trafficmanager.net/amer/',
            user: {
                id: 'user-id-placeholder',
                name: 'User'
            }
        });

        await adapter.continueConversationAsync(reference, async (turnContext) => {
            await turnContext.sendActivity('Hello, this is a proactive message from the bot!');
        });

Yields the claim identity error above.

Adding some logging to the library itself, to this function in node_modules/botframework-connector/lib/auth/parameterizedBotFrameworkAuthentication.js

function getAppId(claimsIdentity) {
    const util = require('util')
    console.log(` Inside CLaims stuff: ${ util.inspect( claimsIdentity)}`)
    var _a, _b;
    // For requests from channel App Id is in Audience claim of JWT token. For emulator it is in AppId claim. For
    // unauthenticated requests we have anonymous claimsIdentity provided auth is disabled.
    // For Activities coming from Emulator AppId claim contains the Bot's AAD AppId.
    return ((_b = (_a = claimsIdentity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AudienceClaim)) !== null && _a !== void 0 ? _a : claimsIdentity.getClaimValue(authenticationConstants_1.AuthenticationConstants.AppIdClaim)) !== null && _b !== void 0 ? _b : undefined);
}

Nets this result. Clearly I am authing somehow incorrect but some of the data in there does look familiar.

{                                     
  activityId: undefined,                                    
  user: undefined,                                          
  bot: undefined,                                           
  conversation: {                                           
    isGroup: true,                                          
    conversationType: 'channel',
    id: '89e34e16-1ef0-41a3-9186-ac19de141260;messageid=19:96c3e7b1129f4f39ac7bac5c3969c334@thread.tacv2'                
  },                                                        
  channelId: '19:96c3e7b1129f4f39ac7bac5c3969c334@thread.tacv2',                                                         
  locale: undefined,                                        
  serviceUrl: 'https://smba.trafficmanager.net/amer/'
}

Printing the claim when doing a user initiated conversation nets this object.

ClaimsIdentity {                                                                              
  claims: [                                            
    {                                                  
      type: 'serviceurl',                                                                                     
      value: 'https://smba.trafficmanager.net/amer/'                                                          
    },                                                                                                        
    { type: 'nbf', value: 1716993450 },                                                                       
    { type: 'exp', value: 1716997050 },                                                                       
    { type: 'iss', value: 'https://api.botframework.com' },                                                   
    { type: 'aud', value: 'bfdecf05-af65-4061-b960-29ded0e0e4ac' }                                            
  ],                                                                                                          
  authenticationType: true                             
}