Wechatty 프로젝트는 WeChat 공용 계정(서비스 계정 및 구독 계정 포함) 및 WeChat 기업 계정을 위한 JAVA 기반 개발 프레임워크로, 잘 캡슐화된 API를 통해 개발자는 비즈니스 로직 개발에 집중하고 개발 효율성을 높일 수 있습니다.
여기서 Maven은 종속성을 도입하는 데 사용됩니다.
<dependency>
<groupId>space.chensheng.wechatty</groupId>
<artifactId>wechatty-mp</artifactId>
<version>2.0.0</version>
</dependency>
MpAppContext
는 WechatMpBootstrap
사용하여 초기화되는 공용 계정 API에 대한 통합 호출 입구입니다.
WechatMpBootstrap bootstrap = new WechatMpBootstrap();
bootstrap.addMsgListener(new TextMessageListener());
MpAppContext mpAppContext = bootstrap.build();
프로젝트가 spring을 사용하여 관리되는 경우 FactoryBean
구현하여 후속 참조를 위해 MpAppContext
초기화할 수 있습니다.
@Component
public class MpAppContextFactoryBean implements FactoryBean<MpAppContext> {
@Override
public MpAppContext getObject() throws Exception {
WechatMpBootstrap bootstrap = new WechatMpBootstrap();
bootstrap.addMsgListener(new TextMessageListener());
return bootstrap.build();
}
@Override
public Class<?> getObjectType() {
return MpAppContext.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
구성 방법에는 두 가지가 있습니다. 하나는配置文件
이고 다른 하나는 JAVA代码配置
입니다. JAVA代码配置
의 우선순위는配置文件
우선순위보다 높습니다.
새 구성 파일 wechat-mp.properties를 생성하고 해당 파일을 프로젝트 클래스 경로에 배치합니다. 예를 들어, Maven 프로젝트에서 이 파일은 src/main/resources
디렉터리에 배치될 수 있습니다. 일반적인 구성은 다음과 같습니다.
token=thisIsToken
aesKey=thisIsAesKey
appId=thisIsYourAppId
appSecret=thisIsAppSecret
MpAppConetxt
초기화되면 WechatMpBootstrap
의 customizeWechatContext
메소드를 호출하여 구성합니다.
WechatMpBootstrap bootstrap = new WechatMpBootstrap();
bootstrap.customizeWechatContext(new MpWechatContextCustomizer() {
@Override
public void customize(MpWechatContext wechatContext) {
wechatContext.setToken("thisIsToken");
wechatContext.setAesKey("thisIsAeskey");
wechatContext.setAppId("thisIsAppId");
wechatContext.setAppSecret("thisIsAppSecret");
}
});
필수 매개변수 | 설명하다 |
---|---|
토큰 | 공식계정의 토큰은 공식계정 백그라운드에서 확인할 수 있습니다. |
에이스키 | 암호화에 사용된 키는 공식 계정 백그라운드에서 확인할 수 있습니다. |
앱 ID | 공식계정의 appId는 공식계정 백그라운드에서 확인할 수 있습니다. |
앱비밀 | 공식계정의 appSecret은 공식계정 백그라운드에서 보실 수 있습니다. |
선택적 매개변수 | 설명하다 |
---|---|
암호화 모드 활성화 | 콜백 암호화 모드 활성화 여부, 기본값은 true입니다. 켜져 있는 경우 jdk의 관련 파일을 포함하는 JCE 무제한 권한 정책 파일을 다운로드해야 합니다. 자세한 내용은 WeChat의 일반적인 오류 예를 참조하세요. |
autoUpdateAccessToken | access_token 관련 오류 발생 시 access_token을 자동으로 업데이트할지 여부. 기본값은 false입니다. 애플리케이션은 예약된 작업을 통해 이를 업데이트할 수 있으며 이에 대해서는 나중에 자세히 소개합니다. |
accessTokenStrategyClass | access_token 액세스 전략(기본값은 space.chensheng.wechatty.common.http.MemoryAccessTokenStrategy)이며, access_token을 메모리에 저장하고, 애플리케이션은 이를 데이터베이스에 저장하는 등 자체 액세스 전략을 구현할 수 있습니다. 자세한 내용은 나중에. |
페이키 | 위챗 결제 키 |
지불인증서파일 | WeChat 결제 인증서 파일 경로 |
payCert 비밀번호 | WeChat 결제 인증서 비밀번호 |
payMchId | 위챗결제 가맹점ID |
payClientIp | 결제를 위해 기기 IP를 호출하세요. |
poolingHttpProxyEnable | 프록시 서버를 통해 WeChat 서버를 요청할지 여부, 기본값은 false입니다. |
poolingHttpProxyHostname | www.chensheng.space와 같은 프록시 서버의 호스트 이름 |
poolingHttpProxyPort | 프록시 서버 포트 |
poolingHttpProxy사용자 이름 | 프록시 서버 사용자 이름 |
poolingHttpProxyPassword | 프록시 서버 비밀번호 |
poolingHttpMaxPerRoute | http 연결 풀의 링크당 최대 동시 연결 수, 기본값은 50입니다. |
poolingHttpMaxTotal | http 연결 풀의 최대 동시 연결 수, 기본값 200 |
poolingHttpSocketTimeoutMillis | 소켓 시간 초과의 밀리초 수(기본값 10000) |
poolingHttpConnectTimeoutMillis | WeChat 서버 시간 초과에 연결하는 데 걸리는 시간(밀리초), 기본값은 10000 |
poolingHttpConnectionRequestTimeoutMillis | http 연결 풀에서 연결 시간 초과 밀리초를 가져옵니다. 기본값은 10000입니다. |
poolingHttpTcpNoDelay | tpcNoDelay 활성화 여부, 기본값은 true |
mpAppContext.getAccessTokenFetcher().updateAccessToken()
실행합니다. 일반적으로 1.5시간마다 한 번씩 실행됩니다.accessTokenStrategyClass=your.package.name.YourAccessTokenStrategy
구성을 추가하세요. 다음은 accesss_token 데이터베이스에 액세스하기 위한 전략입니다. import space . chensheng . wechatty . common . http . AccessTokenStrategy ;
//因为这个策略类的实例化不是通过Spring来管理的,所以在这个类中不能使用Autowired来注入bean,
//要通过ApplicationContext#getBean方法来获取。
public class DatabaseAccessTokenStrategy implements AccessTokenStrategy {
//将access_token存到数据库中去
@ Override
public void doSave ( String accessToken ) {
TokenService tokenService = ApplicationContextUtil
. getApplicationContext (). getBean ( TokenService . class );
tokenService . doSave ( accessToken );
}
//从数据库中取出access_token
@ Override
public String doQuery () {
TokenService tokenService = ApplicationContextUtil
. getApplicationContext (). getBean ( TokenService . class );
return tokenService . doQuery ();
}
}
MpAppContext
초기화되면 WechatMpBootstrap
통해 메시지 리스너를 추가하여 메시지를 수신합니다(메시지 리스너는 나중에 소개됩니다).
WechatMpBootstrap bootstrap = new WechatMpBootstrap();
bootstrap.addMsgListener(new TextMessageListener());
bootstrap.addMsgListener(new SubscribeEventListener());
bootstrap.addMsgListener(new UnsubscribeEventListener());
WeChat 공식 계정 백그라운드에서 콜백 URL을 설정한 경우 WeChat 서버는 확인을 위해 이 URL로 GET 요청을 보냅니다. 개발자는 웹 애플리케이션에서 이 요청을 처리해야 합니다. 다음은 SpringMVC 검증 예시이다:
@RestController
@RequestMapping(value = "/wechat-mp")
public class CallbackController extends BaseController{
@Autowired
private MpAppContext mpAppContext;
//验证请求,并回复字符串
@RequestMapping(value = "/callback", method = RequestMethod.GET)
public String verify(String msg_signature, String timestamp, String nonce, String echostr) {
String reply = mpAppContext.getCallbackModeVerifier().verify(msg_signature, timestamp, nonce, echostr);
return reply;
}
}
콜백 요청을 확인한 후 실제로 콜백 모드가 활성화됩니다. 사용자가 공식 계정으로 메시지를 보내면 WeChat 서버는 콜백 URL로 POST 요청을 보내고 이 URL로 메시지를 전달합니다. 개발자는 웹 애플리케이션에서 이 요청을 처리해야 합니다. 다음은 SpringMVC의 예입니다. (및 컨트롤러에서 콜백을 활성화하는 이전 확인 예):
@RestController
@RequestMapping(value = "/wechat-mp")
public class CallbackController extends BaseController{
@Autowired
private MpAppContext mpAppContext;
//接收回调消息,并回复相应xml消息
@RequestMapping(value = "/callback", method = RequestMethod.POST)
public String verify(String msg_signature, String timestamp, String nonce) {
//postBody是请求体内容,String格式,开发者可以通过HttpServletRequest来解析
String replyXml = mpAppContext.getMpMessageDispatcher().dispatch(msg_signature(), timestamp, nonce, postBody);
return replyXml;
}
}
개발자는 space.chensheng.wechatty.common.message.MessageListener
상속하여 특정 유형의 메시지를 수신할 수 있습니다. 다음은 사용자가 보낸 문자 메시지를 듣는 예입니다.
public class TextMessageListener extends MessageListener<TextInboundMessage> {
@Override
protected ReplyMessage onMessage(TextInboundMessage message) {
String content = message.getContent();
//根据消息内容来回复用户
if ("1".equals(content)) {
TextReplyMessage replyMsg = new TextReplyMessage();
replyMsg.setContent("this is reply message content");
replyMsg.setFromUserName(message.getToUserName());
replyMsg.setToUserName(message.getFromUserName());
replyMsg.setCreateTime(System.currentTimeMillis());
return replyMsg;
}
//返回null表示不回复用户
return null;
}
}
정보 | 설명하다 |
---|---|
텍스트인바운드메시지 | 문자 메시지 |
이미지인바운드메시지 | 그림 메시지 |
링크인바운드메시지 | 그래픽 메시지로 이동 |
위치인바운드메시지 | 위치 정보 공유 |
짧은동영상인바운드메시지 | 작은 영상 메시지 |
비디오인바운드메시지 | 영상 메시지 |
음성인바운드메시지 | 음성 메시지 |
클릭이벤트메시지 | 일반 메뉴 메시지를 클릭하세요. |
이벤트 메시지 보기 | 링크 메뉴 메시지로 이동하려면 클릭하세요. |
위치이벤트메시지 | 위치 이벤트 메시지 |
구독이벤트메시지 | 사용자는 공개 계정 뉴스를 따릅니다. |
구독 취소이벤트 메시지 | 공개 계정 메시지를 팔로우 취소하는 것을 잊지 마세요. |
스캔이벤트메시지 | 사용자가 QR 코드 메시지를 스캔합니다. |
MassSendJobFinishEventMessage | 그룹 메시지 전송 완료 보고서 |
정보 | 설명하다 |
---|---|
텍스트답장메시지 | 문자 답장 |
이미지답글메시지 | 그림 답장 |
음악답장메시지 | 음악 답장 |
뉴스답글메시지 | 그래픽 응답 |
비디오답장메시지 | 영상 답장 |
음성답장메시지 | 음성 답장 |
공식 계정에서는 그룹 메시지, 고객 서비스 메시지 등 사용자에게 적극적으로 메시지를 보낼 수 있습니다. 모든 메시지는 space.chensheng.wechatty.mp.message.MpMessageSender
사용하여 균일하게 전송됩니다.
TextMassMessage message = new TextMassMessage();
message.setIsToAll(true);
message.setContent("群发消息测试");
mpAppContext.getMpMessageSender().send(message, 3);
그룹 메시지 유형 | 설명하다 |
---|---|
TextMass메시지 | 대량 텍스트 |
이미지질량메시지 | 사진 그룹 보내기 |
MpnewsMass메시지 | WeChat 내에서 사진 및 텍스트 그룹 전송 |
MpvideoMass메시지 | 영상 그룹 전송 |
VoiceMass메시지 | 음성 그룹 전송 |
WxcardMassMessage | 위챗 카드 및 쿠폰 대량 배포 |
TextCsMessage message = new TextCsMessage();
message.setToUser("thisIsUserOpenId");
message.setContent("客服消息测试 n 212");
mpAppContext.getMpMessageSender().send(message, 3);
고객 서비스 메시지 유형 | 설명하다 |
---|---|
텍스트Cs메시지 | 문자 고객 서비스 |
이미지Cs메시지 | 사진 고객 서비스 |
MpnewsCs메시지 | WeChat 내 그래픽 고객 서비스 |
뉴스Cs메시지 | 외부 그래픽 고객 서비스 |
VideoCs메시지 | 비디오 고객 서비스 |
VoiceCs메시지 | 음성 고객 서비스 |
WxcardCs메시지 | WeChat 카드 및 바우처 고객 서비스 |
자료 관리에는 주로 자료 업로드, 조회, 수정 및 삭제가 포함됩니다. 자료 유형에는 사진, 비디오, 음성 및 그래픽이 포함됩니다.
해당 자료 업로드 클래스를 운영하면 자료 업로드가 완료됩니다. 다음은 이미지 업로드 예입니다.
File image = new File("/this/is/image/path.jpg");
ImagePermanentMedia material = new ImagePermanentMedia(mpAppContext, image);
UploadResponse resp = material.upload();
자료 업로드 수업 | 설명하다 |
---|---|
이미지영구미디어 | 영구 사진 |
엄지손가락영구적인미디어 | 영구 썸네일 |
비디오영구미디어 | 영구 비디오 |
VoicePermanentMedia | 영구 음성 |
영구뉴스 | 영구 사진 및 텍스트 |
영구뉴스Img | 영구 그래픽의 그림 |
이미지임시미디어 | 임시 사진 |
엄지손가락임시미디어 | 임시 썸네일 |
비디오임시미디어 | 임시 비디오 |
음성임시미디어 | 임시 음성 |
재료 쿼리 작업은 도구 클래스 space.chensheng.wechatty.mp.material.MaterialQuery
및 space.chensheng.wechatty.mp.material.MaterialFinder
를 통해 완료됩니다.
mpAppContext.getMaterialQuery().count()
mpAppContext.getMaterialQuery().listNews(int offset, int count)
mpAppContext.getMaterialQuery().listMedia(MediaType mediaType, int offset, int count)
mpAppContext.getMaterialFinder().findNews(String mediaId)
mpAppContext.getMaterialFinder().findPermanentVideo(String mediaId)
mpAppContext.getMaterialFinder().findTemporaryVideo(String mediaId)
mpAppContext.getMaterialFinder().downloadPermanentMedia(String mediaId, String saveDir, String fileName)
mpAppContext.getMaterialFinder().downloadTemporaryMedia(String mediaId, String saveDir, String fileName)
재료 삭제 작업은 도구 클래스 space.chensheng.wechatty.mp.material.MaterialDeleter
를 통해 완료됩니다.
mpAppContext.getMaterialDeleter().delete(String mediaId)
매개변수가 포함된 QR 코드 생성은 도구 클래스 space.chensheng.wechatty.mp.account.QRCodeCreator
를 통해 완료됩니다.
mpAppContext.getQRCodeCreator().createTemporary(int expireSeconds, int sceneId)
mpAppContext.getQRCodeCreator().createPermanent(int sceneId)
mpAppContext.getQRCodeCreator().createPermanent(String sceneStr)
사용자 정보 조회는 UserInfoQuery
를 통해 구현됩니다.
mpAppConext.getUserInfoQuery().get(String openId)
mpAppContext.getUserInfoQuery().batchGet(List<String> openIds)
사용자 인증은 AuthHelper
통해 구현됩니다.
mpAppContext.getAuthHelper().fetchAuthAccessToken(String code)
통해 auth access token
가져옵니다.auth access token
새로 고침 : mpAppContext.getAuthHelper().refreshAuthAccessToken(String refreshAccessToken)
auth access token
통해 사용자 정보 가져오기 : mpAppContext.getAuthHelper().fetchAuthUserInfo(String authAccessToken, String openId)
다음은 사용자 인증을 위한 의사코드입니다.
public WxAuthLoginDto authAndLogin(String code) {
AuthAccessTokenResponse authResp = mpAppContext.getAuthHelper().fetchAuthAccessToken(code);
if (authResp == null || !authResp.isOk()) {
//授权失败,执行相应业务逻辑
return new WxAuthLoginDto("fail");
}
String openId = authResp.getOpenId();
AuthUserInfoResponse wxUserInfo = mpAppContext.getAuthHelper().fetchAuthUserInfo(authResp.getAccessToken(), authResp.getOpenId())
//根据微信用户信息在数据库里查找系统对应的用户,或新建一个用户
//进行登录相关业务逻辑处理
return new WxAuthLoginDto("success");
}
jsapi 인증은 JsapiHelper
통해 구현됩니다.
jsapi ticket
받기(예약된 작업을 사용하여 정기적으로 티켓을 받고 데이터베이스에 저장할 수 있음): mpAppContext.getJsapiHelper().fetchTicket()
mpAppContext.getJsapiHelper().generateSignature(String jsapiTicket, String nonceStr, long timestamp, String url)
MpAppContext
초기화할 때 WechatMpBootstrap
의 enablePayCert()
메서드를 호출하여 WeChat 결제를 활성화하고 관련 매개변수를 구성합니다. (특정 매개변수는 구성 모듈을 참조하세요)
WechatMpBootstrap bootstrap = new WechatMpBootstrap();
bootstrap.enablePayCert();
mpAppContext.getPayHelper().sendRedPack(RedPackRequest request)
mpAppContext.getPayHelper().sendGroupRedPack(GroupRedPackRequest request)
mpAppContext.getPayHelper().transfers(TransfersRequest request)
mpAppContext.getPayHelper().unifiedOrder(UnifiedOrderRequest request)
mpAppContext.getPayHelper().parsePayNotify(String notifyContent)
mpAppContext.getPayHelper().validatePayNotify(PayNotifyResponse response)
mpAppContext.getPayHelper().orderQuery(OrderQueryRequest request)
mpAppContext.getPayHelper().closeOrder(CloseOrderRequest request)
mpAppContext.getPayHelper().shortUrl(String longUrl)
mpAppContext.getPayHelper().generateJsapiPayParams(String prepayId, PaySignType signType)
mpAppContext.getPayHelper().refund(RefundRequest request)
mpAppContext.getPayHelper().parseRefundNotify(String notifyContent)