【问题标题】:Protocol buffer serialization Golang协议缓冲区序列化 Golang
【发布时间】:2018-05-08 13:39:28
【问题描述】:

我正在使用DialogFlow V2 official GoLang SDK。在我的 webhook 中,我返回了一个有效负载,我使用函数 GetWebhookPayload() 获取该有效负载。

这将返回 *google_protobuf4.Struct。我想把这个结构变成map[string]interface{}。这怎么可能?

这是结构体序列化后的样子:

"payload": {
        "fields": {
            "messages": {
                "Kind": {
                    "ListValue": {
                        "values": [
                            {
                                "Kind": {
                                    "StructValue": {
                                        "fields": {
                                            "title": {
                                                "Kind": {
                                                    "StringValue": "Hi! How can I help?"
                                                }
                                            },
                                            "type": {
                                                "Kind": {
                                                    "StringValue": "message"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        ]
                    }
                }
            }
        }

我本质上需要的是这样序列化它:

"payload": {
    "messages": [
        {
            "title": "Hi! How can I help?",
            "type": "message"
        }
    ]
}

【问题讨论】:

  • 实现unmarshaler接口从json中获取你需要的数据
  • 返回的数据可以是任何格式,没有结构
  • message 键和StringValue 键不会改变吧?
  • messages 不会改变它总是包含一个未知对象的列表
  • 为此使用接口{}并从深层获取值,直到找不到字符串

标签: go protocol-buffers dialogflow-es


【解决方案1】:

这可以使用jsonpb解决。

package main

import (
    "bytes"
    "encoding/json"

    "github.com/golang/protobuf/jsonpb"
)

func main() {
    ...

    payload := qr.GetWebhookPayload()
    b, marshaler := bytes.Buffer{}, jsonpb.Marshaler{}
    if err := marshaler.Marshal(&b, payload.GetFields()["messages"]); err != nil {
        // handle err
    }

    msgs := []interface{}{}
    if err := json.Unmarshal(b.Bytes(), &msgs); err != nil {
        // handle err
    }

    // msgs now populated
}

【讨论】: