Comprehensive Java SDK for WeChat MiniApp development with complete platform integration
—
Comprehensive messaging capabilities including customer service messages, subscription messages, template messages, uniform messages, and dynamic updatable messages for WeChat MiniApp communication.
Core messaging operations for different types of messages and communication channels.
public interface WxMaMsgService {
// Customer Service Messages
boolean sendKefuMsg(WxMaKefuMessage message) throws WxErrorException;
// Subscription Messages
void sendSubscribeMsg(WxMaSubscribeMessage subscribeMessage) throws WxErrorException;
// Uniform Messages (MiniApp + Official Account)
void sendUniformMsg(WxMaUniformMessage uniformMessage) throws WxErrorException;
// Dynamic Messages
JsonObject createUpdatableMessageActivityId() throws WxErrorException;
void setUpdatableMsg(WxMaUpdatableMsg msg) throws WxErrorException;
}Template-based subscription message management for personalized notifications.
public interface WxMaSubscribeService {
// Template Management
PubTemplateTitleListResult getPubTemplateTitleList(String[] ids, int start, int limit) throws WxErrorException;
List<PubTemplateKeyword> getPubTemplateKeyWordsById(String id) throws WxErrorException;
String addTemplate(String id, List<Integer> keywordIdList, String sceneDesc) throws WxErrorException;
List<TemplateInfo> getTemplateList() throws WxErrorException;
boolean delTemplate(String templateId) throws WxErrorException;
List<CategoryData> getCategory() throws WxErrorException;
// Message Sending
void sendSubscribeMsg(WxMaSubscribeMessage subscribeMessage) throws WxErrorException;
}Models and builders for different types of customer service messages.
public class WxMaKefuMessage implements Serializable {
private String toUser; // User OpenID
private String msgType; // Message type
private String text; // Text content (for text messages)
private String mediaId; // Media ID (for media messages)
private String title; // Title (for link/card messages)
private String description; // Description
private String url; // URL (for link messages)
private String thumbUrl; // Thumbnail URL
private String thumbMediaId; // Thumbnail media ID
private String appid; // Mini program App ID (for mini program cards)
private String pagePath; // Mini program page path
// Builder methods
public static TextMessageBuilder newTextBuilder();
public static ImageMessageBuilder newImageBuilder();
public static LinkMessageBuilder newLinkBuilder();
public static MaPageMessageBuilder newMaPageBuilder();
// Getters and setters
public String getToUser();
public void setToUser(String toUser);
public String getMsgType();
public void setMsgType(String msgType);
// ... other getters/setters
// Utility methods
public String toJson();
public static WxMaKefuMessage fromJson(String json);
}Fluent builders for constructing different types of customer service messages.
// Text Message Builder
public class TextMessageBuilder extends BaseBuilder<TextMessageBuilder> {
public TextMessageBuilder content(String content);
public WxMaKefuMessage build();
}
// Image Message Builder
public class ImageMessageBuilder extends BaseBuilder<ImageMessageBuilder> {
public ImageMessageBuilder mediaId(String mediaId);
public WxMaKefuMessage build();
}
// Link Message Builder
public class LinkMessageBuilder extends BaseBuilder<LinkMessageBuilder> {
public LinkMessageBuilder title(String title);
public LinkMessageBuilder description(String description);
public LinkMessageBuilder url(String url);
public LinkMessageBuilder thumbUrl(String thumbUrl);
public WxMaKefuMessage build();
}
// Mini Program Page Message Builder
public class MaPageMessageBuilder extends BaseBuilder<MaPageMessageBuilder> {
public MaPageMessageBuilder title(String title);
public MaPageMessageBuilder pagePath(String pagePath);
public MaPageMessageBuilder thumbMediaId(String thumbMediaId);
public MaPageMessageBuilder appid(String appid);
public WxMaKefuMessage build();
}
// Base Builder
public abstract class BaseBuilder<T extends BaseBuilder<T>> {
public T toUser(String toUser);
protected abstract WxMaKefuMessage build();
}Template-based notification messages requiring user consent.
public class WxMaSubscribeMessage implements Serializable {
private String toUser; // Target user OpenID
private String templateId; // Template ID
private String page; // Mini program page to jump to
private Map<String, WxMaSubscribeData> data; // Template data
private String miniprogramState; // Mini program state
private String lang; // Language
// Constructors
public WxMaSubscribeMessage();
public WxMaSubscribeMessage(String toUser, String templateId, Map<String, WxMaSubscribeData> data);
// Getters and setters
public String getToUser();
public void setToUser(String toUser);
public String getTemplateId();
public void setTemplateId(String templateId);
public String getPage();
public void setPage(String page);
public Map<String, WxMaSubscribeData> getData();
public void setData(Map<String, WxMaSubscribeData> data);
// Convenience methods for data
public WxMaSubscribeMessage addData(String key, String value);
public WxMaSubscribeMessage addData(String key, String value, String color);
// Utility methods
public String toJson();
public static WxMaSubscribeMessage fromJson(String json);
}
public class WxMaSubscribeData {
private String value; // Data value
private String color; // Text color (optional)
public WxMaSubscribeData(String value);
public WxMaSubscribeData(String value, String color);
public String getValue();
public void setValue(String value);
public String getColor();
public void setColor(String color);
}Messages that can be sent to both mini program and official account users.
public class WxMaUniformMessage implements Serializable {
private String toUser; // Target user OpenID
private WxMpTemplateMessage mpTemplateMsg; // Official account template message
private WxMaSubscribeMessage maTemplateMsg; // Mini program subscription message
public WxMaUniformMessage();
// Getters and setters
public String getToUser();
public void setToUser(String toUser);
public WxMpTemplateMessage getMpTemplateMsg();
public void setMpTemplateMsg(WxMpTemplateMessage mpTemplateMsg);
public WxMaSubscribeMessage getMaTemplateMsg();
public void setMaTemplateMsg(WxMaSubscribeMessage maTemplateMsg);
// Utility methods
public String toJson();
public static WxMaUniformMessage fromJson(String json);
}Updatable messages that can be modified after sending (for sharing scenarios).
public class WxMaUpdatableMsg implements Serializable {
private String activityId; // Activity ID from createUpdatableMessageActivityId
private Integer targetState; // Target state (0: not started, 1: in progress, 2: completed)
private List<UpdatableTemplateData> templateInfo; // Template data
public WxMaUpdatableMsg();
// Getters and setters
public String getActivityId();
public void setActivityId(String activityId);
public Integer getTargetState();
public void setTargetState(Integer targetState);
public List<UpdatableTemplateData> getTemplateInfo();
public void setTemplateInfo(List<UpdatableTemplateData> templateInfo);
// Utility methods
public String toJson();
public static WxMaUpdatableMsg fromJson(String json);
public static class UpdatableTemplateData {
private String parameterName; // Parameter name
private String parameterValue; // Parameter value
public UpdatableTemplateData(String parameterName, String parameterValue);
public String getParameterName();
public void setParameterName(String parameterName);
public String getParameterValue();
public void setParameterValue(String parameterValue);
}
}// Simple text message
WxMaKefuMessage textMsg = WxMaKefuMessage.newTextBuilder()
.toUser("oLVPpjqs9BhvzwPj5A-vTYAX3GLc")
.content("Welcome to our service! How can we help you today?")
.build();
try {
boolean success = wxService.getMsgService().sendKefuMsg(textMsg);
if (success) {
logger.info("Text message sent successfully");
}
} catch (WxErrorException e) {
logger.error("Failed to send text message: {}", e.getMessage());
}// First upload image to get media_id
WxMaMediaService mediaService = wxService.getMediaService();
File imageFile = new File("/path/to/image.jpg");
WxMediaUploadResult uploadResult = mediaService.uploadMedia("image", imageFile);
String mediaId = uploadResult.getMediaId();
// Send image message
WxMaKefuMessage imageMsg = WxMaKefuMessage.newImageBuilder()
.toUser("oLVPpjqs9BhvzwPj5A-vTYAX3GLc")
.mediaId(mediaId)
.build();
try {
wxService.getMsgService().sendKefuMsg(imageMsg);
logger.info("Image message sent successfully");
} catch (WxErrorException e) {
logger.error("Failed to send image message: {}", e.getMessage());
}WxMaKefuMessage linkMsg = WxMaKefuMessage.newLinkBuilder()
.toUser("oLVPpjqs9BhvzwPj5A-vTYAX3GLc")
.title("Special Offer")
.description("Check out our latest products with 50% off!")
.url("https://yourstore.com/offers")
.thumbUrl("https://yourstore.com/images/offer-thumb.jpg")
.build();
try {
wxService.getMsgService().sendKefuMsg(linkMsg);
} catch (WxErrorException e) {
logger.error("Failed to send link message: {}", e.getMessage());
}// Upload thumbnail image first
File thumbFile = new File("/path/to/thumbnail.jpg");
WxMediaUploadResult thumbResult = mediaService.uploadMedia("thumb", thumbFile);
WxMaKefuMessage cardMsg = WxMaKefuMessage.newMaPageBuilder()
.toUser("oLVPpjqs9BhvzwPj5A-vTYAX3GLc")
.title("Product Details")
.pagePath("pages/product/detail?id=123")
.thumbMediaId(thumbResult.getMediaId())
.appid("your-miniprogram-appid") // Optional, defaults to current app
.build();
try {
wxService.getMsgService().sendKefuMsg(cardMsg);
} catch (WxErrorException e) {
logger.error("Failed to send mini program card: {}", e.getMessage());
}// Template variables map
Map<String, WxMaSubscribeData> data = new HashMap<>();
data.put("thing1", new WxMaSubscribeData("iPhone 14 Pro")); // Product name
data.put("amount2", new WxMaSubscribeData("¥8999.00")); // Amount
data.put("date3", new WxMaSubscribeData("2023-12-01 14:30")); // Order time
data.put("thing4", new WxMaSubscribeData("ORD20231201001")); // Order number
WxMaSubscribeMessage subscribeMsg = new WxMaSubscribeMessage();
subscribeMsg.setToUser("oLVPpjqs9BhvzwPj5A-vTYAX3GLc");
subscribeMsg.setTemplateId("your-template-id");
subscribeMsg.setPage("pages/order/detail?id=123");
subscribeMsg.setData(data);
subscribeMsg.setMiniprogramState("formal"); // formal, trial, developer
try {
wxService.getMsgService().sendSubscribeMsg(subscribeMsg);
logger.info("Subscription message sent successfully");
} catch (WxErrorException e) {
int errorCode = e.getError().getErrorCode();
if (errorCode == 43101) {
logger.warn("User refused to receive subscription messages");
} else if (errorCode == 47003) {
logger.error("Template parameters error");
} else {
logger.error("Failed to send subscription message: {}", e.getMessage());
}
}WxMaSubscribeMessage msg = new WxMaSubscribeMessage()
.toUser("oLVPpjqs9BhvzwPj5A-vTYAX3GLc")
.templateId("your-template-id")
.page("pages/order/detail?id=123")
.addData("thing1", "iPhone 14 Pro")
.addData("amount2", "¥8999.00", "#FF0000") // Red color
.addData("date3", "2023-12-01 14:30")
.addData("thing4", "ORD20231201001");
wxService.getMsgService().sendSubscribeMsg(msg);WxMaSubscribeService subscribeService = wxService.getSubscribeService();
try {
// Get public template categories
List<CategoryData> categories = subscribeService.getCategory();
for (CategoryData category : categories) {
logger.info("Category: {} - {}", category.getId(), category.getName());
}
// Get public template titles
String[] categoryIds = {"1", "2", "3"};
PubTemplateTitleListResult titles = subscribeService.getPubTemplateTitleList(
categoryIds, 0, 10
);
for (PubTemplateTitle title : titles.getData()) {
logger.info("Template: {} - {}", title.getTid(), title.getTitle());
// Get keywords for this template
List<PubTemplateKeyword> keywords = subscribeService.getPubTemplateKeyWordsById(title.getTid());
for (PubTemplateKeyword keyword : keywords) {
logger.info(" Keyword: {} - {}", keyword.getKid(), keyword.getName());
}
}
} catch (WxErrorException e) {
logger.error("Failed to get templates: {}", e.getMessage());
}try {
// Add template with selected keywords
List<Integer> keywordIds = Arrays.asList(1, 3, 5, 7); // Selected keyword IDs
String templateId = subscribeService.addTemplate(
"templateTitleId", // Public template title ID
keywordIds, // Selected keyword IDs
"Order notification template" // Usage scenario description
);
logger.info("Added template: {}", templateId);
} catch (WxErrorException e) {
if (e.getError().getErrorCode() == 47001) {
logger.error("Template parameter error");
}
}// Send to both mini program and official account users
WxMaUniformMessage uniformMsg = new WxMaUniformMessage();
uniformMsg.setToUser("oLVPpjqs9BhvzwPj5A-vTYAX3GLc");
// Mini program subscription message
WxMaSubscribeMessage maMsg = new WxMaSubscribeMessage();
maMsg.setTemplateId("miniprogram-template-id");
maMsg.addData("thing1", "Order shipped");
maMsg.addData("thing2", "Your order is on the way!");
uniformMsg.setMaTemplateMsg(maMsg);
// Official account template message
WxMpTemplateMessage mpMsg = new WxMpTemplateMessage();
mpMsg.setTemplateId("official-account-template-id");
mpMsg.addData(new WxMpTemplateData("first", "Order Update"));
mpMsg.addData(new WxMpTemplateData("keyword1", "Order shipped"));
mpMsg.setUrl("https://yoursite.com/order/123");
uniformMsg.setMpTemplateMsg(mpMsg);
try {
wxService.getMsgService().sendUniformMsg(uniformMsg);
} catch (WxErrorException e) {
logger.error("Failed to send uniform message: {}", e.getMessage());
}try {
// Create activity ID for dynamic message
JsonObject activityResult = wxService.getMsgService().createUpdatableMessageActivityId();
String activityId = activityResult.get("activity_id").getAsString();
// Store activityId for later updates
// This would be returned to client for sharing
// Later, update the message (e.g., when game status changes)
WxMaUpdatableMsg updateMsg = new WxMaUpdatableMsg();
updateMsg.setActivityId(activityId);
updateMsg.setTargetState(1); // 0: not started, 1: in progress, 2: completed
List<WxMaUpdatableMsg.UpdatableTemplateData> templateData = new ArrayList<>();
templateData.add(new WxMaUpdatableMsg.UpdatableTemplateData("member_count", "3"));
templateData.add(new WxMaUpdatableMsg.UpdatableTemplateData("room_limit", "6"));
templateData.add(new WxMaUpdatableMsg.UpdatableTemplateData("path", "pages/room/room?roomId=123"));
templateData.add(new WxMaUpdatableMsg.UpdatableTemplateData("version_type", "develop"));
updateMsg.setTemplateInfo(templateData);
// Update the shared message
wxService.getMsgService().setUpdatableMsg(updateMsg);
logger.info("Dynamic message updated successfully");
} catch (WxErrorException e) {
logger.error("Failed to handle dynamic message: {}", e.getMessage());
}@Service
public class MessageService {
public void sendCustomerServiceMessage(String openid, String content) {
WxMaKefuMessage message = WxMaKefuMessage.newTextBuilder()
.toUser(openid)
.content(content)
.build();
try {
wxService.getMsgService().sendKefuMsg(message);
} catch (WxErrorException e) {
int errorCode = e.getError().getErrorCode();
String errorMsg = e.getError().getErrorMsg();
switch (errorCode) {
case 45015:
logger.warn("Reply time exceeded for user: {}", openid);
break;
case 45047:
logger.warn("Customer service interface usage limit exceeded");
break;
case 40003:
logger.error("Invalid openid: {}", openid);
break;
case 45006:
logger.warn("Cannot send messages - user has blocked messages");
break;
default:
logger.error("Failed to send customer service message: {} - {}",
errorCode, errorMsg);
}
throw new MessageSendException("Failed to send message", errorCode, errorMsg);
}
}
}@Service
public class BatchMessageService {
@Async
public void sendBatchSubscriptionMessages(List<String> userIds, String templateId,
Map<String, String> templateData) {
for (String userId : userIds) {
try {
WxMaSubscribeMessage message = new WxMaSubscribeMessage();
message.setToUser(userId);
message.setTemplateId(templateId);
// Convert template data
Map<String, WxMaSubscribeData> data = new HashMap<>();
templateData.forEach((key, value) ->
data.put(key, new WxMaSubscribeData(value)));
message.setData(data);
wxService.getMsgService().sendSubscribeMsg(message);
// Delay to avoid rate limiting
Thread.sleep(100);
} catch (WxErrorException e) {
logger.warn("Failed to send message to user {}: {}", userId, e.getMessage());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
logger.error("Batch message sending interrupted");
break;
}
}
}
}The messaging service provides comprehensive communication capabilities with proper error handling, template management, and support for all WeChat message types.
Install with Tessl CLI
npx tessl i tessl/maven-com-github-binarywang--weixin-java-miniapp