项目作者: dueros

项目描述 :
度秘bot开发的Java版SDK
高级语言: Java
项目地址: git://github.com/dueros/bot-sdk-java.git
创建时间: 2018-01-04T07:19:08Z
项目社区:https://github.com/dueros/bot-sdk-java

开源协议:Apache License 2.0

下载


度秘BOT-SDK for Java

这是一个帮助开发Bot的SDK,我们强烈建议您使用这个SDK开发度秘的Bot。当然,您也可以完全自己来处理中控的协议,自己完成session、nlu、result处理,但是度秘的中控对Bot的协议经常会进行升级,这样会给你带来一些麻烦。这个SDK会与中控的协议一起升级,会最大限度减少对您开发bot的影响。

BOT-SDK提供了以下功能

我们的目标是通过使用bot-sdk,可以迅速的开发一个bot,而不必过多去关注DuerOS的复杂协议。我们提供了如下功能:

  • 封装了DuerOS的request和response
  • 提供了session的简化接口
  • 提供了nlu简化接口
  • 提供了多轮对话开发接口
  • 提供了事件监听接口

BOT-SDK安装说明

  • BOT-SDK需要Java 8及以上版本
  • 建议使用Maven作为工程管理工具,BOT-SDK的升级、维护都将通过Maven进行发布,在pom.xml中添加最新的版本依赖,如下
  1. <dependency>
  2. <groupId>com.baidu.dueros</groupId>
  3. <artifactId>bot-sdk</artifactId>
  4. <version>1.2.0</version>
  5. </dependency>

BOT-SDK使用说明

BOT-SDK提供了两个简单的例子,分别在com.baidu.dueros.samples.audioplayer和com.baidu.dueros.samples.tax。为了使用BOT-SDK,你需要新建一个Class,比如查询个人所得税的例子TaxBot,根据税前工资、城市计算所要查询的个税,需要继承com.baidu.dueros.bot.BaseBot类。

查询个税的意图为inquiry,槽位分别为monthlysalary(税前工资)、location(城市)、compute_type(个税种类)。关于意图以及槽位的概念见https://dueros.baidu.com/didp/doc/dueros-bot-platform/dbp-nlu/intents_markdown

  1. public class TaxBot extends BaseBot {}

开发一个音频播放的Bot,应该继承com.baidu.dueros.bot.AudioPlayer类,AudioPlayer也是继承自BaseBot的子类

  1. public class AudioPlayerBot extends AudioPlayer {}

开发一个视频播放的Bot,应该继承com.baidu.dueros.bot.VideoPlayer类,VideoPlayer也是继承自BaseBot的子类

  1. public class VideoPlayerBot extends VideoPlayer {}

然后,重写BaseBot的构造方法,BaseBot提供了四种基本的构造函数,Bot可以根据自身情况进行重写

  1. // 使用HttpServletRequest作为参数(针对使用Servlet实现服务)
  2. protected BaseBot(HttpServletRequest request) throws IOException {}
  3. // 使用Request作为参数
  4. protected BaseBot(Request request) throws IOException {}
  5. // 使用序列化后的字符串作为参数
  6. protected BaseBot(String request) throws IOException {}
  7. // 使用Certificate对象作为参数,在开启请求参数验证的情况下,需要构造Certificate对象,Certificate的message成员变量是HTTP请求body信息
  8. protected BaseBot(Certificate certificate) throws IOException {}

假设TaxBot使用HttpServletRequest作为参数实现构造方法

  1. /**
  2. * 重写BaseBot构造方法
  3. */
  4. public TaxBot(HttpServletRequest request) throws IOException {
  5. super(request);
  6. }

Bot重写多轮对话接口或事件监听接口

