以前做过微信对接,但好久没做了,又忘记了,现在从新记录一下。开发使用的是.net 8.0框架,下面代码都是在此框架下的,复制粘贴不能用可能是目标框架不一样。
微信公众号Api地址
登录公众平台后,进入后台页面,本以为菜单里面的“接口权限“就是接口介绍,看了半天也没有找到,发布文章的接口。后台网上查找了一下查才发现,这个不是,微信公众号的开发文档是
➤ https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html
头有点大,至于腾讯的开发文档,不是一次听到同事吐槽了。终于找到正确位置了:
原理
文章同步到微信公众号的原理就是
1.新建草稿:➤ https://developers.weixin.qq.com/doc/offiaccount/Draft_Box/Add_draft.html
2.发布:➤ https://developers.weixin.qq.com/doc/offiaccount/Publish/Publish.html
新增草稿时:图文消息的具体内容,支持HTML标签,必须少于2万字符,小于1M,且此处会去除JS,涉及图片url必须来源 "上传图文消息内的图片获取URL"接口获取。外部图片url将被过滤。文章中图片还要单独处理,要解析文章,图片还要使用微信接口单独上传,将其中的图片地址替换为,上传到微信公众号的图片。
一、获取access_token
先是获取access_token,我是.net7.0的框架,下面是请求,代码还是比较简单 (Identity 是我用来存储appid和appSecret的类),token 有效时间是2个小时,建议放缓存或者数据保存,过期了再申请,会有申请次数限制,不停申请,可能会申请失败噢。
var client = httpClientFactory.CreateClient(WeChatConsts.HttpClientName);
var requestUrl = string.Format(Api.Access_Token_Url, GrantTypes.ClientCredential, identity.AppId, identity.AppSecret);
var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, requestUrl));
var result = await response.Content.ReadAsStringAsync();
var resultJson = JObject.Parse(result);
才访问接口都报错,需要白名单,在本地调试那来什么白名单,还要有测试账号。
{"errcode":40164,"errmsg":"invalid ip 116.249.0.118 ipv6 ::ffff:116.249.0.118, not in whitelist rid: 65123627-505e897f-2d012c9b"}
在“接口测试号申请”->"进入微信公众号测试号申请系统",里面有测试账号,
二、创建草稿
创建草稿最大问题是图片的,先上解析文章的图片,把图片单独上传,还有记录地址。文档里面 "上传图文消息内的图片获取URL"接口获取,这么一句好,还真不知道哪里找,这就文档坑爹,对新手太不友好了。首先到素材管理,找到永久素材的上传和获取。把图片上传,文章中的图片要的是地址,而封面要的是id,不同接口返回的内容是不一样的,这就要使用两个接口,难受啊。
先上传封面,根据提供的接口提交文件,封面上传成功,再上传文章中的图片,这里使用uploadimg接口,这个接口不占用素材数量限制,所以你加多少都没关系,这也是为什么不用上面素材接口的原因吧。代码可以参照上面的,这个接口就不需要type,自己修改一下就行了。
添加草稿
添加草稿,需要自己把文章中的图片解析出来上传,替换图片地址,还有封面上传后的得到的Id,接口需要的参数如下:
{
"articles": [
{
"title":TITLE,
"author":AUTHOR,
"digest":DIGEST,
"content":CONTENT,
"content_source_url":CONTENT_SOURCE_URL,
"thumb_media_id":THUMB_MEDIA_ID,
"need_open_comment":0,
"only_fans_can_comment":0
}
//若新增的是多图文素材,则此处应还有几段articles结构
]
}
实现代码
// 解析文章中的图片
article.Content = await ReplaceImageUrl(article.Content, blobContainer);
var token = await GetAccessTokenAsync();
var url = string.Format(Api.AddDraft, token.AccessTokenStr);
var client = httpClientFactory.CreateClient(WeChatConsts.HttpClientName);
///请求消息
var requestMessage = new HttpRequestMessage(HttpMethod.Post, url);
List<ArticleRequest> articles = new List<ArticleRequest>() { article };
var paras = JsonConvert.SerializeObject(new { articles = articles });
// 请求的form内容
var postContent = new StringContent(paras);
requestMessage.Content = postContent;
var responseString = await (await client.SendAsync(requestMessage)).Content.ReadAsStringAsync();
MediaReponse mediaReponse = JsonConvert.DeserializeObject<MediaReponse>(responseString);
提交成功后会得到一个media-id,此文章的唯一标识,发布时需要用到。
发布草稿
文章添加后并不会马上就发布,需要我们自己调用接口来发布,发布成功后会返回一个publish_id,可用于状态查询。
var token = await GetAccessTokenAsync();
var url = string.Format(Api.FreePublish, token.AccessTokenStr);
var client = httpClientFactory.CreateClient(WeChatConsts.HttpClientName);
///请求消息
var requestMessage = new HttpRequestMessage(HttpMethod.Post, url);
var paras = JsonConvert.SerializeObject(new { media_id = mediaId });
// 请求的form内容
var postContent = new StringContent(paras);
requestMessage.Content = postContent;
var responseStr = await (await client.SendAsync(requestMessage)).Content.ReadAsStringAsync();
查询发布结果
发布后的文章是需要审核的,审核会有一个回调地址,配一下就可以了。我们也可以主动查询发布状态。
查询实现和发布代码一样,只是改了一下参数。
var token = await GetAccessTokenAsync();
var url = string.Format(Api.GetPublishStatus, token.AccessTokenStr);
var client = httpClientFactory.CreateClient(WeChatConsts.HttpClientName);
///请求消息
var requestMessage = new HttpRequestMessage(HttpMethod.Post, url);
var paras = JsonConvert.SerializeObject(new { publish_id = publishId });
// 请求的form内容
var postContent = new StringContent(paras);
requestMessage.Content = postContent;
var responseStr = await (await client.SendAsync(requestMessage)).Content.ReadAsStringAsync();
在对接过程中接口都会返回对应的业务数据,我是将其保存到数据库中,根据业务不同,可以灵活处理。
这样几步下来基本已经完成了公众号发布文章的难题,以上这些代码也是本博客开发时,截取的,要看效果也可以直接查看本博客的公众号。