前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微信公众平台开发(二)——自定义菜单、模板消息&微信素材

微信公众平台开发(二)——自定义菜单、模板消息&微信素材

作者头像
不愿意做鱼的小鲸鱼
发布2023-03-25 11:55:05
1.2K0
发布2023-03-25 11:55:05
举报
文章被收录于专栏:web全栈

获取AccessToken

access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。

官方文档:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html

1. 新建一个AccessToken对象

代码语言:javascript
复制
package cn.kt.mywxdemo.token;

/**
 * Created by tao.
 * Date: 2023/3/7 16:26
 * 描述:
 */
public class AccessToken {
    private String token;
    private long expireTime;

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public long getExpireTime() {
        return expireTime;
    }

    public void setExpireTime(long expireIn) {
        this.expireTime = System.currentTimeMillis() + expireIn * 1000;
    }

    /**
     * 判断是否超时
     *
     * @return
     */
    public boolean isExpired() {
        return System.currentTimeMillis() > this.expireTime;
    }
}

2. 新建一个TokenUtil工具类

代码语言:javascript
复制
package cn.kt.mywxdemo.token;

import cn.kt.mywxdemo.utils.HttpUtil;
import net.sf.json.JSONObject;

/**
 * Created by tao.
 * Date: 2023/3/7 16:26
 * 描述:
 */
public class TokenUtil {

    private static final String APP_ID = "wx90a9158b6acc5584";
    private static final String APP_SECRET = "ec23a5d78f12afa569c64794570d753c";
    private static AccessToken accessToken = new AccessToken();

    public static void main(String[] args) {
        //{"access_token":"63_8R2EcPuM3dz_D81Q2FBiSfgrlwokafQloAU33iFhHIbjabRFtC_thRqk7VOkMbarQ8lA9yyq2pgwh4pc6P-5qQutc6WWMLwFafIR6ZaLkB299OJU78npFt--I0ACXCiACAHCH","expires_in":7200}
        System.out.println(getAccessToken());
    }

    private static void getToken() {
        String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
                APP_ID,
                APP_SECRET);
        String result = HttpUtil.doGet(url);
        JSONObject jsonObject = JSONObject.fromObject(result);
        String token = jsonObject.getString("access_token");
        long expiresIn = jsonObject.getLong("expires_in");
        accessToken.setToken(token);
        accessToken.setExpireTime(expiresIn);
    }

    /**
     * 获取AccessToken
     *
     * @return
     */
    public static String getAccessToken() {
        if (accessToken == null || accessToken.isExpired()) {
            getToken();
        }
        return accessToken.getToken();
    }
}

之后AccessToken存了静态,过期可以自动更新可以直接使用TokenUtil.getAccessToken()获取

自定义菜单

自定义菜单功能介绍

自定义菜单能够帮助公众号丰富界面,让用户更好更快地理解公众号的功能。开启自定义菜单后,公众号界面如图所示:

自定义菜单接口可实现多种类型按钮,如下:

具体的参数详情和请求示例可以查看官方文档:https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Creating_Custom-Defined_Menu.html

下面使用代码多态的方式实现:

  1. 一级菜单,二级菜单
  2. 点击类型按钮
  3. 跳转类型按钮
  4. 拍照或者相册选择事件按钮

代码实现如下

  1. 抽象类AbstractButton
代码语言:javascript
复制
package cn.kt.mywxdemo.button;

/**
 * Created by tao.
 * Date: 2023/3/7 17:11
 * 描述:
 */
public abstract class AbstractButton {
    private String name;

