CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-github-binarywang--weixin-java-mp

Comprehensive Java SDK for WeChat Official Account development with complete API coverage for user management, messaging, materials, menus, and WeChat platform features.

Pending
Overview
Eval results
Files

template-messaging.mddocs/

Template Messaging

Send template messages to users with dynamic content for notifications, confirmations, and personalized communications.

Template Message Service Interface

interface WxMpTemplateMsgService {
  // Template message operations
  WxMpTemplateMsgResult sendTemplateMsg(WxMpTemplateMessage templateMessage) throws WxErrorException;
  List<WxMpTemplate> getAllPrivateTemplate() throws WxErrorException;
  String addTemplate(String shortTemplateId) throws WxErrorException;
  boolean delPrivateTemplate(String templateId) throws WxErrorException;
  
  // Industry management
  WxMpTemplateIndustry getIndustry() throws WxErrorException;
  void setIndustry(WxMpTemplateIndustry industry) throws WxErrorException;
  
  // Subscribe message support (for Mini Programs)
  List<WxMpSubscribeMessage> getSubscribeMessages() throws WxErrorException;
}

Data Models

Template Message

class WxMpTemplateMessage implements Serializable {
  private String toUser;
  private String templateId;
  private String url;
  private WxMpTemplateMessage.MiniProgram miniProgram;
  private String clientMsgId;
  private List<WxMpTemplateData> data;
  
  public String getToUser();
  public void setToUser(String toUser);
  public String getTemplateId();
  public void setTemplateId(String templateId);
  public String getUrl();
  public void setUrl(String url);
  public MiniProgram getMiniProgram();
  public void setMiniProgram(MiniProgram miniProgram);
  public String getClientMsgId();
  public void setClientMsgId(String clientMsgId);
  public List<WxMpTemplateData> getData();
  public void setData(List<WxMpTemplateData> data);
  
  // Convenience methods
  public WxMpTemplateMessage addData(WxMpTemplateData datum);
  public WxMpTemplateMessage addData(String name, String value);
  public WxMpTemplateMessage addData(String name, String value, String color);
  
  public static class MiniProgram implements Serializable {
    private String appid;
    private String pagepath;
    private Boolean usePath;
    
    public String getAppid();
    public void setAppid(String appid);
    public String getPagepath();
    public void setPagepath(String pagepath);
    public Boolean getUsePath();
    public void setUsePath(Boolean usePath);
  }
}

class WxMpTemplateData implements Serializable {
  private String name;
  private String value;
  private String color;
  
  public WxMpTemplateData();
  public WxMpTemplateData(String name, String value);
  public WxMpTemplateData(String name, String value, String color);
  
  public String getName();
  public void setName(String name);
  public String getValue();
  public void setValue(String value);
  public String getColor();
  public void setColor(String color);
}

Template Message Result

class WxMpTemplateMsgResult implements Serializable {
  private String msgId;
  
  public String getMsgId();
  public void setMsgId(String msgId);
}

Template Information

class WxMpTemplate implements Serializable {
  private String templateId;
  private String title;
  private String primaryIndustry;
  private String deputyIndustry;
  private String content;
  private String example;
  
  public String getTemplateId();
  public void setTemplateId(String templateId);
  public String getTitle();
  public void setTitle(String title);
  public String getPrimaryIndustry();
  public void setPrimaryIndustry(String primaryIndustry);
  public String getDeputyIndustry();
  public void setDeputyIndustry(String deputyIndustry);
  public String getContent();
  public void setContent(String content);
  public String getExample();
  public void setExample(String example);
}

Industry Information

class WxMpTemplateIndustry implements Serializable {
  private String primaryIndustryCode;
  private String primaryIndustryName;
  private String secondaryIndustryCode;
  private String secondaryIndustryName;
  
  public String getPrimaryIndustryCode();
  public void setPrimaryIndustryCode(String primaryIndustryCode);
  public String getPrimaryIndustryName();
  public void setPrimaryIndustryName(String primaryIndustryName);
  public String getSecondaryIndustryCode();
  public void setSecondaryIndustryCode(String secondaryIndustryCode);
  public String getSecondaryIndustryName();
  public void setSecondaryIndustryName(String secondaryIndustryName);
}

Subscribe Message

class WxMpSubscribeMessage implements Serializable {
  private String priTmplId;
  private String title;
  private String content;
  private String example;
  private Integer type;
  
  public String getPriTmplId();
  public void setPriTmplId(String priTmplId);
  public String getTitle();
  public void setTitle(String title);
  public String getContent();
  public void setContent(String content);
  public String getExample();
  public void setExample(String example);
  public Integer getType();
  public void setType(Integer type);
}