Bot开始提供服务

  1. /**
  2. * 重写onLaunch方法,处理onLaunch对话事件
  3. */
  4. @Override
  5. protected Response onLaunch(LaunchRequest launchRequest) {
  6. // 新建文本卡片
  7. TextCard textCard = new TextCard("所得税为您服务");
  8. // 设置链接地址
  9. textCard.setUrl("www:....");
  10. // 设置链接内容
  11. textCard.setAnchorText("setAnchorText");
  12. // 添加引导话术
  13. textCard.addCueWord("欢迎进入");
  14. // 新建返回的语音内容
  15. OutputSpeech outputSpeech = new OutputSpeech(SpeechType.PlainText, "所得税为您服务");
  16. // 构造返回的Response
  17. Response response = new Response(outputSpeech, textCard);
  18. return response;
  19. }

Bot结束对话

  1. /**
  2. * 重写onSessionEnded事件,处理onSessionEnded对话事件
  3. */
  4. @Override
  5. protected Response onSessionEnded(SessionEndedRequest sessionEndedRequest) {
  6. // 构造TextCard
  7. TextCard textCard = new TextCard("感谢使用所得税服务");
  8. textCard.setAnchorText("setAnchorText");
  9. textCard.addCueWord("欢迎再次使用");
  10. // 构造OutputSpeech
  11. OutputSpeech outputSpeech = new OutputSpeech(SpeechType.PlainText, "欢迎再次使用所得税服务");
  12. // 构造Response
  13. Response response = new Response(outputSpeech, textCard);
  14. return response;
  15. }

Bot处理NLU解析的意图

  1. /**
  2. * 重写onInent方法,处理onInent对话事件
  3. */
  4. @Override
  5. protected Response onInent(IntentRequest intentRequest) {
  6. // 判断NLU解析的意图名称是否匹配
  7. if ("myself".equals(intentRequest.getIntentName())) {
  8. // 判断NLU解析解析后是否存在这个槽位
  9. if (getSlot("monthlysalary") == null) {
  10. // 询问月薪槽位
  11. ask("monthlysalary");
  12. return askSalary();
  13. } else if (getSlot("location") == null) {
  14. // 询问城市槽位
  15. ask("location");
  16. return askLocation();
  17. } else if (getSlot("compute_type") == null) {
  18. // 询问查询种类槽位
  19. ask("compute_type");
  20. return askComputeType();
  21. } else {
  22. // 具体计算方法
  23. compute();
  24. }
  25. }
  26. return null;
  27. }

Bot处理端上触发的事件

在音频类和视频类技能中,端在播放音频或者视频时,会上报事件,Bot收到事件后需要做出相应的处理。

音频类技能

开发一个音频播放的Bot,应该继承com.baidu.dueros.bot.AudioPlayer类,AudioPlayer也是继承自BaseBot的子类

  1. public class AudioPlayerBot extends AudioPlayer {}

音频类技能端上报的事件有PlaybackStartedEvent、PlaybackStoppedEvent、PlaybackNearlyFinishedEvent、PlaybackFinishedEvent事件。

  1. // 处理PlaybackStartedEvent事件
  2. protected Response onPlaybackStartedEvent(final PlaybackStartedEvent playbackNearlyFinishedEvent) {}
  3. // 处理PlaybackStoppedEvent事件
  4. protected Response onPlaybackStoppedEvent(final PlaybackStoppedEvent playbackStoppedEvent) {}
  5. // 处理PlaybackNearlyFinishedEvent事件
  6. protected Response onPlaybackNearlyFinishedEvent(final PlaybackNearlyFinishedEvent playbackNearlyFinishedEvent) {}
  7. // 处理PlaybackFinishedEvent事件
  8. protected Response onPlaybackFinishedEvent(final PlaybackFinishedEvent playbackFinishedEvent) {}