    public AbstractButton(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
  1. 菜单父类Button
代码语言:javascript
复制
package cn.kt.mywxdemo.button;

import java.util.List;

/**
 * Created by tao.
 * Date: 2023/3/7 17:11
 * 描述:
 */
public class Button {
    private List<AbstractButton> button;

    public List<AbstractButton> getButton() {
        return button;
    }

    public void setButton(List<AbstractButton> button) {
        this.button = button;
    }
}
  1. 二级菜单类SubButton
代码语言:javascript
复制
package cn.kt.mywxdemo.button;

import java.util.List;

/**
 * Created by tao.
 * Date: 2023/3/7 17:18
 * 描述:
 */
public class SubButton extends AbstractButton {
    public SubButton(String name) {
        super(name);
    }

    private List<AbstractButton> sub_button;

    public List<AbstractButton> getSub_button() {
        return sub_button;
    }

    public void setSub_button(List<AbstractButton> sub_button) {
        this.sub_button = sub_button;
    }
}
  1. 点击类型按钮类ClickButton
代码语言:javascript
复制
package cn.kt.mywxdemo.button;

/**
 * Created by tao.
 * Date: 2023/3/7 17:13
 * 描述:
 */
public class ClickButton extends AbstractButton{
    public ClickButton(String name) {
        super(name);
        this.type = "click";
    }

    private String type;
    private String key;

    public String getType() {
        return type;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}
  1. 跳转类型按钮类ViewButton
代码语言:javascript
复制
package cn.kt.mywxdemo.button;

/**
 * Created by tao.
 * Date: 2023/3/7 17:22
 * 描述:
 */
public class ViewButton extends AbstractButton {

    public ViewButton(String name, String url) {
        super(name);
        this.type = "view";
        this.url = url;
    }

    private String type;
    private String url;

    public String getType() {
        return type;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}
  1. 拍照或者相册选择事件按钮类PhotoOrAlbumButton
代码语言:javascript
复制
package cn.kt.mywxdemo.button;

/**
 * Created by tao.
 * Date: 2023/3/7 17:15
 * 描述:
 */
public class PhotoOrAlbumButton extends AbstractButton {
    public PhotoOrAlbumButton(String name, String key) {
        super(name);
        this.type = "pic_photo_or_album";
        this.key = key;

    }

    private String type;
    private String key;

    public String getType() {
        return type;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}
  1. 主方法测试类TestButton
代码语言:javascript
复制
package cn.kt.mywxdemo.button;

import cn.kt.mywxdemo.token.TokenUtil;
import cn.kt.mywxdemo.utils.HttpUtil;
import net.sf.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by tao.
 * Date: 2023/3/7 17:18
 * 描述:
 */
public class TestButton {

    public static void main(String[] args) {
        //创建一级菜单
        Button button = new Button();
        List<AbstractButton> buttons = new ArrayList<>();
        //一级菜单中的第一个按钮
        ClickButton clickButton = new ClickButton("博客");
        clickButton.setKey("1");
        //一级菜单中的第二个按钮
        ViewButton viewButton = new ViewButton("Nickの主页", "https://mytab.qkongtao.cn/");
        //一级菜单中的第三个按钮(二级菜单)
        SubButton subButton = new SubButton("更多");
        List<AbstractButton> subButtons = new ArrayList<>();
        //二级菜单的第一个按钮
        subButtons.add(new ViewButton("KT游戏厅", "http://fcgame.qkongtao.cn/"));
        //二级菜单的第二个按钮
        subButtons.add(new PhotoOrAlbumButton("上传图片", "2"));
        subButton.setSub_button(subButtons);
        //把一级菜单中的三个按钮添加进集合
        buttons.add(clickButton);
        buttons.add(viewButton);
        buttons.add(subButton);
        //把集合添加到一级菜单中
        button.setButton(buttons);
        //转换成json字符串
        JSONObject jsonObject = JSONObject.fromObject(button);
        String json = jsonObject.toString();
        String url = String.format("https://api.weixin.qq.com/cgi-bin/menu/create?access_token=%s", TokenUtil.getAccessToken());
        //发送请求
        String result = HttpUtil.doPostByButton(url, json);
        System.out.println(result);
    }
}

效果如下

运行后就会根据我们代码中的设置生成公众号的菜单,结果如图

发送模板消息

模板消息仅⽤于公众号向⽤户发送重要的服务通知,只能⽤于符合其要求的服务场景中,如信⽤卡刷卡通知,商品购买成功通知等。不⽀持⼴告等营销类消息以及其它所有可能对⽤户造成骚扰的消息。 关于使⽤规则,请注意:

  • 所有服务号都可以在功能->添加功能插件处看到申请模板消息功能的⼊⼝,但只有认证后的服务号才可以申请模板消息的使⽤权限并获得该权限;
  • 需要选择公众账号服务所处的2个⾏业,每⽉可更改1次所选⾏业;
  • 在所选择⾏业的模板库中选⽤已有的模板进⾏调⽤;
  • 每个账号可以同时使⽤25个模板。
  • 当前每个账号的模板消息的⽇调⽤上限为10万次,单个模板没有特殊限制。【2014年11⽉18⽇将接⼝调⽤频率从默认的⽇1万次提升为⽇10万次,可在 MP 登录后的开发者中⼼查看】。当账号粉丝数超过10W/100W/1000W时,模板消息的⽇调⽤上限会相应提升,以公众号 MP 后台开发者中⼼⻚⾯中标明的数字为准。

关于接⼝⽂档,请注意:

  • 模板消息调⽤时主要需要模板 ID 和模板中各参数的赋值内容;
  • 模板中参数内容必须以".DATA"结尾,否则视为保留字;
  • 模板保留符号""。

微信模板消息详情具体参考:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Interface.html

1. 设置⾏业

设置⾏业可在微信公众平台后台完成,每⽉可修改⾏业1次,帐号仅可使⽤所属⾏业中相关的模板,为⽅便第三⽅开发者,提供通过接⼝调⽤的⽅式来修改账号所属⾏业,具体如下:

接⼝调⽤请求说明

http请求⽅式: POST https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token=ACCESS_TOKEN

POST数据说明 POST数据示例如下

代码语言:javascript
复制
{
    "industry_id1":"1",
    "industry_id2":"4"
}

参数说明

2. 创建模版

在微信公众平台根据⾏业模版案例创建消息模版。

附目前允许发的模板示例下载:点击下载

可自行根据允许的模板进行设置自己行业的消息模板。

3. 发送模版消息

接⼝调⽤请求说明

http请求⽅式: POST https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN

POST数据说明 POST数据示例如下:

代码语言:javascript
复制
{
    "touser": "OPENID",
    "template_id": "ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
    "url": "http://weixin.qq.com/download",
    "miniprogram": {
        "appid": "xiaochengxuappid12345",
        "pagepath": "index?foo=bar"
    },
    "client_msg_id": "MSG_000001",
    "data": {
        "first": {
            "value": "恭喜你报名成功!",
            "color": "#173177"
        },
        "keyword1": {
            "value": "张三",
            "color": "#173177"
        },
        "keyword2": {
            "value": "18899887766",
            "color": "#173177"
        },
        "keyword3": {
            "value": "2023年9⽉22⽇",
            "color": "#173177"
        },
        "keyword4": {
            "value": "Java核心基础课程",
            "color": "#173177"
        },
        "remark": {
            "value": "欢迎来到新世界!",
            "color": "#173177"
        }
    }
}

参数说明:

注:url和 miniprogram 都是⾮必填字段,若都不传则模板⽆跳转;若都传,会优先跳转⾄⼩程序。开发者可根据实际需要选择其中⼀种跳转⽅式即可。当⽤户的微信客户端版本不⽀持跳⼩程序时,将会跳转⾄url。

返回码说明 在调⽤模板消息接⼝后,会返回 JSON 数据包。正常时的返回 JSON 数据包示例:

代码语言:javascript
复制
{
    "errcode": 0,
    "errmsg": "ok",
    "msgid": 200228332
}

4. 后台示例代码

代码语言:javascript
复制
package cn.kt.mywxdemo.message;

import cn.kt.mywxdemo.token.TokenUtil;
import cn.kt.mywxdemo.utils.HttpUtil;
import org.junit.Test;

/**
 * Created by tao.
 * Date: 2023/3/7 19:26
 * 描述:
 */
public class TestModelMessage {

    //  设置模板行业信息
    //  参考文档:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Interface.html
    @Test
    public void testTrade() {
        String url = String.format("https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token=%s",
                TokenUtil.getAccessToken());
        String data = "{\n" +
                "    \"industry_id1\":\"1\",\n" +
                "    \"industry_id2\":\"4\"\n" +
                "}";
        //使用post
        System.out.println(HttpUtil.doPost(url, data));
    }

    // 获取设置的模板行业信息
    @Test
    public void testGetTrade() {
        String url = String.format("https://api.weixin.qq.com/cgi-bin/template/get_industry?access_token=%s",
                TokenUtil.getAccessToken());
        System.out.println(HttpUtil.doGet(url));
    }

    // 发送模板消息

    @Test
    public void testModelmessage() {
        String url = String.format("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s",
                TokenUtil.getAccessToken());
        String data = "{\n" +
                "           \"touser\":\"oJ4VY61KtF_VJL2Zwm_S-4cJnYCw\",\n" +
                "           \"template_id\":\"1_BTU1dlGB9rPWv5JL-Kkivn6OhjAt7wZMGqE9SHaG4\",\n" +
                "           \"data\":{\n" +
                "                   \"first\": {\n" +
                "                       \"value\":\"恭喜你报名成功!\",\n" +
                "                       \"color\":\"#173177\"\n" +
                "                   },\n" +
                "                   \"keyword1\":{\n" +
                "                       \"value\":\"张三\",\n" +
                "                       \"color\":\"#173177\"\n" +
                "                   },\n" +
                "                   \"keyword2\": {\n" +
                "                       \"value\":\"18899887766\",\n" +
                "                       \"color\":\"#173177\"\n" +
                "                   },\n" +
                "                   \"keyword3\": {\n" +
                "                       \"value\":\"2023年9月22日\",\n" +
                "                       \"color\":\"#173177\"\n" +
                "                   },\n" +
                "                   \"keyword4\": {\n" +
                "                       \"value\":\"Java核心基础课程\",\n" +
                "                       \"color\":\"#173177\"\n" +
                "                   },\n" +
                "                   \"remark\":{\n" +
                "                       \"value\":\"欢迎来到新世界!\",\n" +
                "                       \"color\":\"#173177\"\n" +
                "                   }\n" +
                "           }\n" +
                "       }";
        System.out.println(HttpUtil.doPost(url, data));
    }
}

5. 三个方法测试效果

微信素材的上传与获取

公众号经常有需要⽤到⼀些临时性的多媒体素材的场景,例如在使⽤接⼝特别是发送消息时,对多媒体⽂件、多媒体消息的获取和调⽤等操作,是通过media_id来进⾏的。素材管理接⼝对所有认证的订阅号和服务号开放。通过本接⼝,公众号可以新增临时素材(即上传临时多媒体⽂件)。 注意点: 1)临时素材media_id是可复⽤的。 2)媒体⽂件在微信后台保存时间为3天,即3天后media_id失效。 3)上传临时素材的格式、⼤⼩限制与公众平台官⽹⼀致。 图⽚(image): 10M,⽀持PNG\JPEG\JPG\GIF格式 语⾳(voice):2M,播放⻓度不超过60s,⽀持AMR\MP3格式 视频(video):10MB,⽀持MP4格式 缩略图(thumb):64KB,⽀持 JPG 格式 4)需使用https调用本接口。

http请求方式:POST/FORM,使用https https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE 调用示例(使用curl命令,用FORM表单方式上传一个多媒体文件)

具体参数详情参考官方文档:https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html

测试代码如下: 发送请求工具还是使用之前封装的HttpUtil

代码语言:javascript
复制
package cn.kt.mywxdemo.message;

import cn.kt.mywxdemo.token.TokenUtil;
import cn.kt.mywxdemo.utils.HttpUtil;
import org.junit.Test;

/**
 * 测试 素材管理
 * <p>
 * Created by tao.
 * Date: 2023/3/7 19:56
 * 描述:
 */
public class TestMedia {