Usage Examples

Send Basic Template Message

// Create template message
WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
    .toUser("user_openid")
    .templateId("template_id")
    .url("https://www.example.com/details")
    .build();

// Add template data
templateMessage.addData("first", "Hello!")
               .addData("keyword1", "Order #12345", "#173177")
               .addData("keyword2", "Processing", "#FF0000")
               .addData("keyword3", "2024-01-15 10:30:00")
               .addData("remark", "Thank you for your order!", "#0000FF");

// Send message
WxMpTemplateMsgResult result = wxService.getTemplateMsgService()
    .sendTemplateMsg(templateMessage);
System.out.println("Message sent with ID: " + result.getMsgId());

Send Template Message with Mini Program

// Create template message with mini program link
WxMpTemplateMessage templateMessage = new WxMpTemplateMessage();
templateMessage.setToUser("user_openid");
templateMessage.setTemplateId("template_id");

// Set mini program
WxMpTemplateMessage.MiniProgram miniProgram = new WxMpTemplateMessage.MiniProgram();
miniProgram.setAppid("miniprogram_appid");
miniProgram.setPagepath("pages/order/detail?id=12345");
miniProgram.setUsePath(true);
templateMessage.setMiniProgram(miniProgram);

// Set fallback URL for users without mini program support
templateMessage.setUrl("https://www.example.com/order/12345");

// Add data
List<WxMpTemplateData> dataList = new ArrayList<>();
dataList.add(new WxMpTemplateData("first", "Order Update"));
dataList.add(new WxMpTemplateData("keyword1", "Order #12345"));
dataList.add(new WxMpTemplateData("keyword2", "Shipped"));
dataList.add(new WxMpTemplateData("keyword3", "2024-01-15"));
dataList.add(new WxMpTemplateData("remark", "Your order has been shipped!"));
templateMessage.setData(dataList);

// Send message
WxMpTemplateMsgResult result = wxService.getTemplateMsgService()
    .sendTemplateMsg(templateMessage);

Send Template Message with Client Message ID

// Generate unique client message ID for deduplication
String clientMsgId = "client_msg_" + System.currentTimeMillis();

WxMpTemplateMessage templateMessage = new WxMpTemplateMessage();
templateMessage.setToUser("user_openid");
templateMessage.setTemplateId("template_id");
templateMessage.setClientMsgId(clientMsgId); // Prevents duplicate sends
templateMessage.setUrl("https://www.example.com");

// Add data
templateMessage.addData("first", "Payment Confirmation")
               .addData("keyword1", "Payment Success")
               .addData("keyword2", "$99.99")
               .addData("keyword3", "2024-01-15 14:30:00")
               .addData("remark", "Payment completed successfully!");

WxMpTemplateMsgResult result = wxService.getTemplateMsgService()
    .sendTemplateMsg(templateMessage);

Manage Template Library

// Get all private templates
List<WxMpTemplate> templates = wxService.getTemplateMsgService()
    .getAllPrivateTemplate();

System.out.println("Available templates:");
for (WxMpTemplate template : templates) {
    System.out.println("ID: " + template.getTemplateId());
    System.out.println("Title: " + template.getTitle());
    System.out.println("Content: " + template.getContent());
    System.out.println("Example: " + template.getExample());
    System.out.println("---");
}

// Add new template from template library
String shortTemplateId = "TM00015"; // Template library ID
String templateId = wxService.getTemplateMsgService().addTemplate(shortTemplateId);
System.out.println("Added template with ID: " + templateId);

// Delete private template
boolean deleted = wxService.getTemplateMsgService()
    .delPrivateTemplate("template_id_to_delete");
if (deleted) {
    System.out.println("Template deleted successfully");
}

Industry Management

// Set industry information
WxMpTemplateIndustry industry = new WxMpTemplateIndustry();
industry.setPrimaryIndustryCode("1"); // IT/Internet/Communication/Electronics
industry.setSecondaryIndustryCode("4"); // Internet/E-commerce
wxService.getTemplateMsgService().setIndustry(industry);

// Get current industry
WxMpTemplateIndustry currentIndustry = wxService.getTemplateMsgService().getIndustry();
System.out.println("Primary: " + currentIndustry.getPrimaryIndustryName());
System.out.println("Secondary: " + currentIndustry.getSecondaryIndustryName());

Batch Template Messages

