위챗 플랫폼의 [화웨이 운동건강] 공식계정은 사용자가 최신 랭킹을 클릭할 때 실시간 운동 데이터를 전송합니다. 이 기능은 일반 메시지와 템플릿 메시지 두 가지 형태로 제공됩니다.
본 문서는 weixin-java-mp 라이브러리를 사용하여 위챗 공식계정의 자동 응답 기능을 구현하는 방법을 설명합니다.
참고 문서: https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Passive_user_reply_message.html
weixin-java-tools 라이브러리 사용 시 주요 장점:
- 위챗 API 통합 제공 (URL, AccessToken 관리 필요 없음)
- XML 포맷 자동 변환 기능
- 메시지 라우팅 기능이 강력한 WxMpMessageRouter 제공
Maven 의존성 추가 예시:
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>3.6.0</version>
</dependency>
공식 문서: https://github.com/binarywang/weixin-java-mp-demo
Spring Boot 예제: https://github.com/Thinkingcao/SpringBootLearning/tree/master/springboot-wechat
-
공식계정 서버 설정 ==================
-
https://mp.weixin.qq.com 접속 후 개발자 설정 메뉴 이동
-
AppId 및 Secret 정보 수집
-
서버 주소 설정 및 암호화 설정
-
XML 메시지 처리 로직 구현
예제 코드:
@PostMapping("/wechat/callback")
public String handleWechatRequest(@RequestBody String xmlData,
@RequestParam("signature") String sig,
@RequestParam("timestamp") String ts,
@RequestParam("nonce") String nonce,
@RequestParam("echostr") String echoStr) {
if (validateSignature(sig, ts, nonce, token)) {
return echoStr;
}
throw new RuntimeException("인증 실패");
}
private boolean validateSignature(String sig, String ts, String nonce, String token) {
String[] params = {token, ts, nonce};
Arrays.sort(params);
String sha1 = DigestUtils.sha1Hex(String.join("", params));
return sha1.equals(sig);
}
- WxMpService 설정 및 메시지 라우팅 ===================================
WxMpConfig 클래스 예시:
@Configuration
public class WechatConfig {
@Value("${wechat.app-id}")
private String officialAccountId;
@Value("${wechat.secret}")
private String apiSecret;
@Value("${wechat.token}")
private String securityToken;
@Value("${wechat.aes-key}")
private String encryptionKey;
@Bean
public WxMpService wechatService() {
WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
config.setAppId(officialAccountId);
config.setSecret(apiSecret);
config.setToken(securityToken);
config.setAesKey(encryptionKey);
return new WxMpServiceImpl(config);
}
@Bean
public WxMpMessageRouter messageRouter(WxMpService service) {
WxMpMessageRouter router = new WxMpMessageRouter(service);
// 기본 로깅 핸들러
router.rule().handler(logHandler).next();
// 구독 이벤트 처리
router.rule()
.event(EventType.SUBSCRIBE)
.handler(subscribeHandler)
.end();
// 텍스트 메시지 처리
router.rule()
.msgType(XmlMsgType.TEXT)
.handler(textHandler)
.end();
return router;
}
}
- 메시지 핸들러 구현 ====================
메시지 처리 핸들러 예시:
@Component
public class TextMessageHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage message) {
if (message.getContent().equals("최신 라이브")) {
return WxMpKefuMessage
.MINIPROGRAMPAGE()
.title("라이브 스트리밍")
.toUser(message.getFromUser())
.thumbMediaId("MEDIA_ID")
.appId("MINIAPP_ID")
.pagePath("pages/live/live")
.build();
}
return WxMpXmlOutMessage
.TEXT()
.content("안녕하세요, 도움이 필요하신가요?")
.fromUser(message.getFromUser())
.toUser(message.getToUser())
.build();
}
}
- 커스텀 메시지 전송 ====================
소재 업로드 예시:
WxMpMaterialService materialService = wxService.getMaterialService();
WxMediaUploadResult result = materialService.mediaUpload(
WxConsts.KefuMsgType.IMAGE,
"cover.jpg",
inputStream
);
String mediaId = result.getMediaId();
메시지 전송 예시:
wxService.getKefuService().sendKefuMessage(
WxMpKefuMessage
.TEXT()
.toUser(openId)
.content("관리자 메시지입니다.")
.build()
);