抖音 -抖店开放平台 SDK 实现及项目工程

抖音 - 抖店开放平台 SDK

抖音 - 抖店开放平台:https://op.jinritemai.com/
该 SDK 已实现 API 接口调用和消息推送验证解析

项目地址

github:
gitee:

项目结构

  • common-rocketmq: 根据 阿里 com.aliyun.openservices 的 ons-client 第三方依赖,自定义实现的 rocketmq 基础工程
  • doudian-open-sdk: 对接 抖音 - 抖店开放平台接口 的 SDK 工程
  • doudian-open-test: 结合 common-rocketmq 与 doudian-open-sdk ,测试 SpringBoot 项目中 抖音 - 抖店开放平台接口 SDK 的使用

API 接口

API 文档:https://op.jinritemai.com/docs/guide-docs/10/814

注: 该 SDK 目前只适用于自用型应用,实现了自用型应用 client;后续补充工具型应用;两者的差别仅存在于获取授权的方式不一样

获取可用的 client

  • 自用型应用 client
    建议使用配置文件配置参数 + Bean 注入方式,来构建自用型应用 client

在配置文件中配置

doudian:serverUrl: https://openapi-fxg.jinritemai.comappKey: appSecret:signMethod: md5readTimeout: 30000version: 2

Bean 注入 DoudianClient

@Value("${spring.profiles.active}")
private String env;@Autowired
private DoudianProperties doudianProperties;/*** 描述:默认的抖店开放平台 client(默认为自用型应用)** @methodName defaultDoudianClient* @param* @return {@link DoudianClient}* @date 2021/8/20 10:42* @author chengqb*/
@Bean
public DoudianClient defaultDoudianClient() {DefaultDoudianClient defaultDoudianClient =  new DefaultDoudianClient();defaultDoudianClient.setServerUrl(doudianProperties.getServerUrl());defaultDoudianClient.setAppKey(doudianProperties.getAppKey());defaultDoudianClient.setAppSecret(doudianProperties.getAppSecret());defaultDoudianClient.setSignMethod(doudianProperties.getSignMethod());defaultDoudianClient.setReadTimeout(doudianProperties.getReadTimeout());defaultDoudianClient.setVersion(doudianProperties.getVersion());defaultDoudianClient.setEnv(env);return defaultDoudianClient;
}
  • 工具型应用 client

Client 方法

  • 创建并获取 access_token
  • 刷新并获取 access_token
  • API 接口调用(通用)

具体代码如下:

/*** 描述:抖店平台 api 调用工具** @author chengqb* @className DoudianClient* @date 2021/8/19 10:30*/
public interface DoudianClient extends Cloneable {/*** 描述:创建并获取授权** @methodName getAccessToken* @param* @return {@link DoudianAccessToken}* @date 2021/8/19 10:38* @author chengqb*/DoudianAccessToken getAccessToken();/*** 描述:刷新并获取授权** @methodName getAccessToken* @param refreshToken* @return {@link DoudianAccessToken}* @date 2021/8/19 10:38* @author chengqb*/DoudianAccessToken getAccessToken(String refreshToken);/*** 描述:抖店接口调用** @methodName execute* @param request* @param accessToken* @return {@link T}* @date 2021/8/19 10:38* @author chengqb*/<T extends DoudianResponse> T execute(DoudianRequest<T> request, String accessToken);
}

