Comprehensive Java SDK for WeChat Official Account development with complete API coverage for user management, messaging, materials, menus, and WeChat platform features.
—
Complete message processing framework including routing, handling, and response building for WeChat Official Account messaging.
class WxMpMessageRouter {
// Rule creation and configuration
WxMpMessageRouterRule rule();
// Message routing
WxMpXmlOutMessage route(WxMpXmlMessage message);
WxMpXmlOutMessage route(WxMpXmlMessage message, Map<String, Object> context);
WxMpXmlOutMessage route(WxMpXmlMessage message, Map<String, Object> context,
WxMpService wxMpService, WxSessionManager sessionManager);
}
class WxMpMessageRouterRule {
// Message type matching
WxMpMessageRouterRule msgType(String msgType);
WxMpMessageRouterRule event(String event);
WxMpMessageRouterRule eventKey(String eventKey);
WxMpMessageRouterRule eventKeyRegex(String regex);
WxMpMessageRouterRule content(String content);
WxMpMessageRouterRule rContent(String regexContent);
// User matching
WxMpMessageRouterRule fromUser(String fromUser);
// Custom matching
WxMpMessageRouterRule matcher(WxMpMessageMatcher matcher);
// Handler assignment
WxMpMessageRouterRule handler(WxMpMessageHandler handler);
WxMpMessageRouterRule handler(WxMpMessageHandler handler, WxMpMessageHandler... handlers);
// Processing configuration
WxMpMessageRouterRule async(boolean async);
WxMpMessageRouterRule interceptor(WxMpMessageInterceptor interceptor);
WxMpMessageRouterRule interceptor(WxMpMessageInterceptor interceptor, WxMpMessageInterceptor... interceptors);
// Rule completion
WxMpMessageRouter end();
}interface WxMpMessageHandler {
WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context,
WxMpService wxMpService,
WxSessionManager sessionManager) throws WxErrorException;
}
interface WxMpMessageInterceptor {
boolean intercept(WxMpXmlMessage wxMessage,
Map<String, Object> context,
WxMpService wxMpService,
WxSessionManager sessionManager) throws WxErrorException;
}
interface WxMpMessageMatcher {
boolean match(WxMpXmlMessage message);
}class WxMpXmlMessage implements Serializable {
// Basic message fields
private String toUser;
private String fromUser;
private Long createTime;
private String msgType;
private Long msgId;
// Text message
private String content;
// Image message
private String picUrl;
private String mediaId;
// Voice message
private String format;
private String recognition;
// Video message
private String thumbMediaId;
// Location message
private String locationX;
private String locationY;
private String scale;
private String label;
// Link message
private String title;
private String description;
private String url;
// Event message
private String event;
private String eventKey;
private String ticket;
private String latitude;
private String longitude;
private String precision;
// Menu events
private Long menuId;
// Scan events
private String scanCodeInfo;
private String scanType;
private String scanResult;
// Photo events
private String sendPicsInfo;
private Integer count;
private List<SendPicsInfo.Item> picList;
// Location events
private String sendLocationInfo;
private String locationName;
private String address;
// All fields map for extensibility
private Map<String, Object> allFieldsMap;
// Static factory methods
public static WxMpXmlMessage fromXml(String xml);
public static WxMpXmlMessage fromXml(InputStream is);
public static WxMpXmlMessage fromEncryptedXml(String xml, WxMpConfigStorage config, String timestamp, String nonce, String msgSignature);
public static WxMpXmlMessage fromEncryptedXml(InputStream is, WxMpConfigStorage config, String timestamp, String nonce, String msgSignature);
// Getters and setters for all fields
public String getToUser();
public void setToUser(String toUser);
public String getFromUser();
public void setFromUser(String fromUser);
public Long getCreateTime();
public void setCreateTime(Long createTime);
public String getMsgType();
public void setMsgType(String msgType);
public String getContent();
public void setContent(String content);
public Long getMsgId();
public void setMsgId(Long msgId);
public String getPicUrl();
public void setPicUrl(String picUrl);
public String getMediaId();
public void setMediaId(String mediaId);
public String getFormat();
public void setFormat(String format);
public String getThumbMediaId();
public void setThumbMediaId(String thumbMediaId);
public String getLocationX();
public void setLocationX(String locationX);
public String getLocationY();
public void setLocationY(String locationY);
public String getScale();
public void setScale(String scale);
public String getLabel();
public void setLabel(String label);
public String getTitle();
public void setTitle(String title);
public String getDescription();
public void setDescription(String description);
public String getUrl();
public void setUrl(String url);
public String getEvent();
public void setEvent(String event);
public String getEventKey();
public void setEventKey(String eventKey);
public String getTicket();
public void setTicket(String ticket);
public String getLatitude();
public void setLatitude(String latitude);
public String getLongitude();
public void setLongitude(String longitude);
public String getPrecision();
public void setPrecision(String precision);
public String getRecognition();
public void setRecognition(String recognition);
}abstract class WxMpXmlOutMessage {
protected String toUserName;
protected String fromUserName;
protected Long createTime;
protected String msgType;
// Abstract methods
public abstract String toXml();
// Common methods
public String getToUserName();
public void setToUserName(String toUserName);
public String getFromUserName();
public void setFromUserName(String fromUserName);
public Long getCreateTime();
public void setCreateTime(Long createTime);
public String getMsgType();
public void setMsgType(String msgType);
}
class WxMpXmlOutTextMessage extends WxMpXmlOutMessage {
private String content;
public String getContent();
public void setContent(String content);
}
class WxMpXmlOutImageMessage extends WxMpXmlOutMessage {
private String mediaId;
public String getMediaId();
public void setMediaId(String mediaId);
}
class WxMpXmlOutVoiceMessage extends WxMpXmlOutMessage {
private String mediaId;
public String getMediaId();
public void setMediaId(String mediaId);
}
class WxMpXmlOutVideoMessage extends WxMpXmlOutMessage {
private String mediaId;
private String title;
private String description;
public String getMediaId();
public void setMediaId(String mediaId);
public String getTitle();
public void setTitle(String title);
public String getDescription();
public void setDescription(String description);
}
class WxMpXmlOutMusicMessage extends WxMpXmlOutMessage {
private String title;
private String description;
private String musicUrl;
private String hqMusicUrl;
private String thumbMediaId;
public String getTitle();
public void setTitle(String title);
public String getDescription();
public void setDescription(String description);
public String getMusicUrl();
public void setMusicUrl(String musicUrl);
public String getHqMusicUrl();
public void setHqMusicUrl(String hqMusicUrl);
public String getThumbMediaId();
public void setThumbMediaId(String thumbMediaId);
}
class WxMpXmlOutNewsMessage extends WxMpXmlOutMessage {
private List<WxMpXmlOutNewsMessage.Item> articles;
public List<Item> getArticles();
public void setArticles(List<Item> articles);
public void addArticle(Item item);
public static class Item {
private String title;
private String description;
private String picUrl;
private String url;
public String getTitle();
public void setTitle(String title);
public String getDescription();
public void setDescription(String description);
public String getPicUrl();
public void setPicUrl(String picUrl);
public String getUrl();
public void setUrl(String url);
}
}class TextBuilder {
public static WxMpXmlOutTextMessage build(String content, WxMpXmlMessage wxMessage);
}
class ImageBuilder {
public static WxMpXmlOutImageMessage build(String mediaId, WxMpXmlMessage wxMessage);
}
class VoiceBuilder {
public static WxMpXmlOutVoiceMessage build(String mediaId, WxMpXmlMessage wxMessage);
}
class VideoBuilder {
public static WxMpXmlOutVideoMessage build(String mediaId, String title, String description, WxMpXmlMessage wxMessage);
}
class MusicBuilder {
public static WxMpXmlOutMusicMessage build(String title, String description,
String musicUrl, String hqMusicUrl,
String thumbMediaId, WxMpXmlMessage wxMessage);
}
class NewsBuilder {
public static WxMpXmlOutNewsMessage build(List<WxMpXmlOutNewsMessage.Item> articles, WxMpXmlMessage wxMessage);
}// Message types from WxConsts
public static final String XmlMsgType = "MsgType";
public static final String TEXT = "text";
public static final String IMAGE = "image";
public static final String VOICE = "voice";
public static final String VIDEO = "video";
public static final String SHORTVIDEO = "shortvideo";
public static final String LOCATION = "location";
public static final String LINK = "link";
public static final String EVENT = "event";
public static final String MUSIC = "music";
public static final String NEWS = "news";
public static final String TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service";
public static final String DEVICE_TEXT = "device_text";
public static final String DEVICE_EVENT = "device_event";
public static final String DEVICE_STATUS = "device_status";
public static final String HARDWARE = "hardware";
// Event types
public static final String Event = "Event";
public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";
public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
public static final String EVENT_TYPE_SCAN = "SCAN";
public static final String EVENT_TYPE_LOCATION = "LOCATION";
public static final String EVENT_TYPE_CLICK = "CLICK";
public static final String EVENT_TYPE_VIEW = "VIEW";
public static final String EVENT_TYPE_MASSSENDJOBFINISH = "MASSSENDJOBFINISH";
public static final String EVENT_TYPE_TEMPLATESENDJOBFINISH = "TEMPLATESENDJOBFINISH";
public static final String EVENT_TYPE_SCANCODE_PUSH = "scancode_push";
public static final String EVENT_TYPE_SCANCODE_WAITMSG = "scancode_waitmsg";
public static final String EVENT_TYPE_PIC_SYSPHOTO = "pic_sysphoto";
public static final String EVENT_TYPE_PIC_PHOTO_OR_ALBUM = "pic_photo_or_album";
public static final String EVENT_TYPE_PIC_WEIXIN = "pic_weixin";
public static final String EVENT_TYPE_LOCATION_SELECT = "location_select";import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.common.api.WxConsts;
// Create message router
WxMpMessageRouter router = new WxMpMessageRouter(wxService);
// Handle text messages
router.rule()
.msgType(WxConsts.XmlMsgType.TEXT)
.handler(new TextMessageHandler())
.end();
// Handle subscribe events
router.rule()
.msgType(WxConsts.XmlMsgType.EVENT)
.event(WxConsts.EventType.SUBSCRIBE)
.handler(new SubscribeHandler())
.end();
// Handle menu click events
router.rule()
.msgType(WxConsts.XmlMsgType.EVENT)
.event(WxConsts.EventType.CLICK)
.eventKey("MENU_KEY_HELP")
.handler(new HelpMenuHandler())
.end();
// Route incoming message
WxMpXmlOutMessage response = router.route(incomingMessage);public class TextMessageHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context,
WxMpService wxMpService,
WxSessionManager sessionManager) throws WxErrorException {
String content = wxMessage.getContent();
if ("help".equalsIgnoreCase(content)) {
return TextBuilder.build("Help information here", wxMessage);
} else if (content.startsWith("weather")) {
// Handle weather query
String weatherInfo = getWeatherInfo(content);
return TextBuilder.build(weatherInfo, wxMessage);
} else {
return TextBuilder.build("Echo: " + content, wxMessage);
}
}
private String getWeatherInfo(String query) {
// Weather service implementation
return "Weather information for " + query;
}
}
public class SubscribeHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context,
WxMpService wxMpService,
WxSessionManager sessionManager) throws WxErrorException {
// Welcome new subscriber
String welcomeMessage = "Welcome to our WeChat Official Account! " +
"Send 'help' for available commands.";
return TextBuilder.build(welcomeMessage, wxMessage);
}
}// Complex routing with multiple conditions
router.rule()
.msgType(WxConsts.XmlMsgType.TEXT)
.rContent("(?i)^(hi|hello|hey).*") // Case-insensitive greeting regex
.handler(new GreetingHandler())
.end();
// Handle different users differently
router.rule()
.msgType(WxConsts.XmlMsgType.TEXT)
.fromUser("admin_openid")
.handler(new AdminHandler())
.end();
// Custom matcher
router.rule()
.matcher(message -> {
// Custom logic for complex conditions
return message.getContent() != null &&
message.getContent().contains("urgent");
})
.handler(new UrgentMessageHandler())
.async(true) // Handle asynchronously
.end();
// Interceptor for logging
router.rule()
.msgType(WxConsts.XmlMsgType.TEXT)
.interceptor((wxMessage, context, wxMpService, sessionManager) -> {
System.out.println("Processing message from: " + wxMessage.getFromUser());
return true; // Continue processing
})
.handler(new LoggedTextHandler())
.end();public class MenuHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context,
WxMpService wxMpService,
WxSessionManager sessionManager) throws WxErrorException {
String eventKey = wxMessage.getEventKey();
switch (eventKey) {
case "MENU_NEWS":
return buildNewsMessage(wxMessage);
case "MENU_IMAGE":
return buildImageMessage(wxMessage);
case "MENU_VOICE":
return buildVoiceMessage(wxMessage);
default:
return TextBuilder.build("Unknown menu option", wxMessage);
}
}
private WxMpXmlOutNewsMessage buildNewsMessage(WxMpXmlMessage wxMessage) {
List<WxMpXmlOutNewsMessage.Item> articles = new ArrayList<>();
WxMpXmlOutNewsMessage.Item item1 = new WxMpXmlOutNewsMessage.Item();
item1.setTitle("Latest News");
item1.setDescription("Check out our latest updates");
item1.setPicUrl("https://example.com/image1.jpg");
item1.setUrl("https://example.com/news/1");
articles.add(item1);
WxMpXmlOutNewsMessage.Item item2 = new WxMpXmlOutNewsMessage.Item();
item2.setTitle("Product Updates");
item2.setDescription("New features available now");
item2.setPicUrl("https://example.com/image2.jpg");
item2.setUrl("https://example.com/news/2");
articles.add(item2);
return NewsBuilder.build(articles, wxMessage);
}
private WxMpXmlOutImageMessage buildImageMessage(WxMpXmlMessage wxMessage) {
return ImageBuilder.build("media_id_123", wxMessage);
}
private WxMpXmlOutVoiceMessage buildVoiceMessage(WxMpXmlMessage wxMessage) {
return VoiceBuilder.build("voice_media_id_456", wxMessage);
}
}// QR code scan events
router.rule()
.msgType(WxConsts.XmlMsgType.EVENT)
.event(WxConsts.EventType.SCAN)
.handler(new QrScanHandler())
.end();
// Location events
router.rule()
.msgType(WxConsts.XmlMsgType.EVENT)
.event(WxConsts.EventType.LOCATION)
.handler(new LocationHandler())
.end();
public class QrScanHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context,
WxMpService wxMpService,
WxSessionManager sessionManager) throws WxErrorException {
String eventKey = wxMessage.getEventKey();
String ticket = wxMessage.getTicket();
// Process QR code scan
String response = processQrScan(eventKey, ticket, wxMessage.getFromUser());
return TextBuilder.build(response, wxMessage);
}
private String processQrScan(String eventKey, String ticket, String fromUser) {
// QR code processing logic
return "QR code scanned: " + eventKey;
}
}// Parse incoming XML message
String xmlData = "..."; // Received from WeChat
WxMpXmlMessage message = WxMpXmlMessage.fromXml(xmlData);
// Parse encrypted message
WxMpXmlMessage encryptedMessage = WxMpXmlMessage.fromEncryptedXml(
xmlData, config, timestamp, nonce, msgSignature);
// Access message data
System.out.println("Message type: " + message.getMsgType());
System.out.println("From user: " + message.getFromUser());
System.out.println("Content: " + message.getContent());public class StatefulHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context,
WxMpService wxMpService,
WxSessionManager sessionManager) throws WxErrorException {
String fromUser = wxMessage.getFromUser();
WxSession session = sessionManager.getSession(fromUser);
// Get session attribute
String state = (String) session.getAttribute("conversation_state");
if ("waiting_for_name".equals(state)) {
// Process name input
String name = wxMessage.getContent();
session.setAttribute("user_name", name);
session.setAttribute("conversation_state", "waiting_for_age");
return TextBuilder.build("Thanks " + name + "! What's your age?", wxMessage);
} else if ("waiting_for_age".equals(state)) {
// Process age input
String age = wxMessage.getContent();
String name = (String) session.getAttribute("user_name");
session.removeAttribute("conversation_state");
return TextBuilder.build(
"Nice to meet you, " + name + " (" + age + " years old)!",
wxMessage
);
} else {
// Start conversation
session.setAttribute("conversation_state", "waiting_for_name");
return TextBuilder.build("What's your name?", wxMessage);
}
}
}public class SafeMessageHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context,
WxMpService wxMpService,
WxSessionManager sessionManager) throws WxErrorException {
try {
// Message processing logic
return processMessage(wxMessage, wxMpService);
} catch (Exception e) {
// Log error
System.err.println("Error processing message: " + e.getMessage());
// Return safe fallback response
return TextBuilder.build(
"Sorry, there was an error processing your message. Please try again later.",
wxMessage
);
}
}
private WxMpXmlOutMessage processMessage(WxMpXmlMessage wxMessage, WxMpService wxMpService) {
// Actual processing logic
return TextBuilder.build("Processed successfully", wxMessage);
}
}Install with Tessl CLI
npx tessl i tessl/maven-com-github-binarywang--weixin-java-mp