上一篇文章讲了activity处理的流程,我们bot的核心处理逻辑放在ActivityHandler的子类里,通过重载OnMessageActivityAsync()方法来实现。

这篇文章我来讲一下对于Teams的bot来说,整个处理的逻辑会有哪些不同点。

通过之前的文章,大家应该已经知道,Teams bot是Azure bot service支持的众多bot聊天平台里的一种channel(注意:这里的channel指bot service里的channel,和Teams里的channel是完全不同的概念)。但是Teams实际上提供了很多特有的事件和动作。使用bot sdk的通用模型,我们当然可以处理这些事情,但是Teams作为微软的主打产品,微软的bot sdk当然要为它提供更多的开发便利性。

SDK提供了一个针对Teams的ActivityHandler。这个handler有下面这些特殊的ConversationUpdateActivity的处理函数

事件 函数 说明
channelCreated OnTeamsChannelCreatedAsync 当Teams的channel被创建
channelDeleted OnTeamsChannelDeletedAsync 当Teams的channel被删除
channelRenamed OnTeamsChannelRenamedAsync 当Teams的channel被重命名
teamRenamed OnTeamsTeamRenamedAsync 当Teams的一个team被重命名
MembersAdded OnTeamsMembersAddedAsync 当Teams的一个team中有新用户加入
MembersRemoved OnTeamsMembersRemovedAsync 当Teams的一个team中有用户被移除

除了ConversationUpdateActivity这些Teams的特殊事件,handler还提供了一些Teams特有的invoke动作的处理

Invoke类型 函数 说明
CardAction.Invoke OnTeamsCardActionInvokeAsync 关于卡片的动作,比如卡片上一个按钮被点击了
fileConsent/invoke OnTeamsFileConsentAcceptAsync 用户同意了上传文件
fileConsent/invoke OnTeamsFileConsentAsync 用户要上传文件.
fileConsent/invoke OnTeamsFileConsentDeclineAsync 用户拒绝了上传文件.
actionableMessage/executeAction OnTeamsO365ConnectorCardActionAsync O365连接器的卡片动作
signin/verifyState OnTeamsSigninVerifyStateAsync 登入验证状态
task/fetch OnTeamsTaskModuleFetchAsync Teams的Task Module的获取
task/submit OnTeamsTaskModuleSubmitAsync Teams的Task Module的提交

上面表格中的OnTeamsFileConsentAsync实际上是OnTeamsFileConsentAcceptAsyncOnTeamsFileConsentDeclineAsync的一个综合处理,你可以重载OnTeamsFileConsentAsync,或者分别重载 accept 和 decline 函数。下面的sdk代码可以让你有直观的了解

protected virtual async Task<InvokeResponse> OnTeamsFileConsentAsync(ITurnContext<IInvokeActivity> turnContext, FileConsentCardResponse fileConsentCardResponse, CancellationToken cancellationToken)
{switch (fileConsentCardResponse.Action){case "accept":await OnTeamsFileConsentAcceptAsync(turnContext, fileConsentCardResponse, cancellationToken).ConfigureAwait(false);return CreateInvokeResponse();case "decline":await OnTeamsFileConsentDeclineAsync(turnContext, fileConsentCardResponse, cancellationToken).ConfigureAwait(false);return CreateInvokeResponse();default:throw new InvokeResponseException(HttpStatusCode.BadRequest, $"{fileConsentCardResponse.Action} is not a supported Action.");}
}

对于喜欢把问题研究透彻的朋友可能会问,Teams的ActivityHandler到底是怎么处理的?让我们跳入sdk源代码一探究竟。

public class TeamsActivityHandler : ActivityHandler
{protected override async Task<InvokeResponse> OnInvokeActivityAsync(ITurnContext<IInvokeActivity> turnContext, CancellationToken cancellationToken){...switch (turnContext.Activity.Name){case "fileConsent/invoke":return await OnTeamsFileConsentAsync(turnContext, SafeCast<FileConsentCardResponse>(turnContext.Activity.Value), cancellationToken).ConfigureAwait(false);case "task/fetch":return CreateInvokeResponse(await OnTeamsTaskModuleFetchAsync(turnContext, SafeCast<TaskModuleRequest>(turnContext.Activity.Value), cancellationToken).ConfigureAwait(false));case "task/submit":return CreateInvokeResponse(await OnTeamsTaskModuleSubmitAsync(turnContext, SafeCast<TaskModuleRequest>(turnContext.Activity.Value), cancellationToken).ConfigureAwait(false));......default:return await base.OnInvokeActivityAsync(turnContext, cancellationToken).ConfigureAwait(false);}...}protected override Task OnConversationUpdateActivityAsync(ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken){...switch (channelData.EventType){case "channelCreated":return OnTeamsChannelCreatedAsync(channelData.Channel, channelData.Team, turnContext, cancellationToken);case "channelDeleted":return OnTeamsChannelDeletedAsync(channelData.Channel, channelData.Team, turnContext, cancellationToken);case "channelRenamed":return OnTeamsChannelRenamedAsync(channelData.Channel, channelData.Team, turnContext, cancellationToken);case "teamRenamed":return OnTeamsTeamRenamedAsync(channelData.Team, turnContext, cancellationToken);default:return base.OnConversationUpdateActivityAsync(turnContext, cancellationToken);}...}
}