public void sendBatchTemplateMessages(List<String> userOpenIds, String templateId) {
    for (String openId : userOpenIds) {
        try {
            WxMpTemplateMessage message = createTemplateMessage(openId, templateId);
            WxMpTemplateMsgResult result = wxService.getTemplateMsgService()
                .sendTemplateMsg(message);
            
            System.out.println("Sent to " + openId + " - Message ID: " + result.getMsgId());
            
            // Add delay to avoid rate limiting
            Thread.sleep(100);
            
        } catch (WxErrorException e) {
            System.err.println("Failed to send to " + openId + ": " + e.getMessage());
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            break;
        }
    }
}

private WxMpTemplateMessage createTemplateMessage(String openId, String templateId) {
    WxMpTemplateMessage message = new WxMpTemplateMessage();
    message.setToUser(openId);
    message.setTemplateId(templateId);
    message.setUrl("https://www.example.com/user/" + openId);
    
    // Personalized content
    message.addData("first", "Dear Customer")
           .addData("keyword1", "System Notification")
           .addData("keyword2", "Important Update")
           .addData("keyword3", new Date().toString())
           .addData("remark", "Please check your account for details.");
           
    return message;
}

Template Message Event Handling

// Handle template message send completion events
public class TemplateMsgEventHandler implements WxMpMessageHandler {
    @Override
    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
                                   Map<String, Object> context,
                                   WxMpService wxMpService,
                                   WxSessionManager sessionManager) throws WxErrorException {
        
        // Template message send status event
        if ("TEMPLATESENDJOBFINISH".equals(wxMessage.getEvent())) {
            String status = wxMessage.getStatus();
            String msgId = wxMessage.getMsgId();
            
            switch (status) {
                case "success":
                    System.out.println("Template message " + msgId + " sent successfully");
                    break;
                case "failed:user block":
                    System.out.println("Template message " + msgId + " failed: user blocked");
                    // Handle user block scenario
                    break;
                case "failed:system failed":
                    System.out.println("Template message " + msgId + " failed: system error");
                    // Handle system failure
                    break;
                default:
                    System.out.println("Template message " + msgId + " status: " + status);
            }
        }
        
        return null; // No response needed for event notifications
    }
}

// Register event handler
router.rule()
    .msgType(WxConsts.XmlMsgType.EVENT)
    .event("TEMPLATESENDJOBFINISH")
    .handler(new TemplateMsgEventHandler())
    .end();

Custom Template Message Builder

public class TemplateMessageBuilder {
    
    public static WxMpTemplateMessage buildOrderNotification(String openId, 
                                                           String orderId, 
                                                           String status, 
                                                           String amount,
                                                           String orderTime) {
        return WxMpTemplateMessage.builder()
            .toUser(openId)
            .templateId("ORDER_NOTIFICATION_TEMPLATE_ID")
            .url("https://www.example.com/order/" + orderId)
            .build()
            .addData("first", "Order Status Update")
            .addData("keyword1", "Order #" + orderId)
            .addData("keyword2", status)
            .addData("keyword3", amount)
            .addData("keyword4", orderTime)
            .addData("remark", "Thank you for your business!");
    }
    
    public static WxMpTemplateMessage buildPaymentNotification(String openId,
                                                             String paymentId,
                                                             String amount,
                                                             String paymentTime) {
        return WxMpTemplateMessage.builder()
            .toUser(openId)
            .templateId("PAYMENT_NOTIFICATION_TEMPLATE_ID")
            .url("https://www.example.com/payment/" + paymentId)
            .build()
            .addData("first", "Payment Confirmation", "#00FF00")
            .addData("keyword1", "Payment #" + paymentId)
            .addData("keyword2", amount, "#FF0000")
            .addData("keyword3", paymentTime)
            .addData("remark", "Payment completed successfully!");
    }
    
    public static WxMpTemplateMessage buildAppointmentReminder(String openId,
                                                             String appointmentId,
                                                             String service,
                                                             String dateTime,
                                                             String location) {
        return WxMpTemplateMessage.builder()
            .toUser(openId)
            .templateId("APPOINTMENT_REMINDER_TEMPLATE_ID")
            .url("https://www.example.com/appointment/" + appointmentId)
            .build()
            .addData("first", "Appointment Reminder")
            .addData("keyword1", service)
            .addData("keyword2", dateTime, "#FF0000")
            .addData("keyword3", location)
            .addData("remark", "Please arrive 10 minutes early.");
    }
}

// Usage
WxMpTemplateMessage orderMsg = TemplateMessageBuilder.buildOrderNotification(
    "user_openid", "12345", "Shipped", "$99.99", "2024-01-15 10:30:00");