以处理onPlaybackNearlyFinishedEvent事件为例:

  1. /**
  2. * 重写onPlaybackNearlyFinishedEvent方法,处理onPlaybackNearlyFinishedEvent端上报事件
  3. */
  4. @Override
  5. protected Response onPlaybackNearlyFinishedEvent(PlaybackNearlyFinishedEvent playbackNearlyFinishedEvent) {
  6. TextCard textCard = new TextCard();
  7. textCard.setContent("处理即将播放完成事件");
  8. textCard.setUrl("www:...");
  9. textCard.setAnchorText("setAnchorText");
  10. textCard.addCueWord("即将完成");
  11. OutputSpeech outputSpeech = new OutputSpeech(SpeechType.PlainText, "处理即将播放完成事件");
  12. // 新建Play指令
  13. Play play = new Play(PlayBehaviorType.ENQUEUE, "url", 1000);
  14. // 添加返回的指令
  15. addDirective(play);
  16. Reprompt reprompt = new Reprompt(outputSpeech);
  17. Response response = new Response(outputSpeech, textCard, reprompt);
  18. return response;
  19. }
视频类技能

开发一个视频播放的Bot,应该继承com.baidu.dueros.bot.VideoPlayer类,VideoPlayer也是继承自BaseBot的子类

  1. public class VideoPlayerBot extends VideoPlayer {}

视频类技能端上报的事件有PlaybackStartedEvent、PlaybackStoppedEvent、PlaybackNearlyFinishedEvent、PlaybackFinishedEvent、ProgressReportIntervalElapsedEvent、ProgressReportDelayElapsedEvent、PlaybackStutterStartedEvent、PlaybackStutterFinishedEvent、PlaybackPausedEvent、PlaybackResumedEvent、PlaybackQueueClearedEvent等事件。

  1. // 处理PlaybackStartedEvent事件
  2. protected Response onPlaybackStartedEvent(final PlaybackStartedEvent playbackNearlyFinishedEvent) {}
  3. // 处理PlaybackStoppedEvent事件
  4. protected Response onPlaybackStoppedEvent(final PlaybackStoppedEvent playbackStoppedEvent) {}
  5. // 处理PlaybackNearlyFinishedEvent事件
  6. protected Response onPlaybackNearlyFinishedEvent(final PlaybackNearlyFinishedEvent playbackNearlyFinishedEvent) {}
  7. // 处理PlaybackFinishedEvent事件
  8. protected Response onPlaybackFinishedEvent(final PlaybackFinishedEvent playbackFinishedEvent) {}
  9. // 处理ProgressReportIntervalElapsedEvent事件
  10. protected Response onProgressReportIntervalElapsedEvent(final ProgressReportIntervalElapsedEvent progressReportIntervalElapsedEvent) {}
  11. // 处理ProgressReportDelayElapsedEvent事件
  12. protected Response onProgressReportDelayElapsedEvent(final ProgressReportDelayElapsedEvent progressReportDelayElapsedEvent) {}
  13. // 处理PlaybackStutterStartedEvent事件
  14. protected Response onPlaybackStutterStartedEvent(final PlaybackStutterStartedEvent playbackStutterStartedEvent) {}
  15. // 处理PlaybackStutterFinishedEvent事件
  16. protected Response onPlaybackStutterFinishedEvent(final PlaybackStutterFinishedEvent playbackStutterFinishedEvent) {}
  17. // 处理PlaybackPausedEvent事件
  18. protected Response onPlaybackPausedEvent(final PlaybackPausedEvent playbackPausedEvent) {}
  19. // 处理PlaybackResumedEvent事件
  20. protected Response onPlaybackResumedEvent(final PlaybackResumedEvent playbackResumedEvent) {}
  21. // 处理PlaybackQueueClearedEvent事件
  22. protected Response onPlaybackQueueClearedEvent(final PlaybackQueueClearedEvent playbackQueueClearedEvent) {}

如果不想对每个事件都进行处理,可以通过重写onDefaultEvent方法来统一处理。

  1. @Override
  2. protected Response onDefaultEvent() {
  3. this.waitAnswer();
  4. this.setExpectSpeech(false);
  5. return new Response();
  6. }

部署服务

以在Tomcat上部署servlet为例,首先新建一个Servlet。

  1. @WebServlet("/tax")
  2. public class TaxAction extends HttpServlet {
  3. /**
  4. * @see HttpServlet#HttpServlet()
  5. */
  6. public TaxAction() {
  7. super();
  8. }
  9. }

