Moblize IT
Moblize IT

Reputation: 1328

microsoft bots to teams using nodejs fails with missing activityid when updating the same activity

My code has a simple card carousel which has action button like below:


 actions = [
        {
            "type": "Action.Submit",
            "title": "Qualify",
            "data": { "action" : "qualify_lead" }
        },
        {
            "type": "Action.OpenUrl",
            "title": "Retire",
            "url": "{viewUrl}"
        },
        {
            "type": "Action.ShowCard",
            "title": "Add Note",
            "card":   this.noteCard(item.LeadId, "leads")
        }
       ]

I am having a method to handle qualify_lead action like below

async qualifyLead(context:any){
        console.log("in qualifyLead:" + JSON.stringify(context.activity))
        await context.updateActivity(this.successCard('Lead is qualified'))
    }

All I am doing on purpose is to replace entire carousel with a simple text message. But it fails with error:

Error: BotFrameworkAdapter.updateActivity(): missing activity.id

Where do i get this ?

I am using google firebase for this and the wrapper code is like below

const {
    TurnContext,
    TeamsActivityHandler,
    CardFactory,
    AttachmentLayoutTypes,
    ActionTypes
} = require('botbuilder');

class TeamsConversationBot extends TeamsActivityHandler {
    constructor() {
        super();
        this.leadState = 
          this.conversationState.createProperty('leadCarouselState');

        this.onMessage(async (context:any, next:any) => {
            TurnContext.removeRecipientMention(context.activity);
            let msg = context.activity.text
            const action = context.activity.value
            let objNum = ''
            let keyword = ''


            if(msg === undefined && action === undefined)
                msg  = 'help'
            else if(msg !== undefined){
                msg = msg.trim().toLowerCase()
                if(msg.indexOf("help") > -1)
                    msg = 'help'
                else{

                   if(msg.startsWith('lead')){

                        msg = 'lead'
                    } 
                }
            }

            switch (msg) {
                case 'lead':
                        await this.lead(context, userKey, platform)
                        break;
                case 'qualify_lead':
                        await this.qualifyLead(context)
                        break;
            }
            await next();
        });
    }

Upvotes: 0

Views: 747

Answers (2)

Kyle Delaney
Kyle Delaney

Reputation: 12264

As I explained in my answer to your other question, you need to save the activity ID in bot state and then apply it to the update that you're sending. The Bot Framework can't update an activity unless you tell it which activity to update, and you do that using an activity ID.

This was the part that saves the ID:

const dict = await this.carouselState.get(turnContext, {});

dict[batchId] = {
    [KEYACTIVITYID]: response.id,
    [KEYLEADS]: leads
};

And this was the part that applies it to the updated activity:

            const update = this.createCarousel(batchId, leads);
            update.id = info[KEYACTIVITYID];

Upvotes: 1

Hilton Giesenow
Hilton Giesenow

Reputation: 10804

I'm not sure exactly what this.successCard('Lead is qualified') does, but presumably it returns an Activity. To my knowledge, in order for this Activity to replace another one, you need to set it's Id property to match the previous message. That means that, when you send the previous message (i.e. the card), you need to capture the reference that's returned from the send method on the context (e.g. into bot state), and then use it for this new activity.

Upvotes: 1

Related Questions