微信公众号的模板消息接口允许开发者为每个参数字段指定颜色,比如金额用红色突出、时间用灰色弱化,这样推送出来的卡片信息层次感更强。不过颜色值必须严格按照#RRGGBB的十六进制格式传入,一旦手抖多写一位或者漏掉井号,接口就会直接报错。与其每次都手动查色值表,不如自己动手写一个小工具,把取色、格式校验、代码生成这几步全部自动化。

一、模板消息中颜色参数的工作原理
先看接口层面的规则。调用模板消息接口时,请求体中的data字段是一个JSON对象,每个参数的值都是一个包含value和color两个属性的对象,其中color就是颜色代码。下面是一个典型的请求示例:
{
"touser": "OPENID",
"template_id": "TEMPLATE_ID",
"url": "https://ipipp.com/detail",
"data": {
"first": {
"value": "您的订单已发货",
"color": "#173177"
},
"keyword1": {
"value": "iPhone 15 Pro",
"color": "#FF0000"
},
"keyword2": {
"value": "2024-06-01 12:30:00",
"color": "#888888"
},
"remark": {
"value": "请保持手机畅通,等待快递联系",
"color": "#173177"
}
}
}这里需要特别注意三点。第一,color字段必须以#开头,后面紧跟六位十六进制字符,大小写都兼容,但写成#RGB三位缩写形式是不被支持的,会被判为invalid color。第二,即使不想指定颜色,也建议显式传入默认色#173177,而不是省略color字段,某些账号版本下省略会导致渲染异常。第三,颜色值是字符串类型,不要误传成数字。
从产品角度看,颜色的作用是引导用户视线。标题类字段一般用微信官方推荐的深蓝色#173177,金额、状态等关键信息用#FF0000红色或者#FFA500橙色突出,时间、单号这类辅助信息用#888888灰色弱化。理解了这套搭配逻辑,工具的输出才有实际意义,而不是随机给一堆刺眼的颜色。
二、用JavaScript实现颜色代码生成器
工具的核心思路是:提供一个可视化取色器,用户选定颜色后,自动转换成符合规范的六位十六进制字符串,并提供复制到剪贴板的功能。HTML5原生的input类型为color的取色控件可以直接满足需求,浏览器会弹出系统调色板,取值本身就是#RRGGBB格式,省去了自己解析RGB的麻烦。
<div class="color-tool">
<label>选择颜色:</label>
<input type="color" id="picker" value="#173177">
<input type="text" id="colorCode" readonly>
<button id="copyBtn">复制代码</button>
<span id="tips"></span>
</div>
<script>
const picker = document.getElementById('picker');
const codeInput = document.getElementById('colorCode');
const tips = document.getElementById('tips');
picker.addEventListener('input', function () {
// 原生取色器的值就是 #RRGGBB 格式,直接校验后输出
const val = picker.value;
if (/^#[0-9A-Fa-f]{6}$/.test(val)) {
codeInput.value = val.toUpperCase();
tips.textContent = '格式合法,可直接用于模板消息';
}
});
document.getElementById('copyBtn').addEventListener('click', function () {
codeInput.select();
document.execCommand('copy');
tips.textContent = '已复制:' + codeInput.value;
});
</script>正则表达式/^#[0-9A-Fa-f]{6}$/是整个校验的关键,它确保输出永远是井号加六位十六进制字符。有些开发者会在中间做一层RGB到十六进制的转换,比如从滑块分别取红绿蓝三通道的值,再用toString(16)拼接,这种方式灵活度更高,还能做透明度扩展,但要注意单通道值小于16时转换出来只有一位,必须用padStart(2, '0')补零,否则会生成#8808这种非法值。
再进一步,可以把单个取色器扩展为字段列表生成器:为first、keyword1、keyword2、remark分别配一行取色控件,点击生成按钮后直接输出完整的data JSON片段,复制后粘贴进自己的代码或者调试工具即可。这个功能用十几行代码就能实现,却能省掉大量机械劳动。
三、服务端封装与随机配色策略
前端工具解决的是编写阶段的问题,服务端封装解决的是运行阶段的问题。建议把颜色配置集中管理,封装成一个统一的构造函数,避免散落在各处的硬编码色值。下面是一个PHP版本的示例思路:
<?php
class TemplateColor
{
// 预置常用配色方案
private static $presets = [
'title' => '#173177', // 标题深蓝
'amount' => '#FF0000', // 金额红色
'status' => '#FFA500', // 状态橙色
'muted' => '#888888', // 辅助灰色
];
// 根据字段名自动匹配合适的颜色
public static function pick($field)
{
$map = [
'first' => 'title',
'remark' => 'title',
'amount' => 'amount',
'time' => 'muted',
];
$key = $map[$field] ?? 'title';
return self::$presets[$key];
}
// 组装单个参数节点
public static function build($value, $field)
{
return ['value' => $value, 'color' => self::pick($field)];
}
}这样在业务代码里调用TemplateColor::build('99.00元', 'amount')就能得到完整的参数节点,颜色策略调整时只改配置数组即可。如果希望每个用户看到的颜色略有差异,还可以实现随机配色,但随机不能真的全随机,应该在预设的和谐色板里随机抽取,否则生成的颜色对比度失控,在手机屏幕上可能根本看不清。一个简单的办法是准备十组经过验证的配色组合,按用户标识取模选择。
最后提醒两个容易踩的坑。一是模板消息接口对参数校验非常严格,任何一个color字段格式错误,整条消息都会发送失败并返回错误码,调试时建议先把所有color注释掉验证基础链路,再逐个加回颜色。二是同一个模板ID下的字段数量和顺序由模板本身决定,工具生成的JSON必须与模板字段一一对应,多传的参数会被忽略,少传的会显示为空,上线前用测试号完整走一遍流程最稳妥。