然后重写doPost方法,根据HttpServletRequest构建一个TaxBot对象,然后调用TaxBot的run()方法,run()的返回结果就是bot Response对应的字符串,设置Response的编码为UTF-8,作为servlet的response。

  1. /**
  2. * 重写doPost方法,处理POST请求
  3. */
  4. protected void doPost(HttpServletRequest request, HttpServletResponse response)
  5. throws ServletException, IOException {
  6. // 创建Bot
  7. TaxBot bot = new TaxBot(request);
  8. // 打开签名验证
  9. bot.enableVerify();
  10. // 关闭签名验证
  11. // bot.disableVerify();
  12. try {
  13. // 调用bot的run方法
  14. String responseJson = bot.run();
  15. // 设置response的编码UTF-8
  16. response.setCharacterEncoding("UTF-8");
  17. // 返回response
  18. response.getWriter().append(responseJson);
  19. } catch (Exception e) {
  20. // 返回非法结果
  21. response.getWriter().append("{\"status\":1,\"msg\":\"\"}");
  22. }
  23. }

将上述servlet部署在Tomcat等服务器上,启动服务后即可提供服务

使多轮对话管理更加简单

NLU交互协议

在DBP(DuerOS Bot Platform)平台,可以通过NLU工具,添加了针对槽位询问的配置,包括:

  • 是否必选,对应询问的默认话术
  • 是否需要用户确认槽位内容,以及对应的话术
  • 是否需要用户在执行动作前,对所有的槽位确认一遍,以及对应的话术

针对填槽多轮,Bot发起对用户收集、确认槽位(如果针对特定槽位有设置确认选项,就进行确认)、确认意图(如果有设置确认选项)的询问,BOT-SDK提供了方便的快捷函数支持:

ask

多轮对话的Bot,会通过询问用户来收集完成任务所需要的槽位信息,ask就是询问一个特定的槽位,比如查询个税的意图中,没有提供月薪收入,就可以通过ask询问月薪收入。

  1. // 判断NLU解析的意图名称是否匹配
  2. if ("inquiry".equals(intentRequest.getIntentName())) {
  3. // 判断NLU解析解析后是否存在这个槽位
  4. if (getSlot("monthlysalary") == null) {
  5. // 询问月薪槽位
  6. ask("monthlysalary");
  7. return askSalary();
  8. } else if (getSlot("location") == null) {
  9. // 询问城市槽位
  10. ask("location");
  11. return askLocation();
  12. } else if (getSlot("compute_type") == null) {
  13. // 询问查询种类槽位
  14. ask("compute_type");
  15. return askComputeType();
  16. } else {
  17. // 具体计算方法
  18. compute();
  19. }
  20. }

delegate

将处理交给DuerOS的会话管理模块DM(Dialog Management),按事先配置的顺序,包括对缺失槽位的询问,槽位值的确认(如果设置了需要确认,以及确认的话术),整个意图的确认(如果设置了意图需要确认,以及确认的话术)。比如可以将收集的槽位依次列出,等待用户确认。

  1. // 判断NLU解析的意图名称是否匹配
  2. if ("inquiry".equals(intentRequest.getIntentName())) {
  3. // 如果使用了delegate 就不再需要使用setConfirmSlot/setConfirmIntent,否则返回的directive会被后set的覆盖
  4. setDelegate();
  5. }

confirm slot

主动发起对一个槽位的确认,此时还需要同时返回询问的outputSpeech。主动发起的确认,DM不会使用默认配置的话术。

  1. // 判断NLU解析的意图名称是否匹配
  2. if ("inquiry".equals(intentRequest.getIntentName())) {
  3. // 判断NLU解析解析后是否存在这个槽位
  4. if (getSlot("monthlysalary") == null) {
  5. // 确认槽位
  6. setConfirmSlot("monthlysalary");
  7. }
  8. }

confirm intent