SDK 调用类名规则

  • 请求类(Request)

    1. 基类(DoudianRequest)
      该基类为一个接口,含有两个方法:
          getMethod():用于请求时,构建请求路径,从而指定请求接口
          getResponseClass():用于请求结果返回时,构建对应的 Response;必须被实现

    2. 分页基类(BasePage)
      主要有两个参数:page(当前页码,从 0 开始)、size(每页条数)

    3. 具体接口请求类(Request)
      必须实现 DoudianRequest 接口
      需要分页请求的接口,具体接口请求类需继承 BasePage 类
      必须定义 private final String method = ""; 具体值,根据抖店开放平台 API 文档中的接口而定
          注: method 由 “.” 分隔,具体可查看抖店开放平台 API 文档
              如:
      在这里插入图片描述

      必须实现 getResponseClass() ,并指定具体的返回基类(Response)
      再补充定义具体接口所需请求参数,如:shopOrderId(店铺订单号)

      如:

      /*** 描述:获取抖店订单详情请求类** @author chengqb* @className DoudianOrderDetailRequest* @date 2021/8/25 17:59*/
      @Data
      public class DoudianOrderDetailRequest implements DoudianRequest<DoudianOrderDetailResponse> {private final String method = "order.orderDetail";/*** 店铺订单号*/private String shopOrderId;@Overridepublic Class<DoudianOrderDetailResponse> getResponseClass() {return DoudianOrderDetailResponse.class;}
      }
      
  • 返回基类(Response)

    1. 基类(DoudianResponse)
      该基类后跟上一个泛型,标识具体返回参数类
      返回基础结构如下:

      {"err_no": 0,"message": "success","logId": "20210831199610203011""data": {}
      }
      
    2. 分页基类(DoudianPage)
      该基类后跟上一个泛型,标识具体返回参数类,指明具体分页数据类型

    3. 具体接口返回类(Response)
      必须继承 DoudianResponse 类,并指定泛型
      若为分页请求,DoudianResponse 的泛型指定为 DoudianPage ;而 DoudianPage 的泛型再指定为具体参数类;
      如:public class DoudianSettleBillResponse extends DoudianResponse<DoudianPage<DoudianSettleBill>>

      如:

      /*** 描述:获取抖店订单详情返回类** @author chengqb* @className DoudianOrderDetailResponse* @date 2021/8/25 18:00*/
      @Data
      public class DoudianOrderDetailResponse extends DoudianResponse<DoudianOrderDetail> {
      }
      
  • 返回参数类(Entity)

    1. 普通返回参数类
      根据抖店开放平台接口具体返回参数进行定义

      如:

      /*** 描述:获取抖店订单详情返回参数** @author chengqb* @className DoudianOrderDetail* @date 2021/8/25 18:01*/
      @Data
      public class DoudianOrderDetail {/*** 抖店订单详情信息*/private ShopOrderDetail shopOrderDetail;
      }
      

订阅消息接收

抖店订阅消息推送:https://op.jinritemai.com/docs/guide-docs/10/99

注: 需定义个接口,专门接收抖店各类订阅消息;再将该接口路径拼接上请求协议及请求域名,再填写至抖店开放平台配置中

此处,要求在 5 s 内必须返回 {"code":0,"msg":"success"} ;故而,建议在接收到消息内容并解析完成后,立即返回指定格式数据给抖店,再通过 异步来处理业务 ;doudian-open-test 使用了 mq 消息 的方式来实现了异步处理

  • 基础返回类(BaseResponse)
    只含有 code、msg 两个参数字段

  • 基础数据类(DoudianMessageData )
    含有 tag、msgId、data 三个参数字段;其中 data 为字符串类型,存放具体数据;
    含有 toObject(Class tClass) 方法,可将 data 字符串数据转换为具体的订阅消息数据

    如: DoudianOrderPaySuccess 为抖店订单支付成功订阅消息数据类

    DoudianMessage pushMessage = DoudianMessageUtil.getDoudianMessage(request);
    List<DoudianMessageData> pushDataList = pushMessage.getData();
    for (DoudianMessageData messageData : messageDataList) {DoudianOrderPaySuccess orderPaySuccess = messageData.toObject(DoudianOrderPaySuccess.class);
    }
    
  • 基础消息类(DoudianMessage)
    含有 appId、eventSign、body 三个参数字段;其中 body 为字符串类型,存放具体数据;
    含有 getData() 方法,可将 body 字符串数据转换为 DoudianMessageData 列表

  • 消息获取
    该 SDK 定义了 DoudianMessageUtil 工具类
    其中的 public static DoudianMessage getDoudianMessage(HttpServletRequest request) 方法,可解析获取抖店开放平台订阅消息

具体代码可参考:

