首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在node.js & Bot框架V4.4中调试文本日志中间件

在node.js & Bot框架V4.4中调试文本日志中间件
EN

Stack Overflow用户
提问于 2019-07-27 19:06:10
回答 1查看 753关注 0票数 0

我刚刚在聊天机器人中添加了我的第一个中间件,用于记录记录,方法是遵循这个堆栈溢出响应这里

但是,该实现会弹出一些错误,例如:

代码语言:javascript
运行
复制
[onTurnError]: TypeError: this.logger.log is not a function
[onTurnError]: TypeError: Cannot read property 'role' of undefined
BotFrameworkAdapter.processActivity(): 500 ERROR - Error: BotFrameworkAdapter.sendActivity(): missing conversation id.

这些错误在我初始化会话后直接抛出,用户发送第一个"GET_STARTED“消息。

成绩单记录工作良好,每一个记录(短!)对话被上传到我的Azure Blob存储库。

然而,由于这是我第一次使用中间件,我不知道如何调试这些错误并使聊天机器人按预期工作。

用于记录记录的onTurn函数与链接示例非常类似,我刚刚在最后添加了一个await next();

代码语言:javascript
运行
复制
this.onTurn(async (turnContext, next) => {
// See https://aka.ms/about-bot-activity-message to learn more about the message and other activity types.
if (turnContext.activity.type === ActivityTypes.Message) {
   if (turnContext.activity.text === '!history') {
      // Retrieve the activities from the Transcript (blob store) and send them over to the channel when a request to upload history arrives. This could be an event or a special message activity as above.
      // Create the connector client to send transcript activities
      let connector = turnContext.adapter.createConnectorClient(turnContext.activity.serviceUrl);

      // Get all the message type activities from the Transcript.
      let continuationToken = '';
      var count = 0;

      // WebChat and Emulator require modifying the activity.Id to display the same activity again within the same chat window
      let updateActivities = [ 'webchat', 'emulator', 'directline' ].includes(turnContext.activity.channelId);
      let incrementId = 0;
      if (updateActivities && turnContext.activity.id.includes('|')) {
                    incrementId = parseInt(turnContext.activity.id.split('|')[1]) || 0;
      } do {
      // Transcript activities are retrieved in pages.  When the continuationToken is null, there are no more activities to be retrieved for this conversation.
      var pagedTranscript = await this.transcriptStore.getTranscriptActivities(turnContext.activity.channelId, turnContext.activity.conversation.id, continuationToken);
      let activities = pagedTranscript.items.filter(item => item.type === ActivityTypes.Message);

         if (updateActivities) {
            activities.forEach(function(a) {
            incrementId++;
            a.id = `${ turnContext.activity.conversation.id }|${ incrementId.toString().padStart(7, '0') }`;
            a.timestamp = new Date().toISOString();
            a.channelData = []; // WebChat uses ChannelData for id comparisons, so we clear it here
            a.replyToId = '';
          });
         }

         // DirectLine only allows the upload of at most 500 activities at a time. The limit of 1500 below is arbitrary and up to the Bot author to decide.
         count += activities.length;
         if (activities.length > 500 || count > 1500) {
            throw new InvalidOperationException('Attempt to upload too many activities');
         }

         await connector.conversations.sendConversationHistory(turnContext.activity.conversation.id, { activities });
                    continuationToken = pagedTranscript.continuationToken;
         }
         while (continuationToken != null);

         console.log("Transcript sent");
         } else {
            // Echo back to the user whatever they typed.
            console.log(`User sent: ${ turnContext.activity.text }\n`);
         }
         } else if (turnContext.activity.type === ActivityTypes.ConversationUpdate) {
            // Send greeting when users are added to the conversation.
            console.log('Welcome Message');
         } else {
            // Generic message for all other activities
            console.log(`[${ turnContext.activity.type } event detected]`);
         }
     await next();
 });

下面也是我的onMessage函数:

