Wechattty Project هو إطار تطوير قائم على JAVA لحسابات WeChat العامة (بما في ذلك حسابات الخدمة وحسابات الاشتراك) وحسابات مؤسسة WeChat، تتيح واجهة برمجة التطبيقات المغلفة جيدًا للمطورين التركيز على تطوير منطق الأعمال وتحسين كفاءة التطوير.
يتم استخدام Maven هنا لتقديم التبعيات.
<dependency>
<groupId>space.chensheng.wechatty</groupId>
<artifactId>wechatty-mp</artifactId>
<version>2.0.0</version>
</dependency>
MpAppContext
هو مدخل الاتصال الموحد لواجهة برمجة تطبيقات الحساب العام، والذي تتم تهيئته باستخدام WechatMpBootstrap
.
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 ووضع الملف في مسار فئة المشروع. على سبيل المثال، في مشروع مخضرم، يمكن وضع هذا الملف في دليل src/main/resources
. التكوين العام هو كما يلي:
token=thisIsToken
aesKey=thisIsAesKey
appId=thisIsYourAppId
appSecret=thisIsAppSecret
عند تهيئة MpAppConetxt
، قم باستدعاء أسلوب customizeWechatContext
الخاص بـ WechatMpBootstrap
للتكوين.
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");
}
});
المعلمات المطلوبة | يوضح |
---|---|
رمز مميز | يمكن عرض رمز الحساب الرسمي في خلفية الحساب الرسمي. |
aesKey | يمكن الاطلاع على المفتاح المستخدم للتشفير في الواجهة الخلفية للحساب الرسمي. |
معرف التطبيق | يمكن عرض معرف التطبيق الخاص بالحساب الرسمي في خلفية الحساب الرسمي. |
appSecret | يمكن الاطلاع على appSecret الخاص بالحساب الرسمي في خلفية الحساب الرسمي. |
المعلمات الاختيارية | يوضح |
---|---|
تمكينCryptedMode | ما إذا كان سيتم تمكين وضع تشفير رد الاتصال، فهذا صحيح بشكل افتراضي. إذا تم تشغيله، فستحتاج إلى تنزيل ملف سياسة الأذونات غير المقيدة لـ JCE لتغطية الملفات ذات الصلة في jdk. للحصول على التفاصيل، راجع أمثلة الأخطاء الشائعة في WeChat. |
autoUpdateAccessToken | ما إذا كان سيتم تحديث Access_token تلقائيًا عند حدوث خطأ يتعلق بـ Access_token أم لا، الإعداد الافتراضي هو خطأ. يمكن للتطبيق تحديثه من خلال المهام المجدولة، والتي سيتم تقديمها بالتفصيل لاحقًا. |
AccessTokenStrategyClass | استراتيجية الوصول Access_token، الافتراضية هي space.chensheng.wechatty.common.http.MemoryAccessTokenStrategy، تقوم بتخزين Access_token في الذاكرة، ويمكن للتطبيق تنفيذ استراتيجية الوصول الخاصة به، مثل تخزينها في قاعدة البيانات، والتي سيتم تقديمها في التفاصيل في وقت لاحق. |
payKey | مفتاح الدفع WeChat |
ملف payCert | مسار ملف شهادة الدفع WeChat |
payCertPassword | كلمة مرور شهادة الدفع WeChat |
com.payMchId | معرف تاجر دفع WeChat |
payClientIp | اتصل بالجهاز IP للدفع |
poolingHttpProxyEnable | ما إذا كنت تريد طلب خادم WeChat من خلال خادم وكيل، فإن الإعداد الافتراضي هو خطأ |
poolingHttpProxyHostname | اسم المضيف للخادم الوكيل، مثل www.chensheng.space |
poolingHttpProxyPort | منفذ الخادم الوكيل |
poolingHttpProxyUsername | اسم مستخدم الخادم الوكيل |
poolingHttpProxyPassword | كلمة مرور الخادم الوكيل |
poolingHttpMaxPerRoute | الحد الأقصى لعدد الاتصالات المتزامنة لكل رابط في تجمع اتصالات http، الافتراضي هو 50 |
poolingHttpMaxTotal | الحد الأقصى لعدد الاتصالات المتزامنة في تجمع اتصالات http، الافتراضي هو 200 |
poolingHttpSocketTimeoutMillis | عدد المللي ثانية لمهلة المقبس، الافتراضي 10000 |
poolingHttpConnectTimeoutMillis | عدد المللي ثانية للاتصال بمهلة خادم WeChat، الافتراضي 10000 |
poolingHttpConnectionRequestTimeoutMillis | احصل على مهلة الاتصال بالمللي ثانية من تجمع اتصالات http، الافتراضي 10000 |
poolingHttpTcpNoDelay | ما إذا كان سيتم تمكين tpcNoDelay، فهذا صحيح بشكل افتراضي |
mpAppContext.getAccessTokenFetcher().updateAccessToken()
بانتظام، عادةً مرة واحدة كل 1.5 ساعة، لأن وقت انتهاء صلاحية Access_token هو ساعتين.accessTokenStrategyClass=your.package.name.YourAccessTokenStrategy
في wechat-mp.properties. فيما يلي استراتيجية للوصول إلى قاعدة بيانات Access_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());
إذا قمت بتعيين عنوان URL لرد الاتصال في خلفية حساب WeChat الرسمي، فسيرسل خادم WeChat طلب GET إلى عنوان URL هذا للتحقق. فيما يلي مثال للتحقق من 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 طلب POST إلى عنوان URL لرد الاتصال ويعيد توجيه الرسالة إلى عنوان 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;
}
}
معلومة | يوضح |
---|---|
TextInboundMessage | رسالة نصية |
ImageInboundMessage | رسالة مصورة |
LinkInboundMessage | انتقل إلى الرسالة الرسومية |
الموقعالرسالة الواردة | مشاركة معلومات الموقع |
رسالة قصيرة بالفيديو الوارد | رسالة فيديو صغيرة |
رسالة فيديو واردة | رسالة فيديو |
الرسالة الصوتية الواردة | رسالة صوتية |
انقر فوق رسالة الحدث | انقر على رسالة القائمة العادية |
ViewEventMessage | انقر للانتقال إلى رسالة القائمة الارتباط |
الموقع الحدث الرسالة | رسائل أحداث الموقع |
اشترك في رسالة الحدث | يتابع المستخدمون أخبار الحساب العام |
إلغاء الاشتراكEventMessage | تذكر إلغاء متابعة رسائل الحساب العام |
ScanEventMessage | يقوم المستخدم بمسح رسالة رمز الاستجابة السريعة |
MassSendJobFinishEventMessage | رسالة جماعية ترسل تقرير الإكتمال |
معلومة | يوضح |
---|---|
رسالة نصية | الرد النصي |
رسالة الرد على الصورة | الرد بالصورة |
رسالة الرد على الموسيقى | رد الموسيقى |
رسالة الرد الإخبارية | الرد الرسومي |
رسالة الرد بالفيديو | الرد بالفيديو |
رسالة الرد الصوتي | الرد الصوتي |
يمكن للحسابات الرسمية إرسال رسائل إلى المستخدمين بشكل استباقي، بما في ذلك الرسائل الجماعية ورسائل خدمة العملاء. يتم إرسال كافة الرسائل بشكل موحد باستخدام space.chensheng.wechatty.mp.message.MpMessageSender
.
TextMassMessage message = new TextMassMessage();
message.setIsToAll(true);
message.setContent("群发消息测试");
mpAppContext.getMpMessageSender().send(message, 3);
نوع الرسالة الجماعية | يوضح |
---|---|
رسالة نصية | النص السائبة |
ImageMassMessage | إرسال مجموعة الصور |
MpnewsMassMessage | إرسال مجموعة من الصور والنصوص داخل WeChat |
MpvideoMassMessage | إرسال مجموعة الفيديو |
رسالة صوتية | إرسال المجموعة الصوتية |
WxcardMassMessage | التوزيع الشامل لبطاقة WeChat والقسيمة |
TextCsMessage message = new TextCsMessage();
message.setToUser("thisIsUserOpenId");
message.setContent("客服消息测试 n 212");
mpAppContext.getMpMessageSender().send(message, 3);
نوع رسالة خدمة العملاء | يوضح |
---|---|
رسالة نصية | خدمة العملاء النصية |
ImageCsMessage | خدمة العملاء بالصور |
MpnewsCsMessage | خدمة العملاء الرسومية داخل WeChat |
رسالة أخبارCs | خدمة عملاء الجرافيك الخارجي |
VideoCsMessage | خدمة عملاء الفيديو |
رسالة صوتية | خدمة العملاء الصوتية |
WxcardCsMessage | خدمة عملاء بطاقة WeChat والقسائم |
تتضمن إدارة المواد بشكل أساسي تحميل المواد والاستعلام عنها وتعديلها وحذفها. وتشمل أنواع المواد الصور ومقاطع الفيديو والأصوات والرسومات.
يتم إكمال تحميل المواد عن طريق تشغيل فئة تحميل المواد المقابلة، وفيما يلي مثال لتحميل الصور:
File image = new File("/this/is/image/path.jpg");
ImagePermanentMedia material = new ImagePermanentMedia(mpAppContext, image);
UploadResponse resp = material.upload();
فئة تحميل المواد | يوضح |
---|---|
ImagePermanentMedia | صورة دائمة |
ThumbPermanentMedia | الصورة المصغرة الدائمة |
الوسائط الدائمة للفيديو | فيديو دائم |
الوسائط الصوتية الدائمة | صوت دائم |
أخبار دائمة | الصور والنصوص الدائمة |
أخبار دائمة | الصور في الرسومات الدائمة |
ImageTemporaryMedia | صورة مؤقتة |
ThumbTemporaryMedia | الصورة المصغرة المؤقتة |
الوسائط المؤقتة للفيديو | فيديو مؤقت |
الوسائط المؤقتة الصوتية | صوت مؤقت |
يتم إكمال عملية الاستعلام عن المواد من خلال فئات الأدوات 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
.
auth access token
من خلال رمز رابط التفويض: mpAppContext.getAuthHelper().fetchAuthAccessToken(String code)
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
، اتصل بطريقة enablePayCert()
الخاصة بـ WechatMpBootstrap
لتمكين دفع 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)