/*** 描述:抖店开放平台订阅消息推送接收** @author chengqb* @className DoudianMessageController* @date 2021/8/20 17:05*/
@Slf4j
@RestController
@Api(tags = "抖店消息")
@RequestMapping("/doudian/message")
public class DoudianMessageController {@Autowiredprivate DoudianMessageDataHandler doudianMessageDataHandler;/*** 描述:抖店订阅消息接收** @methodName receiveMessage* @param request* @return {@link BaseResponse}* @date 2021/8/12 14:42* @author chengqb*/@ApiOperation(value = "抖店订阅消息接收", notes = "接收")@PostMapping("/receiveMessage")public BaseResponse receiveMessage(HttpServletRequest request) {// return BaseResponse.failed(1, "测试中");DoudianMessage pushMessage = DoudianMessageUtil.getDoudianMessage(request);if (CollectionUtil.isEmpty(pushMessage.getData())) {log.info("接收到抖店平台订阅消息,但消息解析失败");return BaseResponse.failed(ReponseEnum.DATA_BLANK.getCode(), ReponseEnum.DATA_BLANK.getMsg());} else {// 推送地址添加后,平台会立即 Post 一条 "[{"tag":"0","msg_id":"0","data":"2020-09-10T16:27:56.52842897+08:00"}]" 的测试消息,// 必须返回 {"code":0,"msg":"success"} ,否则平台判定推送地址异常,将无法启用消息推送服务// (注意:超时也会被认为是推送失败,超时时间是5s)List<DoudianMessageData> pushDataList = pushMessage.getData();// 接收到抖店平台推送消息后,必须返回{"code":0,"msg":"success"}if (pushDataList.size() == 1 && "0".equals(pushDataList.get(0).getTag())) {log.info("接收到抖店平台订阅消息,消息 tag 为:{}", pushDataList.get(0).getTag());return BaseResponse.ok();} else {log.info("接收到抖店平台订阅消息,并解析成功");// 处理抖店订阅消息数据doudianMessageDataHandler.proccessPushData(pushDataList);// return BaseResponse.failed(1, "测试中");return BaseResponse.ok();}}}
}

access_token 获取

店铺授权:https://op.jinritemai.com/docs/guide-docs/9/20

access_token 获取后,有效期为 7 天,而 refresh_token 有效期为 14 天

