## 5.6 触发器 >本节主要介绍如何利用开发者后台调用第三方API接口,用户可以在后台自定义触发器来调用接口数据,实现一些复杂的功能。 ### 5.6.1 什么是触发器 ruyi.ai 的开发者后台提供了经典的“用户说”、“机器答”形式的问答对编辑,并提供了实时生效的自定义词典实体编辑,以及可以通过暗号控制的多轮对话等。但是当客户希望自定义实现一些复杂的功能时,那么就需要给意图开发相应的触发器。 触发器是在实体解析、意图识别之后,根据识别的意图和解析的实体进行自定义逻辑处理的功能接口。它可以获取解析到的实体作为参数,在此基础上进行开发,并把结果加入 ruyi.ai 语义接口的返回结果中。如果第三方接口返回的数据不满足需求,还可以对第三方数据进行进一步逻辑处理,触发器上填入“包装”后的接口url即可。 ### 5.6.2 如何使用自定义触发器 ruyi.ai 支持Web API 形式的自定义触发器,支持GET、POST方法,支持自定义header以及json形式的请求体。使用自定义触发器分两步: ①编辑自定义触发器 ②在意图中使用自定义触发器 #### 第一步:编辑自定义触发器 在机器人助理界面的机器人设置中有一个触发器设置,在触发器设置页面中可以添加自定义触发器。 ![](http://gitlab.ruyi.ai/ruyi-ai/ruyi-fuwu/uploads/c988b8961db6abfaf7c417cb1fb833ca/Screen_Shot_2017-06-07_at_1.19.19_PM.png) 在添加自定义触发器时,需要填写自定义触发器的名字,API 的服务地址、请求方法以及需要的 header 信息。 以名人名言机器人为例。 ![](https://box.kancloud.cn/a616f9047a6ff7cdea10fc9e04a7e9ac_1920x1080.png) - 触发器名称:自定义触发器名称,该名称在该机器人下需要唯一。 - URL: Web API的请求地址,API可以使用开放的API网站或自己制作。 - Method:Web API 的请求方法,目前支持 GET、POST 两种方法。 - header:请求所需的 header,可添加多个 header,没有则不填。 - JSON body:当请求需要传递 JSON 格式的请求体时,在文本框中直接编辑JSON,若 JSON 中某个 field 或某处需要引用用户说中实体的值,则以$符号加名称引用,即"$名称".**此处名称与意图界面中意图处理的名称一致。** 下图使用了 JSON body,其中 city 和 name 的值来自于用户说。 ![](http://gitlab.ruyi.ai/ruyi-ai/ruyi-fuwu/uploads/92544faa7f1473105b31a2de8b7dc209/image.png) - 是否缓存:触发器是否使用缓存,选择"ON"的情况下,需要选择缓存周期以及指定缓存的 key,选择"OFF"的情况下,触发器不使用缓存。一般情况下不建议使用` - 缓存周期:如果使用缓存,则需要选择缓存周期,即一个结果会被缓存多长时间。以下拉框形式选择,目前支持1小时,当天,24小时,一周,其中当天是指缓存到当天23:59:59。 - 缓存key:如果使用缓存,需要指定缓存的 key,对于 REST API 来说,请求的结果取决于该请求所传递的参数,而使用缓存的前提是当参数相同时,返回相同的结果,而参数不同时,返回不同的结果,所以缓存的key应该以 API 的参数来构建。` 设置自定义触发器的人应当清楚哪些参数会影响 API 的结果,那么这些参数都应该作为 key 的一部分,这些参数的名称应该都加入缓存 key 中。**此处名称与意图界面中意图处理的名称一致。** 以天气为例,天气 API 接受参数地点和日期,这两个参数决定了 API 的结果,它们在意图处理中的名称分别是 location 和 date,那么缓存 key 就需要填入 location 和 date。 ![](http://gitlab.ruyi.ai/ruyi-ai/ruyi-fuwu/uploads/0061236a44adda8565c7655f6d69f1eb/Screen_Shot_2017-06-07_at_5.10.29_PM.png) #### 第二步:在意图中使用自定义触发器 在意图页面的触发器栏中选择配置好的触发器,如果触发器需要参数,那么我们需要配置触发器的参数。 **触发器参数来源**:自定义触发器的参数可以是用户说的话中的实体,也可以通过默认值的方式传递自定义参数,另外ruyi平台会向自定义触发器传递一些默认参数,比如appId,userId等(见附录1)。 **触发器参数传递方式**:ruyi平台默认参数会直接把参数放入触发器请求的request中,其他自定义参数则通过意图中的意图处理来传递。意图处理中的名称对应 API 中的参数名。来自于用户说的实体参数,开发者后台会自动在意图处理中进行配置,只需要修改**名称**为 API 的参数名即可。自定义参数,比如 AppKey,名称填入参数名,值填入“$"+参数名,类型用@sys.any,然后把参数值填入默认值即可。 以意图名人名言为例。编写好用户说后,在意图处理中进行参数配置。 ![](http://gitlab.ruyi.ai/ruyi-ai/ruyi-fuwu/uploads/eb2afc7b10851e40147c7ef88fd6b2bc/Screen_Shot_2017-06-07_at_2.24.11_PM.png) ![](http://gitlab.ruyi.ai/ruyi-ai/ruyi-fuwu/uploads/788ec2d32749a351563889c83d7645b4/%E8%A7%A6%E5%8F%91%E5%99%A8%E8%AE%BE%E7%BD%AE1.png) 意图名人名言完成后,选择保存,然后就可以在“试一试”中感受对话效果了。以下为试一试中返回成功的JSON。 ``` { "_text": "孔子讲过什么名言", "msg_id": "75da006e-ed6b-4bbf-8519-2dd78364d9cc", "intents": [{ "parameters": { "key": "70617dd808f24244a91b3e2c1a25244f", "keyword": "孔子", "any": "", "名言": "名言" }, "action": "名人名言", "name": "名人名言", "result": { "code": 200, "response": { "total": 29, "result": [{ "famous_name": "孔子", "famous_saying": "君子谋道不谋食,忧道不忧贫。" }, { "famous_name": "孔子", "famous_saying": "鸟之将死,其鸣也哀;人之将死,其言也善。" }, { "famous_name": "孔子", "famous_saying": "自古皆有死,民无信不立。" }, { "famous_name": "孔子", "famous_saying": "君子之道四焉,强于行义,弱于受谏,怵于待禄,慎于治身。" }, { "famous_name": "孔子", "famous_saying": "礼之于人,犹酒之有襞也。" }, { "famous_name": "孔子家语", "famous_saying": "君子以行言,小人以舌言" }, { "famous_name": "孔子", "famous_saying": "其身正,不令而行;其身不正,虽令不行。" }, { "famous_name": "孔子", "famous_saying": "天下之至仁者,能合天之至亲也。" }, { "famous_name": "孔子", "famous_saying": "吾十有五而志于学,三十而立,四十而不惑,五十而知天命,六十而耳顺,七十而从心所欲,不逾矩。" }, { "famous_name": "孔子", "famous_saying": "夫子循循然善诱人,博我以文,约我以礼,欲罢不能。" }, { "famous_name": "孔子", "famous_saying": "民无信不立。" }, { "famous_name": "《孔子家语·三恕》", "famous_saying": "虚则欹,中则正,满则震。" }, { "famous_name": "孔子", "famous_saying": "独学而无友,则孤陋而寡闻。" }, { "famous_name": "苏轼", "famous_saying": "孔子圣人,其学必始于观书。" }, { "famous_name": "《孔子家语》", "famous_saying": "鞭扑之自子,不从父之教。" }, { "famous_name": "孔子", "famous_saying": "不患贫而患不均,不患寡而患不安。" }, { "famous_name": "《孔子家语》", "famous_saying": "良药苦于口而利于病,忠言逆于耳而利于行。" }, { "famous_name": "《孔子家语·颜回·孔子语》", "famous_saying": "君子以行言,小人以舌言。" }, { "famous_name": "孔子", "famous_saying": "益者三友:友直、友谅、友多闻。" }, { "famous_name": "孔子家语", "famous_saying": "君者舟也,庶人者水也。水所以载舟,亦所以覆舟" }], "error_code": 0, "reason": "Succes" }, "text": "【孔子】讲过【独学而无友,则孤陋而寡闻。】", "type": "dialog" }, "outputs": [{ "type": "wechat.text", "property": { "text": "【孔子】讲过【益者三友:友直、友谅、友多闻。】" } }], "score": "1.0", "scoreColor": "c4", "is_match": 1, "id": "3efeeae2-e32c-489b-8471-c11112df5311" }], "meta_process_milliseconds": 81 } ``` ### 附录1 #### ruyi平台触发器默认参数 | 参数名 | 获取方式 | 说明 | | --- | --- | --- | | appId | 直接从request中获取 | Bot对应的appId | | userId | 直接从request中获取 | 该次对话的用户id | | skillAppId | 直接从request中获取 | 触发的技能Bot对应的appId | #### ruyi平台默认暗号携带参数 | 参数名 | 获取方式 | 说明 | | --- | --- | --- | | 自定义 | 通过意图处理获取,意图处理”值“的一栏填入#ruyi_default_context.last_result.xxx,xxx对应上次触发器结果中所需字段的路径 | ruyi默认暗号携带的参数,可以从中获取上次触发器的结果 | | 自定义 | 通过意图处理获取,意图处理”值“的一栏填入#ruyi_default_context.last_q | ruyi默认暗号携带的参数,对应上次对话中用户说的话 | | 自定义 | 通过意图处理获取,意图处理”值“的一栏填入#ruyi_default_context.curr_q | uyi默认暗号携带的参数,对应本次对话中用户说的话 |