从上面的代码里可以看到没有什么特别的magic,TeamsActivityHandler重载了OnConversationUpdateActivityAsync,并且根据channelData.EventType判断出不同teams的事件,然后调用相应的方法。对于invoke也类似,重载了OnInvokeActivityAsync,根据turnContext.Activity.Name来调用不同的方法。

回到我们的EchoBot代码,让EchoBot从TeamsActivityHandler继承下来,然后我们可以添加OnTeamsChannelRenamedAsync方法。把EchoBot设置到Teams里,修改安装了EchoBot的channel的名字,就可以看到这个方法被促发的。

public class EchoBot : TeamsActivityHandler
{protected virtual Task OnTeamsChannelRenamedAsync(ChannelInfo channelInfo, TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken){var replyText = "Channel renamed.";await turnContext.SendActivityAsync(MessageFactory.Text(replyText, replyText), cancellationToken);}
}

Teams Bot开发系列:Teams的Activity处理相关推荐

  1. Teams Bot开发系列:初识Bot

    上次我们讲了Teams Bot开发的概述,讲了Azure Bot Service,Bot Framework SDK和我们自己的bot服务的概念,这篇文章就带大家看看Azure Bot Service ...

  2. Teams Bot开发系列:Bot验证

    我们今天来说一下authentication,authentication一直是一个复杂的问题.bot里的authentication也不简单.我们先来看一个概念:Bot Framework Toke ...

  3. Teams Bot开发系列:Activity和Turn

    这篇文章我们来说一下Activity和Turn这两个bot framework中最重要的两个概念,同时也介绍一下TurnContext和BotAdapter Activity 一个activity是聊 ...

  4. Teams Bot开发系列:Activity处理流程

    上篇文章介绍了什么是Activity,Turn,TurnContext和BotAdapter,这篇文章我们看看这些东西是如何窜起来的,他们是如何处理用户发给bot的消息的. 我们以一个最简单的bot, ...

  5. Teams Bot开发系列:Middleware

    middleware是目前一些framework比较流行的概念,通常一个开发框架需要提供一些可扩展可定制化的功能.所以middleware这种pattern就很实用. 熟悉asp.net core的开 ...

  6. Teams Bot App 初探

    上一篇文章深入讲了incoming webhook.这篇文章我们来看一个稍微复杂点的,正式点的 teams app:bot. 我们先来和之前一样,通过teams toolkit 的 sample ga ...

  7. 用AzureFunction开发最简单的Teams Bot

    之前我有一篇文章讲了如何在azure function上开发最简单的outgoing webhook,收到一些反馈,建议我介绍一下如果在azure function上开发teams bot,那这篇文章 ...

  8. 在VSCode Remote环境下开发Teams Bot

    我使用VS Code开发已经有蛮长一段时间了,时间长了,越来越喜欢VS Code,虽然有些时候会没有传统的VS方便,比如开发Azure Function时你需要编写一下launch.json,而且你需 ...

  9. 如何开发Teams Bot

    很多朋友问我如何开发一个成功的Teams Bot,他们说Bot Framework SDK看起来简单,但是真要的去开发一款成熟的bot,很多地方还是不知道如何使用.我从最早的bot framework ...

最新文章

  1. 树莓派上传文件到服务器,05_树莓派图片定时上传到服务器
  2. JavaScript面试系列:JavaScript设计模式之桥接模式和懒加载
  3. 浏览器无法访问虚拟机的服务器
  4. PP部分主数据导出SQVI设置
  5. xshell执行结果到文本_xshell拷贝文件到本地
  6. RocketMQ的Producer详解之分布式事务消息(代码实现以及过程分析)
  7. Cookie和Session的作用和工作原理
  8. Java学习笔记——模块化
  9. php mysql 操作函数_PHP操作mysql函数详解,mysql和php交互函数
  10. 数据3分钟丨GitHub开放全世界最大安全咨询数据库;DataBench-T正式开源;甲骨文283亿美元收购Cerner...
  11. Educational Codeforces Round 47
  12. 把Alexa工具条改装成木马
  13. IDEA2017版本的破解方法
  14. vooc充电原理_OPPO手机充电技术——VOOC技术原理
  15. 华为智慧屏跟Android,华为智慧屏全力打造智慧生活体验 “智慧屏”时代来临
  16. 第八届“图灵杯”NEUQ—ACM程序设计竞赛个人赛(同步赛)
  17. 好看的网站发布导航页HTML源码
  18. 第十四届蓝桥杯模拟赛c++ 试题 I
  19. wordpress.mu
  20. 浅谈windows 编程中SendMessage函数的妙用!!!

热门文章

  1. linux内核设计与实现 中文第三版 pdf_大牛推荐的5本 Linux 经典必读书
  2. win7 php redis 扩展,Windows中安装Redis及php redis扩展
  3. JDK 8 新特性 之 Strams简单使用
  4. zoom 用户被锁定_重新考虑Zoom的用户体验
  5. web mp4第一帧_Web成帧器就在这里!
  6. IDEA、 JetBrains、webstorm、 pycharm 破解教程
  7. java如何获取一个double的小数位数
  8. MySQL Date 函数
  9. Oracle数据表中输入引号等特殊字符
  10. 禁止sethc.exe运行 防止3389的sethc后门