主动发起对一个意图的确认,此时还需同时返回询问的outputSpeach。主动发起的确认,DM不会使用默认配置的话术。一般当槽位填槽完毕,在进行下一步操作之前,一次性的询问各个槽位,是否符合用户预期。

  1. // 判断NLU解析的意图名称是否匹配
  2. if ("inquiry".equals(intentRequest.getIntentName())) {
  3. // 判断NLU解析解析后是否存在这个槽位
  4. if (getSlot("monthlysalary") != null && getSlot("location") != null) {
  5. // 确认意图
  6. setConfirmIntent();
  7. }
  8. }

返回卡片

文本展现模板

BodyTemplate1

  1. // 构造模板BodyTemplate1
  2. BodyTemplate1 bodyTemplate = new BodyTemplate1();
  3. bodyTemplate.setToken("token");
  4. bodyTemplate.setTitle("托尔斯泰的格言");
  5. // 可以链式set设置信息
  6. bodyTemplate.setPlainContent("拖尔斯泰-理想的书籍是智慧的钥匙")
  7. .setBackgroundImageUrl("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg");
  8. // 定义RenderTemplate指令
  9. RenderTemplate renderTemplate = new RenderTemplate(bodyTemplate);
  10. this.addDirective(renderTemplate);

上图下文模版

BodyTemplate2

  1. // 构造模板BodyTemplate2
  2. BodyTemplate2 bodyTemplate = new BodyTemplate2();
  3. bodyTemplate.setToken("token");
  4. // 可以链式set设置信息
  5. bodyTemplate.setPlainContent("拖尔斯泰-理想的书籍是智慧的钥匙")
  6. .setBackgroundImageUrl("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg");
  7. // 定义RenderTemplate指令
  8. RenderTemplate renderTemplate = new RenderTemplate(bodyTemplate);
  9. this.addDirective(renderTemplate);

左图右文模板

BodyTemplate3
定义图片文本展现模板,图片在文字内容左侧,即左图右文

  1. // 构造模板BodyTemplate3
  2. BodyTemplate3 bodyTemplate = new BodyTemplate3();
  3. bodyTemplate.setToken("token");
  4. bodyTemplate.setTitle("托尔斯泰的格言");
  5. // 可以链式set设置信息
  6. bodyTemplate.setPlainContent("拖尔斯泰-理想的书籍是智慧的钥匙")
  7. .setBackgroundImageUrl("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg");
  8. // 定义RenderTemplate指令
  9. RenderTemplate renderTemplate = new RenderTemplate(bodyTemplate);
  10. this.addDirective(renderTemplate);

右图左文模板

BodyTemplate4

  1. // 构造模板BodyTemplate4
  2. BodyTemplate4 bodyTemplate = new BodyTemplate4();
  3. bodyTemplate.setToken("token");
  4. bodyTemplate.setTitle("托尔斯泰的格言");
  5. // 可以链式set设置信息
  6. bodyTemplate.setPlainContent("拖尔斯泰-理想的书籍是智慧的钥匙")
  7. .setBackgroundImageUrl("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg");
  8. // 定义RenderTemplate指令
  9. RenderTemplate renderTemplate = new RenderTemplate(bodyTemplate);
  10. this.addDirective(renderTemplate);

图片模板

BodyTemplate5

  1. // 构造模板BodyTemplate5
  2. BodyTemplate5 bodyTemplate = new BodyTemplate5();
  3. bodyTemplate.setTitle("托尔斯泰的格言");
  4. bodyTemplate.setBackgroundImageUrl("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg");
  5. // 也可以链式set设置信息
  6. bodyTemplate.addImage("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg")
  7. .addImage("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg");
  8. // 定义RenderTemplate指令
  9. RenderTemplate renderTemplate = new RenderTemplate(bodyTemplate);
  10. this.addDirective(renderTemplate);

横向列表模板

