Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions MINIAPP_KEFU_SERVICE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# WeChat Mini Program Customer Service Management

This document describes the new customer service management functionality added to the WxJava Mini Program SDK.

## Overview

Previously, the mini program module only had:
- `WxMaCustomserviceWorkService` - For binding mini programs to enterprise WeChat customer service
- `WxMaMsgService.sendKefuMsg()` - For sending customer service messages

The new `WxMaKefuService` adds comprehensive customer service management capabilities:

## Features

### Customer Service Account Management
- `kfList()` - Get list of customer service accounts
- `kfAccountAdd()` - Add new customer service account
- `kfAccountUpdate()` - Update customer service account
- `kfAccountDel()` - Delete customer service account

### Session Management
- `kfSessionCreate()` - Create customer service session
- `kfSessionClose()` - Close customer service session
- `kfSessionGet()` - Get customer session status
- `kfSessionList()` - Get customer service session list

## Usage Example

```java
// Get the customer service management service
WxMaKefuService kefuService = wxMaService.getKefuService();

// Add a new customer service account
WxMaKfAccountRequest request = WxMaKfAccountRequest.builder()
.kfAccount("service001@example")
.kfNick("Customer Service 001")
.kfPwd("password123")
.build();
boolean result = kefuService.kfAccountAdd(request);

// Create a session between user and customer service
boolean sessionResult = kefuService.kfSessionCreate("user_openid", "service001@example");

// Get customer service list
WxMaKfList kfList = kefuService.kfList();
```

## Bean Classes

### Request Objects
- `WxMaKfAccountRequest` - For customer service account operations
- `WxMaKfSessionRequest` - For session operations

### Response Objects
- `WxMaKfInfo` - Customer service account information
- `WxMaKfList` - List of customer service accounts
- `WxMaKfSession` - Session information
- `WxMaKfSessionList` - List of sessions

## API Endpoints

The service uses the following WeChat Mini Program API endpoints:
- `https://api.weixin.qq.com/cgi-bin/customservice/getkflist` - Get customer service list
- `https://api.weixin.qq.com/customservice/kfaccount/add` - Add customer service account
- `https://api.weixin.qq.com/customservice/kfaccount/update` - Update customer service account
- `https://api.weixin.qq.com/customservice/kfaccount/del` - Delete customer service account
- `https://api.weixin.qq.com/customservice/kfsession/create` - Create session
- `https://api.weixin.qq.com/customservice/kfsession/close` - Close session
- `https://api.weixin.qq.com/customservice/kfsession/getsession` - Get session
- `https://api.weixin.qq.com/customservice/kfsession/getsessionlist` - Get session list

## Integration

The service is automatically available through the main `WxMaService` interface:

```java
WxMaKefuService kefuService = wxMaService.getKefuService();
```

This fills the gap mentioned in the original issue and provides full customer service management capabilities for WeChat Mini Programs.
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package cn.binarywang.wx.miniapp.api;

import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfInfo;
import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfList;
import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfSession;
import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfSessionList;
import cn.binarywang.wx.miniapp.bean.kefu.request.WxMaKfAccountRequest;
import me.chanjar.weixin.common.error.WxErrorException;

/**
* <pre>
* 小程序客服管理接口.
* 不同于 WxMaCustomserviceWorkService (企业微信客服绑定) 和 WxMaMsgService.sendKefuMsg (发送客服消息),
* 此接口专门处理小程序客服账号管理、会话管理等功能。
*
* 注意:小程序客服管理接口与公众号客服管理接口在API端点和功能上有所不同。
* </pre>
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public interface WxMaKefuService {

/**
* <pre>
* 获取客服基本信息
* 详情请见:<a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-service/customerServiceMessage.getContactList.html">获取客服基本信息</a>
* 接口url格式:https://api.weixin.qq.com/cgi-bin/customservice/getkflist?access_token=ACCESS_TOKEN
* </pre>
*
* @return 客服列表
* @throws WxErrorException 异常
*/
WxMaKfList kfList() throws WxErrorException;

