【微信公众号】如何上传客服头像
1. 前言
哎呦,刚刚被恶心坏了,用了一个上午+一个下午的时间来找问题。卡了我一天的时间。看看下面的文档吧。
只能说这个文档去除大部分的示例,留下一点点curl请求。不能说有用吧,只能说有一点点指导作用。
2. 构建请求
从刚开看这文档来气,到最后麻木,只用了一天。行吧,我们来回顾整个过程。因为我用的技术栈是EggJs,所以顺理成章的用了curl
这个方法,把我给坑坏了。来看看v1版本的代码:
// project_path/app/service/customer.js
const Service = require('egg').Service;
const fse = require('fs-extra');
const path = require('path');
class CustomerService extends Service {
/** * 上传客服头像 * @param {string} account 客服账号 * @returns 成功或失败原因 */
async uploadAvatarAccount(account) {
const {ctx} = this;
const {ERR_MAP} = ctx.app.config;
try {
const token_result = await ctx.service.wx.getAssessToken();
if (token_result.errCode) return token_result;
const avatar = await fse.readFile(path.resolve(__dirname,'./../static/avatar-2.jpg'));
//看这个请求方式
const result = await ctx.app.curl(`https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=${token_result}&kf_account=${account}@wx_official_id`,{
method:'post',
contentType:'form',
dataType:'json',
data:{
media:file
}
});
if (result.status !== 200) {
ctx.logger.warn(`【客服账号上传头像错误】${JSON.stringify(result,null,2)}`);
return ERR_MAP.REQUEST;
}
const {errcode} = result.data;
if (errcode !== 0) {
ctx.logger.warn(`【客服账号上传头像错误】错误码:${JSON.stringify(result.data,null,2)}`);
return ERR_MAP.REQUEST;
}
return 'success';
} catch(e) {
ctx.logger.warn(`【客服账号上传头像错误】${e}`);
return ERR_MAP.REQUEST;
}
}
}
module.exports = CustomerService;
正如上面代码所示,出来的请求结果是这个:
{
errcode: 41005,
errmsg: 'media data missing hint: [ehHb1Aore-a6KNRA] rid: 6412c0b6-391d3558-15b56dc7'
}
没有上传成功,看了下Eggjs的HttpClient的文档,原来是因为data不能作为文件上传的参数,而是要使用files
参数,行吧……
3. 上传文件的尝试
来看看v2的版本吧……
// project_path/app/service/customer.js
const Service = require('egg').Service;
const fse = require('fs-extra');
const path = require('path');
class CustomerService extends Service {
/** * 上传客服头像 * @param {string} account 客服账号 * @returns 成功或失败原因 */
async uploadAvatarAccount(account) {
const {ctx} = this;
const {ERR_MAP} = ctx.app.config;
try {
const token_result = await ctx.service.wx.getAssessToken();
if (token_result.errCode) return token_result;
const avatar = await fse.readFile(path.resolve(__dirname,'./../static/avatar-2.jpg'));
//看这个请求方式
const result = await ctx.app.curl(`https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=${token_result}&kf_account=${account}@wx_official_id`,{
method:'post',
contentType:'form',
dataType:'json',
+ files:file,
- data:{
- media:file
- }
});
if (result.status !== 200) {
ctx.logger.warn(`【客服账号上传头像错误】${JSON.stringify(result,null,2)}`);
return ERR_MAP.REQUEST;
}
const {errcode} = result.data;
if (errcode !== 0) {
ctx.logger.warn(`【客服账号上传头像错误】错误码:${JSON.stringify(result.data,null,2)}`);
return ERR_MAP.REQUEST;
}
return 'success';
} catch(e) {
ctx.logger.warn(`【客服账号上传头像错误】${e}`);
return ERR_MAP.REQUEST;
}
}
}
module.exports = CustomerService;
请求一下,发现出现下面的问题:
{
errcode: 40005,
errmsg: 'invalid file type hint: [IhHb2uHae-bexQta] rid: 6412c2b8-0b7ecfa4-2ac30cab'
},
非法的文件类型?搜索了下微信公众号官方的社区,可能是文件名和上传的文件名不同的原因。我在想,有没有一种可能:上传的文件就没有文件名。这个curl就没有地方给我放文件名的地方,就算如下添加了文件名:
/** * 省略以上代码 * more code.... */
const result = await ctx.app.curl(`https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=${token_result}&kf_account=${account}@wx_official_id`,{
method:'post',
contentType:'form',
dataType:'json',
+ files:file,
+ dataAsQueryString:true,
+ data:{
+ media:'avatar.jpg'
+ }
});
/** * 省略以上代码 * more code.... */
还是非法文件类型。我想想是不是请求头有问题啊?然后添加了beforeRequest方法看看
/** * 省略以上代码 * more code.... */
const result = await ctx.app.curl(`https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=${token_result}&kf_account=${account}@wx_official_id`,{
method:'post',
contentType:'form',
dataType:'json',
+ files:file,
+ dataAsQueryString:true,
+ data:{
+ media:'avatar.jpg'
+ },
+ beforeRequest:(options) => {
+ console.log(options.headers);
+ }
});
/** * 省略以上代码 * more code.... */
看看请求头,发现还不如不看呢……
{
'content-type': 'multipart/form-data; boundary=--------------------------101357776524923229718969',
'content-length': '3608',
accept: 'application/json'
}
emmmm,后来查了别人关于form-data上传的前端示例。如果上传多个file的话,每个file都有其自己的filename和name,那么后端eggjs怎么做呢?于是我试了试axiosjs。
5. 还是Axios好用
最终版的代码……
// project_path/app/service/customer.js
const Service = require('egg').Service;
const fse = require('fs-extra');
const path = require('path');
+ const axios = require('axios');
+ const FormData = require('form-data');
class CustomerService extends Service {
/** * 上传客服头像 * @param {string} account 客服账号 * @returns 成功或失败原因 */
async uploadAvatarAccount(account) {
const {ctx} = this;
const {ERR_MAP} = ctx.app.config;
try {
const token_result = await ctx.service.wx.getAssessToken();
if (token_result.errCode) return token_result;
- const avatar = await fse.readFile(path.resolve(__dirname,'./../static/avatar-2.jpg'));
+ const file = await fse.readFile(path.resolve(__dirname,'./../static/avatar-2.jpg'));
+ const form = new FormData();
+ form.append('media',file,'avatar-2.jpg');
//看这个请求方式
- const result = await - -ctx.app.curl(`https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?-access_token=${token_result}&kf_account=${account}@wx_official_id`,{
- method:'post',
- contentType:'form',
- dataType:'json',
- files:file,
- data:{
- media:file
- }
});
+ const result = await axios({
url:`https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=${token_result}&kf_account=${account}@wx_official_id`,
+ method:'post',
+ data:form,
+ });
if (result.status !== 200) {
ctx.logger.warn(`【客服账号上传头像错误】${JSON.stringify(result,null,2)}`);
return ERR_MAP.REQUEST;
}
const {errcode} = result.data;
if (errcode !== 0) {
ctx.logger.warn(`【客服账号上传头像错误】错误码:${JSON.stringify(result.data,null,2)}`);
return ERR_MAP.REQUEST;
}
return 'success';
} catch(e) {
ctx.logger.warn(`【客服账号上传头像错误】${e}`);
return ERR_MAP.REQUEST;
}
}
}
module.exports = CustomerService;
于是,就成功了。我的感受就是,这微信公众号文档写的什么啊,什么示例都没有,都这么久了,写了一点点,不能写多了。我佛了……
今天的文章【微信公众号】如何上传客服头像分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/21537.html