ListTemplate1

  1. ListTemplate1 listTemplate = new ListTemplate1();
  2. listTemplate.setTitle("title");
  3. listTemplate.setToken("token");
  4. // 设置模版列表数组listItems其中一项,即列表的一个元素
  5. ListItem listItem = new ListItem();
  6. listItem.setPlainPrimaryText("一级标题");
  7. // 也可以链式设置信息
  8. listItem.setPlainSecondaryText("二级标题")
  9. .setPlainTertiaryText("三级标题")
  10. .setImageUrl("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg");
  11. // 把listItem添加到模版listTemplate
  12. listTemplate.addListItem(listItem);
  13. // 定义RenderTemplate指令
  14. RenderTemplate renderTemplate = new RenderTemplate(listTemplate);
  15. this.addDirective(renderTemplate);

纵向列表模板

ListTemplate2

  1. ListTemplate2 listTemplate = new ListTemplate2();
  2. listTemplate.setTitle("title");
  3. listTemplate.setToken("token");
  4. // 设置模版列表数组listItems其中一项,即列表的一个元素
  5. ListItem listItem = new ListItem();
  6. listItem.setPlainPrimaryText("一级标题");
  7. // 也可以链式设置信息
  8. listItem.setPlainSecondaryText("二级标题")
  9. .setPlainTertiaryText("三级标题")
  10. .setImageUrl("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg");
  11. // 把listItem添加到模版listTemplate
  12. listTemplate.addListItem(listItem);
  13. // 定义RenderTemplate指令
  14. RenderTemplate renderTemplate = new RenderTemplate(listTemplate);
  15. this.addDirective(renderTemplate);

文本卡片

  1. TextCard textCard = new TextCard("您的税前工资是多少呢?");
  2. textCard.setUrl("www:......");
  3. textCard.setAnchorText("链接文本");
  4. textCard.addCueWord("您的税前工资是多少呢?");

标准卡片

  1. StandardCard standardCard = new StandardCard("您的税前工资是多少呢?", "您的税前工资是多少呢?");
  2. standardCard.setUrl("www:......");
  3. standardCard.setAnchorText("链接文本");
  4. standardCard.addCueWords("您的税前工资是多少呢?");
  5. standardCard.setImage("图片");

列表卡片

  1. StandCardList standCardList = new StandCardList();
  2. standCardList.addStandardCardInfo("您的税前工资是多少呢?", "您的税前工资是多少呢?");
  3. standCardList.addCueWords("您的税前工资是多少呢?");

图片卡片

  1. ImageCard imageCard = new ImageCard();
  2. imageCard.addImageCardInfo("图片地址", "缩略图地址");
  3. imageCard.addCueWords("引导话术");

返回speech

outputSpeech

  1. // 构造outputSpeech
  2. OutputSpeech outputSpeech = new OutputSpeech(Type.SSML, "您的税前工资是多少呢?");

reprompt

  1. // 构造reprompt
  2. Reprompt reprompt = new Reprompt(outputSpeech);

音频指令

音频播放指令

  1. import com.baidu.dueros.data.response.directive.audioplayer.Play;
  2. // 新建Play指令
  3. Play play = new Play("url");
  4. play.setPlayBehavior(PlayBehaviorType.REPLACE_ALL);
  5. play.setOffsetInMilliSeconds(1000);

渲染音频播放器的主界面

AudioPlayer.Play指令中增加playerInfo信息

  1. import com.baidu.dueros.data.response.directive.audioplayer.Play;
  2. // 新建Play指令
  3. Play play = new Play("http://www.music");
  4. play.setPlayBehavior(PlayBehaviorType.ENQUEUE);
  5. // 音频播放器的主界面
  6. PlayerInfo playerInfo = new PlayerInfo();
  7. // 创建按钮
  8. PlayPauseButton playpause = new PlayPauseButton();
  9. PreviousButton previous = new PreviousButton();
  10. // 设置PlayerInfo的按钮控件
  11. playerInfo.addButton(playpause);
  12. playerInfo.addButton(previous);
  13. playerInfo.setTitle("周杰伦");
  14. playerInfo.setTitleSubtext1("七里香");
  15. // 也可以链式set信息
  16. playerInfo.setLyric("www.lyric...")
  17. .setTitleSubtext2("周文山");
  18. // 设置Play指令的PlayerInfo
  19. play.setPlayerInfo(playerInfo);