代码语言:javascript
运行
复制
this.onMessage(async (context, next) => {
     await sendTyping(context);
     this.logger.log('Processing a Message Activity');
     // await logMessageText(storageBlob, context);

     const qnaResults = await this.qnaMaker.getAnswers(context);

     // Show choices if the Facebook Payload from ChannelData is not handled
     if (!await fbBot.processFacebookPayload(context, context.activity.channelData)) {
         // detect if Facebook Messenger is the channel being used
         if (context.activity.channelId === 'facebook') {
             let facebookPayload = context.activity.channelData;
             let fbSender = facebookPayload.sender;
             var fbPSID = fbSender.id;
             if (qnaResults[0]) {
                 const { answer, context: { prompts } } = qnaResults[0];

                 // set a variable for the prompts array from QnA
                 var qnaPrompts = null;
                 if (qnaResults[0].context != null) {
                     qnaPrompts = qnaResults[0].context.prompts;
                 }

                 // map the prompts to the required format for quick_replies channelData
                 var qnaPromptsArray = qnaPrompts.map(obj => {
                     return { content_type: 'text', title: obj.displayText, payload: obj.displayText };
                 });

                 let reply;
                 if (prompts.length) {
                     const quickReply = {
                         channelData: {
                         text: answer,
                         quick_replies: qnaPromptsArray
                         }
                     };
                     reply = quickReply;
                 } else {
                     reply = {
                         channelData: {
                         text: answer
                         }
                     };
                 }

                 await context.sendActivity(reply);

             // If no answers were returned from QnA Maker, reply with help.
             } else {
                 let errorCardFB = await fbCards.getErrorCardFB(fbPSID);
                 await context.sendActivity(errorCardFB);
             }
         } else {
         // If an answer was received from QnA Maker, send the answer back to the user.
             if (qnaResults[0]) {
                 const { answer, context: { prompts } } = qnaResults[0];

                 let reply;
                 if (prompts.length) {
                     const card = {
                         'type': 'AdaptiveCard',
                         'body': [
                             {
                             'type': 'TextBlock',
                             'text': answer,
                              wrap: true
                             }
                         ],
                         'actions': prompts.map(({ displayText }) => ({ type: 'Action.Submit', title: displayText, data: displayText })),
                         '$schema': 'http://adaptivecards.io/schemas/adaptive-card.json',
                         'version': '1.1'
                     };

                 reply = { attachments: [CardFactory.adaptiveCard(card)] };
                 } else {
                     reply = answer;
                 }

                 await context.sendActivity(reply);

             // If no answers were returned from QnA Maker, reply with help.
             } else {
                 await context.sendActivity('I\'m sorry, I don\'t have an answer for that. Please ask me something else, such as: \n\n "What Is Mental Health?" \n\n "What Is NeuroDiversity" \n\n "Help"');
             }
         }
     }

     // By calling next() you ensure that the next BotHandler is run.
     await next();
 });

由于我不知道如何调试中间件,也不知道如何使用Facebook作为聊天机器人通道,所以我不确定是什么导致了这些错误。

谁能给我指明正确的方向?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-30 23:50:01

如果您打算将文本记录器用作中间件,则需要在index.js文件中实现它。中间件连接到适配器上,而不存在于“对话框”代码中。

您的代码应该如下所示:

代码语言:javascript
运行
复制
const {
  [...],
  ConsoleTranscriptLogger,
  TranscriptLoggerMiddleware,
  [...]
} = require( 'botbuilder' );

// The bot.
const { WelcomeBot } = require( './bots/welcomeBot' );
const { MainDialog } = require( './dialogs/mainDialog' );

const ENV_FILE = path.join( __dirname, '.env' );
require( 'dotenv' ).config( { path: ENV_FILE } );

// Create HTTP server
let server = restify.createServer();
server.listen( process.env.port || process.env.PORT || 3978, function () {
  console.log( `\n${ server.name } listening to ${ server.url }` );
} );

// configure middleware
const logstore = new ConsoleTranscriptLogger();
const logActivity = new TranscriptLoggerMiddleware( logstore );
[...other middleware...]

// Create adapter.
const adapter = new BotFrameworkAdapter( {
  appId: process.env.MicrosoftAppId,
  appPassword: process.env.MicrosoftAppPassword
} )
  .use( logActivity );

[...other bot code...]

在这一点上,你应该可以走了。记录器将解析通过适配器传递的每条消息,并在控制台中呈现它。

您可以阅读有关中间件这里的更多信息。

希望得到帮助!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57235252

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档