/**
* <pre>
* 添加客服账号
* 详情请见:<a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-service/customerServiceMessage.addKfAccount.html">添加客服账号</a>
* 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/add?access_token=ACCESS_TOKEN
* </pre>
*
* @param request 客服账号信息
* @return 是否成功
* @throws WxErrorException 异常
*/
boolean kfAccountAdd(WxMaKfAccountRequest request) throws WxErrorException;

/**
* <pre>
* 修改客服账号
* 详情请见:<a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-service/customerServiceMessage.updateKfAccount.html">修改客服账号</a>
* 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/update?access_token=ACCESS_TOKEN
* </pre>
*
* @param request 客服账号信息
* @return 是否成功
* @throws WxErrorException 异常
*/
boolean kfAccountUpdate(WxMaKfAccountRequest request) throws WxErrorException;

/**
* <pre>
* 删除客服账号
* 详情请见:<a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-service/customerServiceMessage.deleteKfAccount.html">删除客服账号</a>
* 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/del?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT
* </pre>
*
* @param kfAccount 客服账号
* @return 是否成功
* @throws WxErrorException 异常
*/
boolean kfAccountDel(String kfAccount) throws WxErrorException;

/**
* <pre>
* 创建会话
* 详情请见:<a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-service/customerServiceMessage.createSession.html">创建会话</a>
* 接口url格式:https://api.weixin.qq.com/customservice/kfsession/create?access_token=ACCESS_TOKEN
* </pre>
*
* @param openid 用户openid
* @param kfAccount 客服账号
* @return 是否成功
* @throws WxErrorException 异常
*/
boolean kfSessionCreate(String openid, String kfAccount) throws WxErrorException;

/**
* <pre>
* 关闭会话
* 详情请见:<a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-service/customerServiceMessage.closeSession.html">关闭会话</a>
* 接口url格式:https://api.weixin.qq.com/customservice/kfsession/close?access_token=ACCESS_TOKEN
* </pre>
*
* @param openid 用户openid
* @param kfAccount 客服账号
* @return 是否成功
* @throws WxErrorException 异常
*/
boolean kfSessionClose(String openid, String kfAccount) throws WxErrorException;

/**
* <pre>
* 获取客户的会话状态
* 详情请见:<a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-service/customerServiceMessage.getSession.html">获取客户的会话状态</a>
* 接口url格式:https://api.weixin.qq.com/customservice/kfsession/getsession?access_token=ACCESS_TOKEN&openid=OPENID
* </pre>
*
* @param openid 用户openid
* @return 会话信息
* @throws WxErrorException 异常
*/
WxMaKfSession kfSessionGet(String openid) throws WxErrorException;