音频暂停指令

  1. import com.baidu.dueros.data.response.directive.audioplayer.Stop;
  2. // 新建Stop指令
  3. Stop stop = new Stop();

视频指令

视频播放指令

  1. import com.baidu.dueros.data.response.directive.videoplayer.Play;
  2. // 新建视频播放指令
  3. Play play = new Play("http://www.video");
  4. play.setPlayBehavior(PlayBehaviorType.REPLACE_ALL);
  5. play.setToken("token");
  6. // 也可以链式set信息
  7. play.setOffsetInMilliSeconds(1000)
  8. .setVideoItemId("video_1");

视频停止播放指令

  1. import com.baidu.dueros.data.response.directive.videoplayer.Stop;
  2. // 新建视频停止指令
  3. Stop stop = new Stop();

清除播放队列指令

  1. import com.baidu.dueros.data.response.directive.videoplayer.ClearQueue;
  2. ClearQueue clear = new ClearQueue("CLEAR_ALL");

获取端音频播放器状态

  1. Context context = this.getRequest().getContext();
  2. AudioPlayerState audioPlayerState = context.getAudioPlayer();

获取端视频播放器状态

  1. Context context = this.getRequest().getContext();
  2. VideoPlayerState videoPlayerState = context.getVideoPlayer();

渲染引导词

使用Hint指令渲染引导词

  1. ArrayList<String> hints = new ArrayList<>();
  2. hints.add("提示1");
  3. hints.add("提示2");
  4. hints.add("提示3");
  5. Hint hint = new Hint(hints);

支付

返回支付指令

发起支付扣款指令

  1. // 构造返回的charge指令
  2. // 默认参数为(扣款金额、订单ID、商品名称、商品描述信息)
  3. Charge charge = new Charge("0.01", "sellerOrderId", "productName", "description");
  4. // 添加返回的charge指令
  5. this.addDirective(charge);

处理扣款事件

支付完成后,会收到扣款事件

  1. // 处理扣款事件
  2. protected Response onChargeEvent(final ChargeEvent chargeEvent) {}

权限

返回权限申请指令

  1. // 构造返回的AskForPermissionsConsent指令
  2. AskForPermissionsConsent askForPermissionsConsent = new AskForPermissionsConsent();
  3. askForPermissionsConsent.addPermission(Permission.READ_USER_PROFILE);
  4. this.addDirective(askForPermissionsConsent);

处理用户同意授权事件

  1. // 处理用户同意授权事件
  2. protected Response onPermissionGrantedEvent(PermissionGrantedEvent permissionGrantedEvent) {}

处理用户拒绝授权事件

  1. // 处理用户拒绝授权事件
  2. protected Response onPermissionRejectedEvent(PermissionRejectedEvent permissionRejectedEvent) {}

处理授权失败事件

  1. // 处理授权失败事件
  2. protected Response onPermissionGrantFailedEvent(PermissionGrantFailedEvent permissionGrantFailedEvent) {}

构造Response

  1. Response response = new Response(outputSpeech, textCard, reprompt);

认证

当DuerOS向Bot发送请求时,Bot需要对收到的请求进行验证,验证方法如下:
获取HTTP请求header中的签名signature、证书地址signaturecerturl以及body信息message。

  1. // 根据签名、证书地址、HTTP body构造Certificate对象
  2. Certificate certificate = new Certificate(message, signature, signaturecerturl);
  3. bot.setCertificate(certificate);
  4. // 打开签名验证
  5. bot.enableVerify();

在调试过程中,可以关闭认证

  1. // 关闭签名验证
  2. bot.disableVerify();

线下调试

在启动sample中的taxbot服务后,可以通过postman发送Request,Request的body内容为,resource/request/inquiry_request,便可以看到Bot的返回。