    //上传临时素材
    @Test
    public void testImage() {
        String url = String.format("https://api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s",
                TokenUtil.getAccessToken(),
                "image");
        String result = HttpUtil.doPostByFile(url, null, "D:/images/bg.png", "");
        System.out.println(result);
        //{"type":"image","media_id":"h7mvkpNYOsmyPtPxnvwh7hopFlQ2LLBalyiCXcfGG2p943IqKHrrSTYdIDMbeRID","created_at":1670224505,"item":[]}
    }

    /*
    https://api.weixin.qq.com/cgi-bin/media/get?access_token=66_3Tp-hBPrXQOwoMOwoIygqf_U9YBcqk5tae28kEQtW89kaqaHKcOsXi4vudWi9CiBeBBk7nyxsHirQvQdrsOkyKrBbw8p2MDQZ2BU6pCsm7viUjdS_Ya4VzJuNN4OXFaAIAAJR&media_id=1AHMhn2WLJngIZ31Fiar-SCClNE34BPvmozpfXkvwUKlAt4b4oRQ9iFwk_x1S7n8
     */

    //获得临时素材
    @Test
    public void testGetImage() {
        String mediaId = "h7mvkpNYOsmyPtPxnvwh7hopFlQ2LLBalyiCXcfGG2p943IqKHrrSTYdIDMbeRID";
        String url = String.format("https://api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s",
                TokenUtil.getAccessToken(),
                mediaId);
        String result = HttpUtil.doGet(url);
        System.out.println(result);

    }
}

结果如下:

使用返回的media_id,拼接获取素材的接口即可获取素材: 示例如下: https://api.weixin.qq.com/cgi-bin/media/get?access_token=66_0qO7imNJGvzK1_oSoEK461VzV9406hIL8nv0GEJLH4okCZoYGR1c4uaQDrWdVsbB2fccXTEOac4kOg4eVdyZhp4Umjsl3RMqeoRv8BwTdj-x53ro9Dkf01L4pXMOVKeABAFMB&media_id=WLZtwg8LEjKZstdxRKVGfK8cX0ctJp4rIt4wVgkx2HvTHRfF1vdG8Tlqg3ilJN6P

源码下载

源码链接:https://gitee.com/qkongtao/my-wx-demo

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 获取AccessToken
    • 1. 新建一个AccessToken对象
      • 2. 新建一个TokenUtil工具类
      • 自定义菜单
        • 自定义菜单功能介绍
          • 代码实现如下
            • 效果如下
            • 发送模板消息
              • 1. 设置⾏业
                • 2. 创建模版
                  • 3. 发送模版消息
                    • 4. 后台示例代码
                      • 5. 三个方法测试效果
                      • 微信素材的上传与获取
                      • 源码下载
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档