  1. 建议将 access_token 和 refresh_token 都存放至 redis
  2. 在 7 天内,直接从 redis 中获取 access_token
  3. 在 7 ~ 14 天内,通过 refresh_token 去抖店开放平台刷新并获取 access_token
  4. 在 14 天后,直接去抖店开放平台重新创建获取 access_token

可参考如下代码:

DoudianOauthHandler

/*** 描述:抖店平台 access_token 相关业务处理** @author chengqb* @className DoudianOauthHandler* @date 2021/8/20 10:13*/
@Slf4j
@Service
public class DoudianOauthHandler {@Autowiredprivate RedisTemplate redisTemplate;@Autowiredprivate DoudianOpenOauthHandler doudianOpenOauthHandler;private static final String DOUDIAN_ACCESS_TOKEN_KEY = "doudian:access_token";private static final String DOUDIAN_REFRESH_TOKEN_KEY = "doudian:refresh_token";/*** 描述:获取抖店授权* 文档地址:https://op.jinritemai.com/docs/guide-docs/9/21** @methodName getOauthToken* @param* @return {@link String}* @date 2021/8/16 16:08* @author chengqb*/public String getOauthToken() {Object accessTokenObject = redisTemplate.opsForValue().get(DOUDIAN_ACCESS_TOKEN_KEY);if (ObjectUtil.isNull(accessTokenObject)) {String refreshToken = (String) redisTemplate.opsForValue().get(DOUDIAN_REFRESH_TOKEN_KEY);// 获取 access_tokenDoudianAccessToken accessToken = doudianOpenOauthHandler.getAccessToken(refreshToken);redisTemplate.opsForValue().set(DOUDIAN_ACCESS_TOKEN_KEY, accessToken, accessToken.getExpiresIn(), TimeUnit.SECONDS);redisTemplate.opsForValue().set(DOUDIAN_REFRESH_TOKEN_KEY, accessToken.getRefreshToken(), 14, TimeUnit.DAYS);return accessToken.getAccessToken();}DoudianAccessToken accessToken = JSONUtil.toBean(JSONUtil.toJsonStr(accessTokenObject), DoudianAccessToken.class);return accessToken.getAccessToken();}
}

DoudianOpenOauthHandler

/*** 描述:抖店平台对接 access_token 相关业务处理** @author chengqb* @className DoudianOpenOauthHandler* @date 2021/8/20 10:15*/
@Slf4j
@Service
public class DoudianOpenOauthHandler {@Autowiredprivate DoudianClient defaultDoudianClient;/*** 描述:获取 access_token** @methodName getAccessToken* @param refreshToken* @return {@link DoudianAccessToken}* @date 2021/8/20 10:39* @author chengqb*/public DoudianAccessToken getAccessToken(String refreshToken) {DoudianAccessToken accessToken = null;if (StrUtil.isBlank(refreshToken)) {// 如果刷新令牌也过期了,则调用获取 access_token 接口accessToken = defaultDoudianClient.getAccessToken();} else {// 如果刷新令牌还未过期了,则调用刷新 access_token 接口accessToken = defaultDoudianClient.getAccessToken(refreshToken);}return accessToken;}
}

参考资料: https://github.com/cnJun/sdk4-jinritemai

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/38291.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

将手机接收到的短信实时转发到服务器web端上(或其他需要的地方)

在爬虫时, 有的网站要登录, 登录时需要短信验证, 因为爬虫是跑在服务端上, 所以希望服务器能实时获取到手机上的短信,使爬虫能够自动化. 为此自己开发了个能实时将安卓手机上的短信转发到服务器上. 展示如下:(将手机短信发送到服务端并储存起来,然后可以网页形式访问这些短信.…

(转)短信vs.推送通知vs.电子邮件:app什么时候该用哪种方式来通知用户?

转&#xff1a;http://www.360doc.com/content/15/0811/00/19476362_490860835.shtml 现在&#xff0c;很多公司都关心的一个问题是&#xff1a;要提高用户互动&#xff0c;到底采取哪一种通信技术获得的效果是最好的&#xff0c;怎样才能让用户心甘情愿的融入到自己的产品语境…

入门级短信推送,你还不会吗?

短信推送服务是生活中常见的&#xff0c;包括一些企业的营销或验证码场景的服务&#xff0c;这些都是需要短信服务来进行的 在开发中也比较常见&#xff0c;如开发一个个人博客系统&#xff0c;就会给注册或登录界面加上填写手机号发送验证码功能&#xff0c;或者加上发送邮件等…

瑞吉外卖(22)- 短信发送功能开发(了解一下)

文章目录 效果展示短信服务介绍阿里云短信服务-(了解)介绍注册账号 代码开发maven坐标调用API&#xff08;SMSUtils.java&#xff09; 效果展示 短信服务介绍 阿里云短信服务-(了解) 介绍 注册账号 这里我们不使用阿里云了&#xff0c;注册需要营业执照&#xff0c;我们只是了…

Tasker短信转发

需要开启权限&#xff08;在权限管理中&#xff09;与监听功能&#xff08;在系统设置的辅助功能中&#xff09; &#xff08;1&#xff09;添加事件&#xff1a; 点击右下角的 ----> 事件 ----> 电话 ----> 收到短信 ----> 不做修改返回即可或者在发件人或者内…

Tasker 短信转发微信,所有通知转发微信

前言 快速写一篇&#xff0c;不想花太多时间&#xff0c;不是详细教程&#xff0c;导入就完了。 准备 一台能看片的安卓手机&#xff08;至少安卓5.0&#xff09;。安装好Tasker&#xff08;版本越新越好&#xff0c;目前5.9.3 beta3&#xff09;。权限给足&#xff0c;自启&am…

android实现短信自动转发,利用短信通知的方式在Tasker中实现收到Android手机短信自动转发到微信...

在Tasker中利用短信的通知实现短信内容转发到微信 之前的教程是利用Tasker自带的短信变量来实现的&#xff0c;这有一个无法解决问题&#xff1a;在360&#xff0c;魅族&#xff0c;坚果等品牌的手机中无法获取短信的消息内容。 利用短信的通知则可以获取短信的内容&#xff0c…

AIGC技术发展和应用方向

AIGC&#xff08;Artificial Intelligence Generated Content&#xff09;是指通过人工智能技术生成的各种文本、图像、音频和视频等多媒体内容。AIGC技术是机器学习和自然语言处理等技术的结合&#xff0c;通过对海量数据的学习和分析&#xff0c;可以让计算机模拟人类的创造力…

未来先行者共赴2023全球智博会

从传统机器学习到深度学习&#xff0c;从简单执行到多模态、多任务的综合处理&#xff0c;人工智能技术正不断向更加智慧和复杂的领域拓展进化。伴随着人工智能一路高歌猛进的跨越式发展&#xff0c;产业寻求共融&#xff0c;加速智慧升级&#xff1b;城市汇流聚链&#xff0c;…

GAN出一个女朋友

文章目录 GAN(生成对抗网络&#xff09;1. 生成对抗网络简述2.具体内容2.1 网络如何训练2.2 网络训练时会遇到的问题 3.GAN的发展4.GAN的代码实践4.1 基于GAN的mnist数据生成4.2 放大招—生成美女图片4.2.1 爬取美女图片4.2.2 提取人脸4.2.3 开始训练 GAN(生成对抗网络&#xf…

chatgpt赋能python:Python更换桌面背景指南:教你如何用Python快速实现桌面背景更换

Python更换桌面背景指南&#xff1a;教你如何用Python快速实现桌面背景更换 如果你已经厌倦了一成不变的桌面背景&#xff0c;那么Python可以帮助你快速实现更换功能。本指南将教您如何用Python编写简单的代码来更改桌面背景。 如何用Python更换桌面背景 Python中有几个库可…

chatgpt赋能python:Python自定义背景:让你的编程世界更加缤纷多彩

Python 自定义背景&#xff1a;让你的编程世界更加缤纷多彩 随着科技的迅速发展&#xff0c;人们的日常生活和工作中越来越多地依赖于电脑和各种数字设备。而对于程序员来说&#xff0c;他们的编程世界更是离不开电脑和代码编辑器。因此&#xff0c;如何让这个世界变得更加优美…

chatgpt赋能python:如何使用Python将背景色更改为黑色

如何使用Python将背景色更改为黑色 在网页设计中&#xff0c;背景色是非常重要的元素之一。有时候&#xff0c;为了让网页看起来更加时尚和艺术&#xff0c;设计师可能会使用黑色背景来营造一种神秘和高质感的感觉。在本篇文章中&#xff0c;我们将介绍如何使用Python将背景色…

chatgpt赋能python:Python图片查看器:优化你的图片浏览体验

Python图片查看器&#xff1a;优化你的图片浏览体验 如果你常常处理图片&#xff0c;那么一个高效的图片浏览器会节约你大量的时间。本文将介绍一款使用Python编写的开源图片查看器&#xff0c;它可以帮助你快速预览和编辑图片。此外&#xff0c;我们还会分享如何使用关键字优…

C/C++编程:继承构造函数

引入 在传统C中&#xff0c;如果派生类要使用使用基类的构造函数&#xff0c;通常需要在构造函数中显式声明&#xff1a; struct A{ public:A(int i) {} };struct B : A{B (int i) : A(i){} };B派生自A&#xff0c;B又在构造函数中调用A的构造函数&#xff0c;从而完成构造函…

C++11之继承构造函数(using 声明)

系列文章 C11之正则表达式&#xff08;regex_match、regex_search、regex_replace&#xff09; C11之线程库&#xff08;Thread、Mutex、atomic、lock_guard、同步&#xff09; C11之智能指针&#xff08;unique_ptr、shared_ptr、weak_ptr、auto_ptr&#xff09;浅谈内存管…

继承与派生(Part Ⅱ)——派生类的构造函数/析构函数

派生类的构造函数和析构函数 构造函数的主要作用是对数据成员初始化。基类的构造函数是不能继承的&#xff0c;在声明派生类时&#xff0c;派生类并没有把基类的构造函数继承过来&#xff0c;因此&#xff0c;对继承过来的基类成员初始化的工作也要由派生类的构造函数承担。所…

6.12C++:继承基类的构造函数、单继承的构造函数、多继承的构造函数、派生类复制构造函数、派生类的析构函数

1 继承基类的构造函数 class A{ public:A(){}; // A的构造函数 }; class B : public A{ public:using A:A&#xff1b; }2 单继承的构造函数 class A{ public:A(int i){}; }; class B : public A{ public:B(int i, int j): A(i), bb(j); /i传递给A的构造函数&#xff0c;j初始…

JavaScript构造函数继承

首先介绍对象的call()函数和apply()函数&#xff0c;这两个函数的作用相同、用法不同。它们的作用均是指定当前调用函数的this对象是谁。 call()函数&#xff1a;在第一个传递的参数为一个对象&#xff0c;该对象为该函数的this对象&#xff0c;后面依次传递函数的实参。 apply…

c++继承构造函数

【1】为什么需要继承构造函数&#xff1f; 首先&#xff0c;看看如下代码片段&#xff1a; 1 struct A2 { 3 A(int i)4 {} 5 }; 6 7 struct B : A8 { 9 B(int i) : A(i) 10 {} 11 }; 在C中非常常见&#xff1a;B派生于A&#xff0c;B在构造函数中调用A的构造函…