示例编写程序5 如何在不同的端上渲染自己想要的回复效果

在很多会话端上,应用开发者会开发自己的H5页面,并创造一些个性化的卡片,比如标题文本卡片、图片卡片、点选卡片等,这些卡片可以在不同的会话端被渲染成不同的样式,但是数据存储的结构是相同的。例如,在某个业务的会话端中,标题文本卡片的数据格式如下:

文本卡片数据格式

{
    "cardType": "TextCard",
    "content": {
        "title": "your title",
        "text": "your text"
    }
}

一般情况下, 开发者希望将调用第三方接口返回的数据,通过格式转换,变成期待的卡片数据格式,以达到动态生成卡片的效果。例如,在查天气的例子当中,开发者希望根据实时查询到的天气结果,动态生成标题卡片数据,生成的卡片如下:

{
    "cardType": "TextCard",
    "content": {
        "title": "2018-08-30",
        "text": "Temperature is 28"
    }
}

首先构建对话流,如下图所示:

image.png

其中“调用查天气API”节点为调用第三方查天气接口的函数节点,“动态生成卡片数据”节点为自定义代码函数节点。第三方查天气接口返回的数据格式如下:

HTTP接口返回数据格式

{
    "forecast": [
    {
        "date": "2018-08-30",
        "temperature": "28"
    },
    {
        "date": "2018-08-31",
        "temperature": "30"
    }
    ]
}

示例代码

在“动态生成卡片数据”函数节点中,关联到一个函数计算Function,在代码中,首先将eventObj中的lastOutputForFunction字段反序列化成Object,然后将它其中的forecast[0]的date和temperature字段用于构造卡片对象card,最后将card序列化成字符串格式赋值给overrideResponse的htmlText字段。overrideResponse的htmlText字段一旦被赋值后,机器人这轮对话最终的输出就将是这个值。

Node.js

module.exports.handler = function(event, context, callback) {
    /** event structure definition
    For more details please VIEW DOCS HERE: https://lark.alipay.com/docs/share/1b48172d-0814-4a28-9ea0-3686a5bdb4a0
    {
      // read-only variables
      "environment": "Object",
      "lastOutputForFunction": "String",
      "slotSummary": "Object",

      // read/write variables
      "global": "Object",
      "outputForResponse": "Object",
      "outputForFunction": "String",
      "routeVariable": "String"
    }
    **/

    try {
        var eventObj = JSON.parse(event);
        // // add your code here
        var lastFunctionOutput = JSON.parse(eventObj.lastOutputForFunction);

        var todayForecast = lastFunctionOutput.forecast[0];
        var date = todayForecast.date;
        var temp = todayForecast.temperature; 
        var card = {};
        card["cardType"] = "TextCard";
        card["content"] = {"title": date, "text":"Temperature is " + temp};
        eventObj.overrideResponse.htmlText = [JSON.stringify(card)];

        eventResult = JSON.stringify(eventObj);
        callback(null, eventResult);
    } catch (e) {
        console.log(e);
        eventResult = JSON.stringify(eventObj);
        callback(null, eventResult);
        //callback(null, e);
    }
};

Python

# -*- coding: utf-8 -*-
import logging  
import json

def handler(event, context):
  logger = logging.getLogger()
  logger.info(event)
  eventObj = json.loads(event)

  lastFunctionOutput = json.loads(eventObj['lastOutputForFunction'])
  todayForecast = lastFunctionOutput['forecast'][0]
  date = todayForecast['date']
  temp = todayForecast['temperature']

  card = {'cardType': 'TextCard'}
  card['content'] = {'title': date, 'text': 'Temperature is ' + temp}
  eventObj['overrideResponse'] = {'htmlText':[json.dumps(card)]}

  return eventObj

Java

package com.aliyun.openservices.tcp.example.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.PojoRequestHandler;

/**
 * Created by weili on 2018/8/2.
 *
 * @author weili
 * @date 2018/08/02
 */
public class FunctionHandler implements PojoRequestHandler<JSONObject, JSONObject> {
    @Override
    public JSONObject handleRequest(JSONObject eventObj, Context context) {

        /**
         *  eventObj structure definition
         *
         *  read-only variables
         *  "environment": "Object",
         *  "lastOutputForFunction": "String",
         *  "slotSummary": "Object",
         *
         *  read/write variables
         *  "global": "Object",
         *  "overrideResponse": "Object",
         *  "functionOutput": "String",
         *  "routeVariable": "String"
         */

        JSONObject lastFunctionOutput = JSON.parseObject(eventObj.getString("lastOutputForFunction"));
        JSONObject todayForecast = lastFunctionOutput.getJSONArray("forecast").getJSONObject(0);
        String date = todayForecast.getString("date");
        String temp = todayForecast.getString("temperature");

        JSONObject card = new JSONObject();
        card.put("cardType", "TextCard");
        JSONObject content = new JSONObject();
        content.put("title", date);
        content.put("text", "Temperature is " + temp);
        card.put("content", content);

        JSONArray htmlText = new JSONArray();
        htmlText.add(card.toJSONString());
        JSONObject overrideResponse = new JSONObject();
        overrideResponse.put("htmlText", htmlText);
        eventObj.put("overrideResponse", overrideResponse);

        return eventObj;
    }
}