wxService.getTemplateMsgService().sendTemplateMsg(orderMsg);

Error Handling and Retry Logic

public class TemplateMessageSender {
    private final WxMpService wxService;
    private final int maxRetries = 3;
    
    public TemplateMessageSender(WxMpService wxService) {
        this.wxService = wxService;
    }
    
    public boolean sendTemplateMessageWithRetry(WxMpTemplateMessage message) {
        for (int attempt = 1; attempt <= maxRetries; attempt++) {
            try {
                WxMpTemplateMsgResult result = wxService.getTemplateMsgService()
                    .sendTemplateMsg(message);
                
                System.out.println("Message sent successfully: " + result.getMsgId());
                return true;
                
            } catch (WxErrorException e) {
                int errorCode = e.getError().getErrorCode();
                
                if (shouldRetry(errorCode) && attempt < maxRetries) {
                    System.out.println("Attempt " + attempt + " failed, retrying...");
                    try {
                        Thread.sleep(1000 * attempt); // Exponential backoff
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        return false;
                    }
                } else {
                    handleTemplateMessageError(e, message);
                    return false;
                }
            }
        }
        return false;
    }
    
    private boolean shouldRetry(int errorCode) {
        switch (errorCode) {
            case -1:    // System busy
            case 45047: // Template message send frequency limit
            case 41028: // Form id invalid or expired
                return true;
            case 43004: // User not subscribed
            case 43101: // User refused to receive messages
                return false; // Don't retry for user-related errors
            default:
                return false;
        }
    }
    
    private void handleTemplateMessageError(WxErrorException e, WxMpTemplateMessage message) {
        int errorCode = e.getError().getErrorCode();
        String errorMsg = e.getError().getErrorMsg();
        
        switch (errorCode) {
            case 43004:
                System.err.println("User not subscribed: " + message.getToUser());
                // Log or handle unsubscribed users
                break;
            case 43101:
                System.err.println("User refused messages: " + message.getToUser());
                // Add to do-not-send list
                break;
            case 40037:
                System.err.println("Invalid template ID: " + message.getTemplateId());
                break;
            case 41028:
                System.err.println("Form ID invalid: " + message.getClientMsgId());
                break;
            case 45047:
                System.err.println("Send frequency limit exceeded");
                break;
            default:
                System.err.println("Template message error " + errorCode + ": " + errorMsg);
        }
    }
}

Template Message Colors

Common color codes for template message data:

  • #173177 - Dark blue (default)
  • #FF0000 - Red (for important/urgent information)
  • #00FF00 - Green (for success/positive information)
  • #0000FF - Blue (for links/actions)
  • #FFA500 - Orange (for warnings)
  • #808080 - Gray (for secondary information)

Industry Codes

Common industry codes for template message setup:

  • 1 - IT/Internet/Communication/Electronics
  • 2 - Finance/Banking/Insurance
  • 3 - Real Estate
  • 4 - Education
  • 5 - Healthcare/Medical
  • 6 - Transportation/Logistics
  • 7 - Entertainment/Media
  • 8 - Government/Public Services

Best Practices

  1. Template Selection: Choose appropriate templates from the WeChat template library
  2. Content Relevance: Ensure template content matches your business needs
  3. Personalization: Use dynamic data to personalize messages
  4. Color Usage: Use colors strategically to highlight important information
  5. URL Links: Provide meaningful landing pages for template message links
  6. Rate Limiting: Respect WeChat's sending frequency limits
  7. User Experience: Don't overuse template messages to avoid user fatigue
  8. Error Handling: Implement proper error handling and retry logic
  9. Mini Program Integration: Use mini program links for better user experience
  10. Analytics: Track template message performance and user engagement

Rate Limits

  • Maximum 100,000 template messages per day for verified accounts
  • Maximum 1,000 template messages per day for unverified accounts
  • No more than 4 template messages per user per day
  • Minimum 12-hour interval between messages to the same user for some template types

Common Error Codes

  • 40037: Invalid template_id
  • 41028: Form_id invalid or expired
  • 41029: Form_id used
  • 41030: Page unreachable
  • 43004: User not subscribed
  • 43101: User refused to receive messages
  • 45047: Template message send frequency limit exceeded
  • 47001: Template message data format error
  • 47003: Template message count exceeded daily limit

Install with Tessl CLI

npx tessl i tessl/maven-com-github-binarywang--weixin-java-mp

docs

advanced-services.md

index.md

material-management.md

menu-management.md

message-handling.md

service-management.md

shopping-guide.md

template-messaging.md

user-management.md

tile.json