线下调试可以关闭签名认证。

  1. // 关闭签名验证
  2. bot.disableVerify();

使用Bot的数据统计功能

  1. bot-sdk里已经集成了[数据统计功能](https://gitlab.com/tianyi17/bot-monitor-java)(默认该功能是关闭的),你只需要进行简单的几步操作就可以使用bot的数据统计功能:
  2. 1. 打开终端,执行`openssl genrsa -out rsa_private_key.pem 1024`命令生成私钥
  3. 2. 执行`openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem`生成和私钥匹配的公钥。
  4. 3. 执行`openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt >> rsa_private_key_java.psk`命令,将私钥转换成pkcs8格式。
  5. 4. 使用编辑器打开公钥文件,将文件的完整内容上传到DBP平台对应的Bot空间。
  6. 保存`rsa_private_key_java.psk`私钥文件,我们下面会用到。
  7. 5. bot的构造函数里开启数据上报功能。假设你在TaxBot使用`HttpServletRequest`作为参数实现构造方法,把`rsa_private_key_java.psk`文件里内容赋值给`String`类型的`privateKey`变量:
  1. public TaxBot(HttpServletRequest request) throws IOException {
  2. super(request);
  3. String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALcD5iNhmR/fN9Sw\n" +
  4. "D9dmiyZo31wVapoUmDTjqHOe0qpxQTgRYNqaR8cxmIKpk1IzPskJEYwAl37wu12X\n" +
  5. "tobCZuIZSScrnuSZFozC33DWg3DR4dngf7S1FS08FLKUfAZ7H0rPzuOMRtFUj6Yk\n" +
  6. "iVKArnzNVoTT2bmlrEeq6ttAY5RnAgMBAAECgYBe5MGmZMudsALl3+hG2p+Z6dSu\n" +
  7. "jVg5ziXhfo1wbdBzmcekR7Z9gnNnQDsAvOZrP7D1UiNsAT6MDkxISgrVMuVew91q\n" +
  8. "rEfu7MbmUx6dp4wlVSJOtzhF7VqiisV3zr8EHbf9utWX9yqwhUlszBrsx8Cqvy/B\n" +
  9. "mTsWSmkCST1jFBzV+QJBAOMpYhoyUBjrbq0Y7y7oa8RmW+tmMjUfCbR9W4lFPomN\n" +
  10. "bxnVpwA7OefLzdBjzRM/pfEfQZYSPJYWnENPO7LTxyMCQQDOP8icc9sjWRY//Jtr\n" +
  11. "IIvq3jyAV/o6GwJVXUvwCLTZD+RxkNwUsVVio+bfQ7eBgbb8j7tKKMvftrjKQ11O\n" +
  12. "WvPtAkA19vHQSV2P3fZH9uFzYlGfsbVqgbexuPLkRteFD8cghFH9cC0hN/C0qUz2\n" +
  13. "kY75YKh6VLOPBDwSZ8KtltgWzorDAkBKgoh63PAB6SE8pImRPgTOKNM6mo3vh+pj\n" +
  14. "5HyWjs6mzDL/RBH998KdDBFP/yrAQphUzagftnVQsLY5e/StZfZRAkEAnrolcj06\n" +
  15. "+77j6Ibc++C+IAgUYiuo+ZZmVTDOI0BS1lC6kZz8HMlAqDl4Mf7HulijcdHqm/Z0\n" +
  16. "XgtBxVoMpmbJmQ==";
  17. //privateKey为私钥内容,0代表你的Bot在DBP平台debug环境,1或者其他整数代表online环境,botMonitor对象已经在bot-sdk里初始化,可以直接调用
  18. this.botMonitor.setEnvironmentInfo(privateKey, 0);
  19. }

你也可以在代码里随时开启和关闭数据统计功能:

  1. //true代表开启,false代表关闭。调用setEnvironmentInfo之后会默认开启
  2. this.botMonitor.setMonitorEnabled(false);