功能解释

UserEvent网关事件是通过向天猫精灵网关上报事件,触发技能端的调用。
注意:由于本地调试不带技能信息,该功能测试,必须将包上传到技能平台,进行真机测试绑定,然后通过语音唤起应用
image.png

DOM切面方式上报UserEvent

指定onTap为$userEvent情况下,框架自动会按照UserEvent上报,更加快捷

  1. <div class="operation-button" onTap="$userEvent" data-action="home-action1">界面1-进功能</div>

对应的字段为

type 自动填充标签 当前事件的类型,默认为click
target.dataset 自动填充data- 参考web:https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLOrForeignElement/dataset
target.tagName 自动填充当前标签名 如div, image等
timestamp 自动填充 事件触发的时间

dom切面自动上报的数据格式

  1. {
  2. "eventDomain":"AliGenie.Routine",
  3. "eventName":"EventIssued",
  4. "eventData":{
  5. "eventIssuedContext":{
  6. "eventDetail":{
  7. "type":"click",
  8. "target":{
  9. "dataset":{
  10. "action":"home-action1"
  11. },
  12. "tagName":"div"
  13. },
  14. "timeStamp":1626062006132
  15. },
  16. "coinEventNs":"ScreenScene",
  17. "coinEventName":"UserEvent"
  18. }
  19. }
  20. }

调用接口自定义上报UserEvent

axml标签

  1. <div class="operation-button" onTap="operationButtonTap" data-action="home-action1">界面1-进功能</div>

as逻辑代码

  1. this.addEventListener("operationButtonTap", (e: Event)=>{
  2. // 携带点击事件的dom信息的初始化方法,节点信息会携带到target
  3. // const userEvent = UserEvent.initWithEvent(e);
  4. // 初始化UserEvent
  5. const userEvent = new UserEvent("operationButtonTap");
  6. userEvent.data.set("action","home-action1");
  7. agui.sendUserEvent(userEvent);
  8. });

自定义上报数据格式:

  1. {
  2. "eventDomain":"AliGenie.Routine",
  3. "eventName":"EventIssued",
  4. "eventData":{
  5. "eventIssuedContext":{
  6. "eventDetail":{
  7. "type":"operationButtonTap",
  8. "data":{
  9. "action":"home-action1"
  10. }
  11. },
  12. "coinEventNs":"ScreenScene",
  13. "coinEventName":"UserEvent"
  14. }
  15. }
  16. }

技能端接收处理方式:

权限开通

image.png

意图触发

注意:只有默认意图会接收到网关事件
image.png

处理逻辑(以Java为例)

  1. @Bean
  2. public Function<String, String> carTestFunction(Context context) {
  3. logger = context.getLogger();
  4. return it -> {
  5. try {
  6. String action = null;
  7. logger.log("wph_card_test param : " + it);
  8. if(StringUtils.isBlank(it)){
  9. return speak(1,it);
  10. }
  11. Map itMap = JSON.parseObject(it, Map.class);
  12. if(itMap==null || null==itMap.get("requestInfo")){
  13. return speak(2,itMap);
  14. }
  15. // 获取requestInfoMap
  16. Map requestInfoMap = (Map) itMap.get("requestInfo");
  17. if(requestInfoMap==null || null==requestInfoMap.get("requestData")){
  18. return speak(3,requestInfoMap);
  19. }
  20. //语音 - 讲故事
  21. if(isSpeakStory(requestInfoMap)){
  22. return render(Contants.two_page);
  23. }
  24. //语音 - 不玩了
  25. if(noMore(requestInfoMap)){
  26. return render(Contants.one_page);
  27. }
  28. // 获取requestData
  29. Map requestDataMap = (Map) requestInfoMap.get("requestData");
  30. if(requestDataMap==null ){
  31. return speak(4,requestDataMap);
  32. }
  33. String jsonStr = Contants.default_render;
  34. // 获取eventDetail里的信息,进行判断
  35. Map<String, String> requestData = requestDataMap;
  36. String eventIssuedContext = requestData.get("eventIssuedContext");
  37. if (StringUtils.isNotBlank(it) && itMap != null && requestInfoMap != null && requestDataMap != null
  38. &&StringUtils.isNotBlank(eventIssuedContext)) {
  39. if(eventIssuedContext==null ){
  40. return speak(5,eventIssuedContext);
  41. }
  42. Map targetMap = JSON.parseObject(eventIssuedContext, Map.class);
  43. if(targetMap==null || null == targetMap.get("eventDetail")){
  44. return speak(6,targetMap);
  45. }
  46. // 获取eventDetail里的信息,进行判断
  47. JSONObject eventDetailJsonObject = (JSONObject) targetMap.get("eventDetail");
  48. if(eventDetailJsonObject==null || null == eventDetailJsonObject.get("target")){
  49. return speak(7,eventDetailJsonObject);
  50. }
  51. JSONObject targetJsonObj = (JSONObject) eventDetailJsonObject.get("target");
  52. if(targetJsonObj==null || null == targetJsonObj.get("dataset")){
  53. return speak(8,targetJsonObj);
  54. }
  55. // 对dataSet(dom上绑定的信息)进行判断
  56. JSONObject dataset2 = (JSONObject) targetJsonObj.get("dataset");
  57. action = dataset2.getString("action");
  58. logger.log("进入卡片测试技能-wph-action:{}" + action);
  59. if ("home-action1".equals(action)) {
  60. jsonStr = Contants.two_page;
  61. } else if ("detail-action1".equals(action)) {
  62. jsonStr = Contants.one_page;
  63. } else {
  64. //播放语音
  65. PlayTtsCommand tts = FaasSkillResponseUtils.buildTtsCommand("我还不明白你要干什么wph正常播报", true);
  66. tts.setWakeupType("continuity");
  67. FaasSkillResponse.FaasSkillResponseBuilder builder = FaasSkillResponse.builder();
  68. builder.commands(Arrays.asList(tts));
  69. ResultModel<TaskResult> taskResultResultModel = outputForCardTest(builder.build());
  70. TaskResult returnValue = taskResultResultModel.getReturnValue();
  71. return JSON.toJSONString(returnValue);
  72. }
  73. }
  74. logger.log("进入卡片测试技能-wph");
  75. return render(jsonStr);
  76. } catch (Exception e) {
  77. e.printStackTrace();
  78. logger.log("解析json错误:" + e.getMessage());
  79. return speakMsg("我还不明白你要干什么wph异常播报异常信息" +e.getMessage());
  80. }
  81. };
  82. }
  1. /**
  2. * 是否讲故事
  3. * @param requestInfoMap
  4. * @author wph01011689
  5. * @date 2021/7/5 12:45
  6. * @Return boolean
  7. */
  8. public boolean isSpeakStory(Map requestInfoMap){
  9. String utterance = (String) requestInfoMap.get("utterance");
  10. if(StringUtils.isBlank(utterance)){
  11. return false;
  12. }
  13. if("讲故事".equals(utterance.trim()) || utterance.trim().contains("讲故事")){
  14. return true;
  15. }
  16. return false;
  17. }