/// <summary>
        /// 发送模板消息
        /// </summary>
        /// <param name="appId"></param>
        /// <param name="openId"></param>
        /// <param name="template_id"></param>
        /// <param name="data"></param>
        /// <param name="gotoUrl"></param>
        /// <param name="miniProgramAppId"></param>
        /// <param name="miniProgramPath"></param>
        /// <returns></returns>
        public async Task <ResultReturn> SendTemplateMsg(
            string appId,
            string openId,
            string template_id,
            TemplateMsgDataItem[] data,
            string gotoUrl          = "",
            string miniProgramAppId = "",
            string miniProgramPath  = ""
            )
        {
            var args = new JObject()
            {
                ["touser"]      = openId,
                ["template_id"] = template_id
            };

            var dataJson = new JObject();

            foreach (var item in data)
            {
                dataJson.Add(item.Key, new JObject()
                {
                    ["value"] = item.Value
                });

                if (item.Color.HasValue)
                {
                    dataJson.Add("color", $"#{item.Color.Value.R:X2}{item.Color.Value.G:X2}{item.Color.Value.B:X2}");
                }
            }

            args.Add("data", dataJson);

            args.AddPropertyIf(!string.IsNullOrWhiteSpace(gotoUrl), "url", gotoUrl);
            args.AddPropertyIf(!string.IsNullOrWhiteSpace(miniProgramAppId), "miniprogram", new JObject()
            {
                ["appid"]    = miniProgramAppId,
                ["pagepath"] = miniProgramPath
            });

            var ret = await CommonApi.Post(appId, "/cgi-bin/message/template/subscribe?access_token=ACCESS_TOKEN", args);

            return(ret);
        }
        /// <summary>
        /// 推送消息模板订阅的消息给用户
        /// </summary>
        /// <param name="appId"></param>
        /// <param name="openId">接收者OpenId</param>
        /// <param name="template_id">模板消息ID</param>
        /// <param name="scene">场景值</param>
        /// <param name="title">消息标题</param>
        /// <param name="content">消息内容</param>
        /// <param name="gotoUrl">跳转的链接</param>
        /// <param name="miniProgramAppId">小程序的OpenId,该小程序必须是已和公众号绑定,不需跳小程序可不用传该数据</param>
        /// <param name="miniProgramPath">小程序跳转路径,支持带参数(示例index?foo=bar)</param>
        /// <remarks>
        /// url和miniprogram都是非必填字段,若都不传则模板无跳转;若都传,会优先跳转至小程序。开发者可根据实际需要选择其中一种跳转方式即可。当用户的微信客户端版本不支持跳小程序时,将会跳转至url。
        /// </remarks>
        /// <returns></returns>
        public async Task <ResultReturn> SendSubscribeTemplateToUser(
            string appId,
            string openId,
            string template_id,
            string scene,
            string title,
            string content,
            string gotoUrl          = "",
            string miniProgramAppId = "",
            string miniProgramPath  = ""
            )
        {
            var args = new JObject()
            {
                ["touser"]      = openId,
                ["template_id"] = template_id,
                //["url"] = gotoUrl,
                ["scene"] = scene,
                ["title"] = title,
                ["data"]  = new JObject()
                {
                    ["content"] = new JObject()
                    {
                        ["value"] = content
                    }
                }
            };

            args.AddPropertyIf(!string.IsNullOrWhiteSpace(gotoUrl), "url", gotoUrl);
            args.AddPropertyIf(!string.IsNullOrWhiteSpace(miniProgramAppId), "miniprogram", new JObject()
            {
                ["appid"]    = miniProgramAppId,
                ["pagepath"] = miniProgramPath
            });

            var ret = await CommonApi.Post(appId, "/cgi-bin/message/template/subscribe?access_token=ACCESS_TOKEN", args);

            return(ret);
        }