/**
* <pre>
* 获取客服的会话列表
* 详情请见:<a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-service/customerServiceMessage.getSessionList.html">获取客服的会话列表</a>
* 接口url格式:https://api.weixin.qq.com/customservice/kfsession/getsessionlist?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT
* </pre>
*
* @param kfAccount 客服账号
* @return 会话列表
* @throws WxErrorException 异常
*/
WxMaKfSessionList kfSessionList(String kfAccount) throws WxErrorException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,13 @@ WxMaApiResponse execute(
*/
WxMaCustomserviceWorkService getCustomserviceWorkService();

/**
* 获取小程序客服管理服务。
*
* @return 客服管理服务对象WxMaKefuService
*/
WxMaKefuService getKefuService();

/**
* 获取jsapi操作相关服务对象。
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ public abstract class BaseWxMaServiceImpl<H, P> implements WxMaService, RequestH
private final WxMaAnalysisService analysisService = new WxMaAnalysisServiceImpl(this);
private final WxMaCodeService codeService = new WxMaCodeServiceImpl(this);
private final WxMaCustomserviceWorkService customserviceWorkService = new WxMaCustomserviceWorkServiceImpl(this);
private final WxMaKefuService maKefuService = new WxMaKefuServiceImpl(this);
private final WxMaInternetService internetService = new WxMaInternetServiceImpl(this);
private final WxMaSettingService settingService = new WxMaSettingServiceImpl(this);
private final WxMaJsapiService jsapiService = new WxMaJsapiServiceImpl(this);
Expand Down Expand Up @@ -657,6 +658,11 @@ public WxMaCustomserviceWorkService getCustomserviceWorkService() {
return this.customserviceWorkService;
}

@Override
public WxMaKefuService getKefuService() {
return this.maKefuService;
}

@Override
public WxMaJsapiService getJsapiService() {
return this.jsapiService;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package cn.binarywang.wx.miniapp.api.impl;

import cn.binarywang.wx.miniapp.api.WxMaKefuService;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfInfo;
import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfList;
import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfSession;
import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfSessionList;
import cn.binarywang.wx.miniapp.bean.kefu.request.WxMaKfAccountRequest;
import cn.binarywang.wx.miniapp.bean.kefu.request.WxMaKfSessionRequest;
import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;

/**
* 小程序客服管理服务实现.
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@RequiredArgsConstructor
public class WxMaKefuServiceImpl implements WxMaKefuService {

// 小程序客服管理接口URL
private static final String KFLIST_GET_URL = "https://api.weixin.qq.com/cgi-bin/customservice/getkflist";
private static final String KFACCOUNT_ADD_URL = "https://api.weixin.qq.com/customservice/kfaccount/add";
private static final String KFACCOUNT_UPDATE_URL = "https://api.weixin.qq.com/customservice/kfaccount/update";
private static final String KFACCOUNT_DEL_URL = "https://api.weixin.qq.com/customservice/kfaccount/del?kf_account=%s";
private static final String KFSESSION_CREATE_URL = "https://api.weixin.qq.com/customservice/kfsession/create";
private static final String KFSESSION_CLOSE_URL = "https://api.weixin.qq.com/customservice/kfsession/close";
private static final String KFSESSION_GET_URL = "https://api.weixin.qq.com/customservice/kfsession/getsession?openid=%s";
private static final String KFSESSION_LIST_URL = "https://api.weixin.qq.com/customservice/kfsession/getsessionlist?kf_account=%s";

private final WxMaService service;

@Override
public WxMaKfList kfList() throws WxErrorException {
String responseContent = this.service.get(KFLIST_GET_URL, null);
return WxMaKfList.fromJson(responseContent);
}

@Override
public boolean kfAccountAdd(WxMaKfAccountRequest request) throws WxErrorException {
String responseContent = this.service.post(KFACCOUNT_ADD_URL, request.toJson());
return responseContent != null;
}

@Override
public boolean kfAccountUpdate(WxMaKfAccountRequest request) throws WxErrorException {
String responseContent = this.service.post(KFACCOUNT_UPDATE_URL, request.toJson());
return responseContent != null;
}

@Override
public boolean kfAccountDel(String kfAccount) throws WxErrorException {
String url = String.format(KFACCOUNT_DEL_URL, kfAccount);
String responseContent = this.service.get(url, null);
return responseContent != null;
}

@Override
public boolean kfSessionCreate(String openid, String kfAccount) throws WxErrorException {
WxMaKfSessionRequest request = WxMaKfSessionRequest.builder()
.kfAccount(kfAccount)
.openid(openid)
.build();
String responseContent = this.service.post(KFSESSION_CREATE_URL, request.toJson());
return responseContent != null;
}

@Override
public boolean kfSessionClose(String openid, String kfAccount) throws WxErrorException {
WxMaKfSessionRequest request = WxMaKfSessionRequest.builder()
.kfAccount(kfAccount)
.openid(openid)
.build();
String responseContent = this.service.post(KFSESSION_CLOSE_URL, request.toJson());
return responseContent != null;
}

@Override
public WxMaKfSession kfSessionGet(String openid) throws WxErrorException {
String url = String.format(KFSESSION_GET_URL, openid);
String responseContent = this.service.get(url, null);
return WxMaKfSession.fromJson(responseContent);
}

@Override
public WxMaKfSessionList kfSessionList(String kfAccount) throws WxErrorException {
String url = String.format(KFSESSION_LIST_URL, kfAccount);
String responseContent = this.service.get(url, null);
return WxMaKfSessionList.fromJson(responseContent);
}
}
Loading