这是一个帮助开发Bot的SDK,我们强烈建议您使用这个SDK开发度秘的Bot。当然,您也可以完全自己来处理中控的协议,自己完成session、nlu、result处理,但是度秘的中控对Bot的协议经常会进行升级,这样会给你带来一些麻烦。这个SDK会与中控的协议一起升级,会最大限度减少对您开发bot的影响。
我们的目标是通过使用bot-sdk,可以迅速的开发一个bot,而不必过多去关注DuerOS的复杂协议。我们提供了如下功能:
- 封装了DuerOS的request和response
- 提供了session的简化接口
- 提供了nlu简化接口
- 提供了多轮对话开发接口
- 提供了事件监听接口
- BOT-SDK需要Java 8及以上版本
- 建议使用Maven作为工程管理工具,BOT-SDK的升级、维护都将通过Maven进行发布,在pom.xml中添加最新的版本依赖,如下
<dependency>
<groupId>com.baidu.dueros</groupId>
<artifactId>bot-sdk</artifactId>
<version>1.2.0</version>
</dependency>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
publicclassTaxBotextendsBaseBot {}开发一个音频播放的Bot,应该继承com.baidu.dueros.bot.AudioPlayer类,AudioPlayer也是继承自BaseBot的子类
publicclassAudioPlayerBotextendsAudioPlayer {}开发一个视频播放的Bot,应该继承com.baidu.dueros.bot.VideoPlayer类,VideoPlayer也是继承自BaseBot的子类
publicclassVideoPlayerBotextendsVideoPlayer {}然后,重写BaseBot的构造方法,BaseBot提供了四种基本的构造函数,Bot可以根据自身情况进行重写
// 使用HttpServletRequest作为参数(针对使用Servlet实现服务)protectedBaseBot(HttpServletRequestrequest) throwsIOException {}
// 使用Request作为参数protectedBaseBot(Requestrequest) throwsIOException {}
// 使用序列化后的字符串作为参数protectedBaseBot(Stringrequest) throwsIOException {}
// 使用Certificate对象作为参数,在开启请求参数验证的情况下,需要构造Certificate对象,Certificate的message成员变量是HTTP请求body信息protectedBaseBot(Certificatecertificate) throwsIOException {}假设TaxBot使用HttpServletRequest作为参数实现构造方法
/** * 重写BaseBot构造方法 */publicTaxBot(HttpServletRequestrequest) throwsIOException {
super(request);
}/** * 重写onLaunch方法,处理onLaunch对话事件 */@OverrideprotectedResponseonLaunch(LaunchRequestlaunchRequest) {
// 新建文本卡片TextCardtextCard = newTextCard("所得税为您服务");
// 设置链接地址textCard.setUrl("www:....");
// 设置链接内容textCard.setAnchorText("setAnchorText");
// 添加引导话术textCard.addCueWord("欢迎进入");
// 新建返回的语音内容OutputSpeechoutputSpeech = newOutputSpeech(SpeechType.PlainText, "所得税为您服务");
// 构造返回的ResponseResponseresponse = newResponse(outputSpeech, textCard);
returnresponse;
}/** * 重写onSessionEnded事件,处理onSessionEnded对话事件 */@OverrideprotectedResponseonSessionEnded(SessionEndedRequestsessionEndedRequest) {
// 构造TextCardTextCardtextCard = newTextCard("感谢使用所得税服务");
textCard.setAnchorText("setAnchorText");
textCard.addCueWord("欢迎再次使用");
// 构造OutputSpeechOutputSpeechoutputSpeech = newOutputSpeech(SpeechType.PlainText, "欢迎再次使用所得税服务");
// 构造ResponseResponseresponse = newResponse(outputSpeech, textCard);
returnresponse;
}/** * 重写onInent方法,处理onInent对话事件 */@OverrideprotectedResponseonInent(IntentRequestintentRequest) {
// 判断NLU解析的意图名称是否匹配if ("myself".equals(intentRequest.getIntentName())) {
// 判断NLU解析解析后是否存在这个槽位if (getSlot("monthlysalary") == null) {
// 询问月薪槽位ask("monthlysalary");
returnaskSalary();
} elseif (getSlot("location") == null) {
// 询问城市槽位ask("location");
returnaskLocation();
} elseif (getSlot("compute_type") == null) {
// 询问查询种类槽位ask("compute_type");
returnaskComputeType();
} else {
// 具体计算方法compute();
}
}
returnnull;
}在音频类和视频类技能中,端在播放音频或者视频时,会上报事件,Bot收到事件后需要做出相应的处理。
开发一个音频播放的Bot,应该继承com.baidu.dueros.bot.AudioPlayer类,AudioPlayer也是继承自BaseBot的子类
publicclassAudioPlayerBotextendsAudioPlayer {}音频类技能端上报的事件有PlaybackStartedEvent、PlaybackStoppedEvent、PlaybackNearlyFinishedEvent、PlaybackFinishedEvent事件。
// 处理PlaybackStartedEvent事件protectedResponseonPlaybackStartedEvent(finalPlaybackStartedEventplaybackNearlyFinishedEvent) {}
// 处理PlaybackStoppedEvent事件protectedResponseonPlaybackStoppedEvent(finalPlaybackStoppedEventplaybackStoppedEvent) {}
// 处理PlaybackNearlyFinishedEvent事件protectedResponseonPlaybackNearlyFinishedEvent(finalPlaybackNearlyFinishedEventplaybackNearlyFinishedEvent) {}
// 处理PlaybackFinishedEvent事件protectedResponseonPlaybackFinishedEvent(finalPlaybackFinishedEventplaybackFinishedEvent) {}以处理onPlaybackNearlyFinishedEvent事件为例:
/** * 重写onPlaybackNearlyFinishedEvent方法,处理onPlaybackNearlyFinishedEvent端上报事件 */@OverrideprotectedResponseonPlaybackNearlyFinishedEvent(PlaybackNearlyFinishedEventplaybackNearlyFinishedEvent) {
TextCardtextCard = newTextCard();
textCard.setContent("处理即将播放完成事件");
textCard.setUrl("www:...");
textCard.setAnchorText("setAnchorText");
textCard.addCueWord("即将完成");
OutputSpeechoutputSpeech = newOutputSpeech(SpeechType.PlainText, "处理即将播放完成事件");
// 新建Play指令Playplay = newPlay(PlayBehaviorType.ENQUEUE, "url", 1000);
// 添加返回的指令addDirective(play);
Repromptreprompt = newReprompt(outputSpeech);
Responseresponse = newResponse(outputSpeech, textCard, reprompt);
returnresponse;
}开发一个视频播放的Bot,应该继承com.baidu.dueros.bot.VideoPlayer类,VideoPlayer也是继承自BaseBot的子类
publicclassVideoPlayerBotextendsVideoPlayer {}视频类技能端上报的事件有PlaybackStartedEvent、PlaybackStoppedEvent、PlaybackNearlyFinishedEvent、PlaybackFinishedEvent、ProgressReportIntervalElapsedEvent、ProgressReportDelayElapsedEvent、PlaybackStutterStartedEvent、PlaybackStutterFinishedEvent、PlaybackPausedEvent、PlaybackResumedEvent、PlaybackQueueClearedEvent等事件。
// 处理PlaybackStartedEvent事件protectedResponseonPlaybackStartedEvent(finalPlaybackStartedEventplaybackNearlyFinishedEvent) {}
// 处理PlaybackStoppedEvent事件protectedResponseonPlaybackStoppedEvent(finalPlaybackStoppedEventplaybackStoppedEvent) {}
// 处理PlaybackNearlyFinishedEvent事件protectedResponseonPlaybackNearlyFinishedEvent(finalPlaybackNearlyFinishedEventplaybackNearlyFinishedEvent) {}
// 处理PlaybackFinishedEvent事件protectedResponseonPlaybackFinishedEvent(finalPlaybackFinishedEventplaybackFinishedEvent) {}
// 处理ProgressReportIntervalElapsedEvent事件protectedResponseonProgressReportIntervalElapsedEvent(finalProgressReportIntervalElapsedEventprogressReportIntervalElapsedEvent) {}
// 处理ProgressReportDelayElapsedEvent事件protectedResponseonProgressReportDelayElapsedEvent(finalProgressReportDelayElapsedEventprogressReportDelayElapsedEvent) {}
// 处理PlaybackStutterStartedEvent事件protectedResponseonPlaybackStutterStartedEvent(finalPlaybackStutterStartedEventplaybackStutterStartedEvent) {}
// 处理PlaybackStutterFinishedEvent事件protectedResponseonPlaybackStutterFinishedEvent(finalPlaybackStutterFinishedEventplaybackStutterFinishedEvent) {}
// 处理PlaybackPausedEvent事件protectedResponseonPlaybackPausedEvent(finalPlaybackPausedEventplaybackPausedEvent) {}
// 处理PlaybackResumedEvent事件protectedResponseonPlaybackResumedEvent(finalPlaybackResumedEventplaybackResumedEvent) {}
// 处理PlaybackQueueClearedEvent事件protectedResponseonPlaybackQueueClearedEvent(finalPlaybackQueueClearedEventplaybackQueueClearedEvent) {}如果不想对每个事件都进行处理,可以通过重写onDefaultEvent方法来统一处理。
@OverrideprotectedResponseonDefaultEvent() {
this.waitAnswer();
this.setExpectSpeech(false);
returnnewResponse();
}以在Tomcat上部署servlet为例,首先新建一个Servlet。
@WebServlet("/tax")
publicclassTaxActionextendsHttpServlet {
/** * @see HttpServlet#HttpServlet() */publicTaxAction() {
super();
}
}然后重写doPost方法,根据HttpServletRequest构建一个TaxBot对象,然后调用TaxBot的run()方法,run()的返回结果就是bot Response对应的字符串,设置Response的编码为UTF-8,作为servlet的response。
/** * 重写doPost方法,处理POST请求 */protectedvoiddoPost(HttpServletRequestrequest, HttpServletResponseresponse)
throwsServletException, IOException {
// 创建BotTaxBotbot = newTaxBot(request);
// 打开签名验证bot.enableVerify();
// 关闭签名验证// bot.disableVerify();try {
// 调用bot的run方法StringresponseJson = bot.run();
// 设置response的编码UTF-8response.setCharacterEncoding("UTF-8");
// 返回responseresponse.getWriter().append(responseJson);
} catch (Exceptione) {
// 返回非法结果response.getWriter().append("{\"status\":1,\"msg\":\"\"}");
}
}将上述servlet部署在Tomcat等服务器上,启动服务后即可提供服务
在DBP(DuerOS Bot Platform)平台,可以通过NLU工具,添加了针对槽位询问的配置,包括:
- 是否必选,对应询问的默认话术
- 是否需要用户确认槽位内容,以及对应的话术
- 是否需要用户在执行动作前,对所有的槽位确认一遍,以及对应的话术
针对填槽多轮,Bot发起对用户收集、确认槽位(如果针对特定槽位有设置确认选项,就进行确认)、确认意图(如果有设置确认选项)的询问,BOT-SDK提供了方便的快捷函数支持:
多轮对话的Bot,会通过询问用户来收集完成任务所需要的槽位信息,ask就是询问一个特定的槽位,比如查询个税的意图中,没有提供月薪收入,就可以通过ask询问月薪收入。
// 判断NLU解析的意图名称是否匹配if ("inquiry".equals(intentRequest.getIntentName())) {
// 判断NLU解析解析后是否存在这个槽位if (getSlot("monthlysalary") == null) {
// 询问月薪槽位ask("monthlysalary");
returnaskSalary();
} elseif (getSlot("location") == null) {
// 询问城市槽位ask("location");
returnaskLocation();
} elseif (getSlot("compute_type") == null) {
// 询问查询种类槽位ask("compute_type");
returnaskComputeType();
} else {
// 具体计算方法compute();
}
}将处理交给DuerOS的会话管理模块DM(Dialog Management),按事先配置的顺序,包括对缺失槽位的询问,槽位值的确认(如果设置了需要确认,以及确认的话术),整个意图的确认(如果设置了意图需要确认,以及确认的话术)。比如可以将收集的槽位依次列出,等待用户确认。
// 判断NLU解析的意图名称是否匹配if ("inquiry".equals(intentRequest.getIntentName())) {
// 如果使用了delegate 就不再需要使用setConfirmSlot/setConfirmIntent,否则返回的directive会被后set的覆盖setDelegate();
}主动发起对一个槽位的确认,此时还需要同时返回询问的outputSpeech。主动发起的确认,DM不会使用默认配置的话术。
// 判断NLU解析的意图名称是否匹配if ("inquiry".equals(intentRequest.getIntentName())) {
// 判断NLU解析解析后是否存在这个槽位if (getSlot("monthlysalary") == null) {
// 确认槽位setConfirmSlot("monthlysalary");
}
}主动发起对一个意图的确认,此时还需同时返回询问的outputSpeach。主动发起的确认,DM不会使用默认配置的话术。一般当槽位填槽完毕,在进行下一步操作之前,一次性的询问各个槽位,是否符合用户预期。
// 判断NLU解析的意图名称是否匹配if ("inquiry".equals(intentRequest.getIntentName())) {
// 判断NLU解析解析后是否存在这个槽位if (getSlot("monthlysalary") != null && getSlot("location") != null) {
// 确认意图setConfirmIntent();
}
}BodyTemplate1
// 构造模板BodyTemplate1BodyTemplate1bodyTemplate = newBodyTemplate1();
bodyTemplate.setToken("token");
bodyTemplate.setTitle("托尔斯泰的格言");
// 可以链式set设置信息bodyTemplate.setPlainContent("拖尔斯泰-理想的书籍是智慧的钥匙")
.setBackgroundImageUrl("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg");
// 定义RenderTemplate指令RenderTemplaterenderTemplate = newRenderTemplate(bodyTemplate);
this.addDirective(renderTemplate);BodyTemplate2
// 构造模板BodyTemplate2BodyTemplate2bodyTemplate = newBodyTemplate2();
bodyTemplate.setToken("token");
// 可以链式set设置信息bodyTemplate.setPlainContent("拖尔斯泰-理想的书籍是智慧的钥匙")
.setBackgroundImageUrl("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg");
// 定义RenderTemplate指令RenderTemplaterenderTemplate = newRenderTemplate(bodyTemplate);
this.addDirective(renderTemplate);BodyTemplate3 定义图片文本展现模板,图片在文字内容左侧,即左图右文
// 构造模板BodyTemplate3BodyTemplate3bodyTemplate = newBodyTemplate3();
bodyTemplate.setToken("token");
bodyTemplate.setTitle("托尔斯泰的格言");
// 可以链式set设置信息bodyTemplate.setPlainContent("拖尔斯泰-理想的书籍是智慧的钥匙")
.setBackgroundImageUrl("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg");
// 定义RenderTemplate指令RenderTemplaterenderTemplate = newRenderTemplate(bodyTemplate);
this.addDirective(renderTemplate);BodyTemplate4
// 构造模板BodyTemplate4BodyTemplate4bodyTemplate = newBodyTemplate4();
bodyTemplate.setToken("token");
bodyTemplate.setTitle("托尔斯泰的格言");
// 可以链式set设置信息bodyTemplate.setPlainContent("拖尔斯泰-理想的书籍是智慧的钥匙")
.setBackgroundImageUrl("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg");
// 定义RenderTemplate指令RenderTemplaterenderTemplate = newRenderTemplate(bodyTemplate);
this.addDirective(renderTemplate);BodyTemplate5
// 构造模板BodyTemplate5BodyTemplate5bodyTemplate = newBodyTemplate5();
bodyTemplate.setTitle("托尔斯泰的格言");
bodyTemplate.setBackgroundImageUrl("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg");
// 也可以链式set设置信息bodyTemplate.addImage("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg")
.addImage("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg");
// 定义RenderTemplate指令RenderTemplaterenderTemplate = newRenderTemplate(bodyTemplate);
this.addDirective(renderTemplate);ListTemplate1
ListTemplate1listTemplate = newListTemplate1();
listTemplate.setTitle("title");
listTemplate.setToken("token");
// 设置模版列表数组listItems其中一项,即列表的一个元素ListItemlistItem = newListItem();
listItem.setPlainPrimaryText("一级标题");
// 也可以链式设置信息listItem.setPlainSecondaryText("二级标题")
.setPlainTertiaryText("三级标题")
.setImageUrl("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg");
// 把listItem添加到模版listTemplatelistTemplate.addListItem(listItem);
// 定义RenderTemplate指令RenderTemplaterenderTemplate = newRenderTemplate(listTemplate);
this.addDirective(renderTemplate);ListTemplate2
ListTemplate2listTemplate = newListTemplate2();
listTemplate.setTitle("title");
listTemplate.setToken("token");
// 设置模版列表数组listItems其中一项,即列表的一个元素ListItemlistItem = newListItem();
listItem.setPlainPrimaryText("一级标题");
// 也可以链式设置信息listItem.setPlainSecondaryText("二级标题")
.setPlainTertiaryText("三级标题")
.setImageUrl("https://skillstore.cdn.bcebos.com/icon/100/c709eed1-c07a-be4a-b242-0b0d8b777041.jpg");
// 把listItem添加到模版listTemplatelistTemplate.addListItem(listItem);
// 定义RenderTemplate指令RenderTemplaterenderTemplate = newRenderTemplate(listTemplate);
this.addDirective(renderTemplate);TextCardtextCard = newTextCard("您的税前工资是多少呢?");
textCard.setUrl("www:......");
textCard.setAnchorText("链接文本");
textCard.addCueWord("您的税前工资是多少呢?");StandardCardstandardCard = newStandardCard("您的税前工资是多少呢?", "您的税前工资是多少呢?");
standardCard.setUrl("www:......");
standardCard.setAnchorText("链接文本");
standardCard.addCueWords("您的税前工资是多少呢?");
standardCard.setImage("图片");StandCardListstandCardList = newStandCardList();
standCardList.addStandardCardInfo("您的税前工资是多少呢?", "您的税前工资是多少呢?");
standCardList.addCueWords("您的税前工资是多少呢?");ImageCardimageCard = newImageCard();
imageCard.addImageCardInfo("图片地址", "缩略图地址");
imageCard.addCueWords("引导话术");// 构造outputSpeechOutputSpeechoutputSpeech = newOutputSpeech(Type.SSML, "您的税前工资是多少呢?");// 构造repromptRepromptreprompt = newReprompt(outputSpeech);importcom.baidu.dueros.data.response.directive.audioplayer.Play;
// 新建Play指令Playplay = newPlay("url");
play.setPlayBehavior(PlayBehaviorType.REPLACE_ALL);
play.setOffsetInMilliSeconds(1000);AudioPlayer.Play指令中增加playerInfo信息
importcom.baidu.dueros.data.response.directive.audioplayer.Play;
// 新建Play指令Playplay = newPlay("http://www.music");
play.setPlayBehavior(PlayBehaviorType.ENQUEUE);
// 音频播放器的主界面PlayerInfoplayerInfo = newPlayerInfo();
// 创建按钮PlayPauseButtonplaypause = newPlayPauseButton();
PreviousButtonprevious = newPreviousButton();
// 设置PlayerInfo的按钮控件playerInfo.addButton(playpause);
playerInfo.addButton(previous);
playerInfo.setTitle("周杰伦");
playerInfo.setTitleSubtext1("七里香");
// 也可以链式set信息playerInfo.setLyric("www.lyric...")
.setTitleSubtext2("周文山");
// 设置Play指令的PlayerInfoplay.setPlayerInfo(playerInfo);importcom.baidu.dueros.data.response.directive.audioplayer.Stop;
// 新建Stop指令Stopstop = newStop();importcom.baidu.dueros.data.response.directive.videoplayer.Play;
// 新建视频播放指令Playplay = newPlay("http://www.video");
play.setPlayBehavior(PlayBehaviorType.REPLACE_ALL);
play.setToken("token");
// 也可以链式set信息play.setOffsetInMilliSeconds(1000)
.setVideoItemId("video_1");importcom.baidu.dueros.data.response.directive.videoplayer.Stop;
// 新建视频停止指令Stopstop = newStop();importcom.baidu.dueros.data.response.directive.videoplayer.ClearQueue;
ClearQueueclear = newClearQueue("CLEAR_ALL");Contextcontext = this.getRequest().getContext();
AudioPlayerStateaudioPlayerState = context.getAudioPlayer();Contextcontext = this.getRequest().getContext();
VideoPlayerStatevideoPlayerState = context.getVideoPlayer();使用Hint指令渲染引导词
ArrayList<String> hints = newArrayList<>();
hints.add("提示1");
hints.add("提示2");
hints.add("提示3");
Hinthint = newHint(hints);发起支付扣款指令
// 构造返回的charge指令// 默认参数为(扣款金额、订单ID、商品名称、商品描述信息)Chargecharge = newCharge("0.01", "sellerOrderId", "productName", "description");
// 添加返回的charge指令this.addDirective(charge);支付完成后,会收到扣款事件
// 处理扣款事件protectedResponseonChargeEvent(finalChargeEventchargeEvent) {}// 构造返回的AskForPermissionsConsent指令AskForPermissionsConsentaskForPermissionsConsent = newAskForPermissionsConsent();
askForPermissionsConsent.addPermission(Permission.READ_USER_PROFILE);
this.addDirective(askForPermissionsConsent);// 处理用户同意授权事件protectedResponseonPermissionGrantedEvent(PermissionGrantedEventpermissionGrantedEvent) {}// 处理用户拒绝授权事件protectedResponseonPermissionRejectedEvent(PermissionRejectedEventpermissionRejectedEvent) {}// 处理授权失败事件protectedResponseonPermissionGrantFailedEvent(PermissionGrantFailedEventpermissionGrantFailedEvent) {}Responseresponse = newResponse(outputSpeech, textCard, reprompt);当DuerOS向Bot发送请求时,Bot需要对收到的请求进行验证,验证方法如下: 获取HTTP请求header中的签名signature、证书地址signaturecerturl以及body信息message。
// 根据签名、证书地址、HTTP body构造Certificate对象Certificatecertificate = newCertificate(message, signature, signaturecerturl);
bot.setCertificate(certificate);
// 打开签名验证bot.enableVerify();在调试过程中,可以关闭认证
// 关闭签名验证bot.disableVerify();在启动sample中的taxbot服务后,可以通过postman发送Request,Request的body内容为,resource/request/inquiry_request,便可以看到Bot的返回。
线下调试可以关闭签名认证。
// 关闭签名验证bot.disableVerify();bot-sdk里已经集成了[数据统计功能](https://gitlab.com/tianyi17/bot-monitor-java)(默认该功能是关闭的),你只需要进行简单的几步操作就可以使用bot的数据统计功能:
1. 打开终端,执行`openssl genrsa -out rsa_private_key.pem 1024`命令生成私钥
2. 执行`openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem`生成和私钥匹配的公钥。
3. 执行`openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt >> rsa_private_key_java.psk`命令,将私钥转换成pkcs8格式。
4. 使用编辑器打开公钥文件,将文件的完整内容上传到DBP平台对应的Bot空间。
保存`rsa_private_key_java.psk`私钥文件,我们下面会用到。
5. 在bot的构造函数里开启数据上报功能。假设你在TaxBot使用`HttpServletRequest`作为参数实现构造方法,把`rsa_private_key_java.psk`文件里内容赋值给`String`类型的`privateKey`变量:
publicTaxBot(HttpServletRequestrequest) throwsIOException {
super(request);
StringprivateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALcD5iNhmR/fN9Sw\n" +
"D9dmiyZo31wVapoUmDTjqHOe0qpxQTgRYNqaR8cxmIKpk1IzPskJEYwAl37wu12X\n" +
"tobCZuIZSScrnuSZFozC33DWg3DR4dngf7S1FS08FLKUfAZ7H0rPzuOMRtFUj6Yk\n" +
"iVKArnzNVoTT2bmlrEeq6ttAY5RnAgMBAAECgYBe5MGmZMudsALl3+hG2p+Z6dSu\n" +
"jVg5ziXhfo1wbdBzmcekR7Z9gnNnQDsAvOZrP7D1UiNsAT6MDkxISgrVMuVew91q\n" +
"rEfu7MbmUx6dp4wlVSJOtzhF7VqiisV3zr8EHbf9utWX9yqwhUlszBrsx8Cqvy/B\n" +
"mTsWSmkCST1jFBzV+QJBAOMpYhoyUBjrbq0Y7y7oa8RmW+tmMjUfCbR9W4lFPomN\n" +
"bxnVpwA7OefLzdBjzRM/pfEfQZYSPJYWnENPO7LTxyMCQQDOP8icc9sjWRY//Jtr\n" +
"IIvq3jyAV/o6GwJVXUvwCLTZD+RxkNwUsVVio+bfQ7eBgbb8j7tKKMvftrjKQ11O\n" +
"WvPtAkA19vHQSV2P3fZH9uFzYlGfsbVqgbexuPLkRteFD8cghFH9cC0hN/C0qUz2\n" +
"kY75YKh6VLOPBDwSZ8KtltgWzorDAkBKgoh63PAB6SE8pImRPgTOKNM6mo3vh+pj\n" +
"5HyWjs6mzDL/RBH998KdDBFP/yrAQphUzagftnVQsLY5e/StZfZRAkEAnrolcj06\n" +
"+77j6Ibc++C+IAgUYiuo+ZZmVTDOI0BS1lC6kZz8HMlAqDl4Mf7HulijcdHqm/Z0\n" +
"XgtBxVoMpmbJmQ==";
//privateKey为私钥内容,0代表你的Bot在DBP平台debug环境,1或者其他整数代表online环境,botMonitor对象已经在bot-sdk里初始化,可以直接调用this.botMonitor.setEnvironmentInfo(privateKey, 0);
}你也可以在代码里随时开启和关闭数据统计功能:
//true代表开启,false代表关闭。调用setEnvironmentInfo之后会默认开启this.botMonitor.setMonitorEnabled(false);