UNPKG

@react-native-ohos/react-native-wechat-lib

Version:

react native ohos react native wechat lib

500 lines (453 loc) 13.2 kB
import { EventEmitter } from "events"; import { DeviceEventEmitter } from "react-native"; import WechatLib, { LaunchMiniProgramMetadata, PaymentLoad, ShareFileMetadata, ShareImageMetadata, ShareMiniProgramMetadata, ShareMusicMetadata, ShareTextMetadata, ShareVideoMetadata, ShareWebpageMetadata, SubscribeMessageMetadata, } from "./specs/NativeRNWechatLibModule"; let isAppRegistered = false; // Event emitter to dispatch request and response from WechatLib. const emitter = new EventEmitter(); DeviceEventEmitter.addListener("WeChat_Resp", (resp) => { emitter.emit(resp.type, resp); }); DeviceEventEmitter.addListener("WeChat_Req", (resp) => { emitter.emit(resp.type, resp); }); type Callback = (error: any, result: any) => void; function wrapRegisterApp(nativeFunc: ((...args: any[]) => void) | undefined) { if (!nativeFunc) { return undefined; } return (...args: any[]): Promise<boolean> => { if (isAppRegistered) { return Promise.resolve(true); } isAppRegistered = true; // 注册状态修改 return new Promise((resolve, reject) => { nativeFunc.apply(null, [ ...args, (error: any, result: any) => { if (!error) { return resolve(result); } if (typeof error === "string") { return reject(new Error(error)); } reject(error); }, ] as [...any[], Callback]); }); }; } function wrapApi(nativeFunc: ((...args: any[]) => void) | undefined) { if (!nativeFunc) { return undefined; } return (...args: any[]): Promise<any> => { if (!isAppRegistered) { return Promise.reject(new Error("registerApp required.")); } return new Promise((resolve, reject) => { nativeFunc.apply(null, [ ...args, (error: any, result: any) => { if (!error) { return resolve(result); } if (typeof error === "string") { return reject(new Error(error)); } reject(error); }, ] as [...any[], Callback]); }); }; } /** * `addListener` inherits from `events` module * @method addListener * @param {String} eventName - the event name * @param {Function} trigger - the function when event is fired */ export const addListener = emitter.addListener.bind(emitter); /** * `once` inherits from `events` module * @method once * @param {String} eventName - the event name * @param {Function} trigger - the function when event is fired */ export const once = emitter.once.bind(emitter); /** * `removeAllListeners` inherits from `events` module * @method removeAllListeners * @param {String} eventName - the event name */ export const removeAllListeners = emitter.removeAllListeners.bind(emitter); /** * @method registerApp * @param {String} appid - the app id * @return {Promise} */ export const registerApp = wrapRegisterApp(WechatLib.registerApp); // /** // * @method registerAppWithDescription // * @param {String} appid - the app id // * @param {String} appdesc - the app description // * @return {Promise} // */ // export const registerAppWithDescription = wrapRegisterApp( // WechatLib.registerAppWithDescription, // ); /** * Return if the wechat app is installed in the device. * @method isWXAppInstalled * @return {Promise} */ export const isWXAppInstalled = wrapApi(WechatLib.isWXAppInstalled); /** * Return if the wechat application supports the api * @method isWXAppSupportApi * @return {Promise} */ export const isWXAppSupportApi = wrapApi(WechatLib.isWXAppSupportApi); /** * Get the wechat app installed url * @method getWXAppInstallUrl * @return {String} the wechat app installed url */ // export const getWXAppInstallUrl = wrapApi(WechatLib.getWXAppInstallUrl); /** * Get the wechat api version * @method getApiVersion * @return {String} the api version string */ export const getApiVersion = wrapApi(WechatLib.getApiVersion); /** * Open wechat app * @method openWXApp * @return {Promise} */ export const openWXApp = wrapApi(WechatLib.openWXApp); // wrap the APIs const nativeLaunchMiniProgram = wrapApi(WechatLib.launchMiniProgram); const nativeShareText = wrapApi(WechatLib.shareText); const nativeShareImage = wrapApi(WechatLib.shareImage); const nativeShareLocalImage = wrapApi(WechatLib.shareLocalImage); const nativeShareMusic = wrapApi(WechatLib.shareMusic); const nativeShareVideo = wrapApi(WechatLib.shareVideo); const nativeShareWebpage = wrapApi(WechatLib.shareWebpage); const nativeShareMiniProgram = wrapApi(WechatLib.shareMiniProgram); const nativeSubscribeMessage = wrapApi(WechatLib.subscribeMessage); const nativeChooseInvoice = wrapApi(WechatLib.chooseInvoice); const nativeShareFile = wrapApi(WechatLib.shareFile); export const authByScan = wrapApi(WechatLib.authByScan); const NormalRes = { errCode: 0, errStr: '' }; /** * @method sendAuthRequest * @param {Array} scopes - the scopes for authentication. * @return {Promise} */ export function sendAuthRequest(scopes: string, state: string) { return new Promise((resolve, reject) => { const onSendAuthRes = (resp: any) => { WechatLib.unregisterCallback("SendAuth.Resp"); if (resp.errCode === 0) { resolve(resp); } else { reject(new WechatError(resp)); } }; WechatLib.registerCallback("SendAuth.Resp", onSendAuthRes); WechatLib.sendAuthRequest(scopes, state, () => {}); }); } /** * Share text * @method shareText * @param {Object} data */ export function shareText(data: ShareTextMetadata) { if (data && data.scene == null) { data.scene = 0; } return new Promise(async (resolve, reject) => { try { await nativeShareText?.(data) resolve(NormalRes); } catch (error) { reject({ errCode: -1, errStr: (error as Error).message }) } }); } /** * Choose Invoice * @method chooseInvoice * @param {Object} data */ export function chooseInvoice(data = {}) { return new Promise((resolve, reject) => { nativeChooseInvoice?.(data); emitter.once("WXChooseInvoiceResp.Resp", (resp) => { if (resp.errCode === 0) { resolve(resp); } else { reject(new WechatError(resp)); } }); }); } /** * Share File * @method shareFile * @param {Object} data */ export function shareFile(data: ShareFileMetadata) { return new Promise((resolve, reject) => { nativeShareFile?.(data); emitter.once("SendMessageToWX.Resp", (resp) => { if (resp.errCode === 0) { resolve(resp); } else { reject(new WechatError(resp)); } }); }); } /** * Share image * @method shareImage * @param {Object} data */ export function shareImage(data: ShareImageMetadata) { if (data && data.scene == null) { data.scene = 0; } return new Promise(async (resolve, reject) => { try { await nativeShareImage?.(data); resolve(NormalRes); } catch (error) { reject({ errCode: -1, errStr: (error as Error).message }) } }); } /** * Share local image * @method shareLocalImage * @param {Object} data */ export function shareLocalImage(data: ShareImageMetadata) { if (data && data.scene == null) { data.scene = 0; } return new Promise(async (resolve, reject) => { try { await nativeShareLocalImage?.(data); resolve(NormalRes); } catch (error) { reject({ errCode: -1, errStr: (error as Error).message }) } }); } /** * Share music * @method shareMusic * @param {Object} data */ export function shareMusic(data: ShareMusicMetadata) { if (data && data.scene == null) { data.scene = 0; } return new Promise((resolve, reject) => { nativeShareMusic?.(data); emitter.once("SendMessageToWX.Resp", (resp) => { if (resp.errCode === 0) { resolve(resp); } else { reject(new WechatError(resp)); } }); }); } /** * Share video * @method shareVideo * @param {Object} data */ export function shareVideo(data: ShareVideoMetadata) { if (data && data.scene == null) { data.scene = 0; } return new Promise((resolve, reject) => { nativeShareVideo?.(data); emitter.once("SendMessageToWX.Resp", (resp) => { if (resp.errCode === 0) { resolve(resp); } else { reject(new WechatError(resp)); } }); }); } /** * Share webpage * @method shareWebpage * @param {Object} data */ export function shareWebpage(data: ShareWebpageMetadata) { if (data && data.scene == null) { data.scene = 0; } return new Promise((resolve, reject) => { nativeShareWebpage?.(data); emitter.once("SendMessageToWX.Resp", (resp) => { if (resp.errCode === 0) { resolve(resp); } else { reject(new WechatError(resp)); } }); }); } /** * Share miniProgram * @method shareMiniProgram * @param {Object} data */ export function shareMiniProgram(data: ShareMiniProgramMetadata) { if (data && data.scene == null) { data.scene = 0; } if (data && data.miniProgramType == null) { data.miniProgramType = 0; } return new Promise((resolve, reject) => { nativeShareMiniProgram?.(data); emitter.once("SendMessageToWX.Resp", (resp) => { if (resp.errCode === 0) { resolve(resp); } else { reject(new WechatError(resp)); } }); }); } /** * 打开小程序 * @method launchMini * @param * @param {String} userName - 拉起的小程序的username * @param {Integer} miniProgramType - 拉起小程序的类型. 0-正式版 1-开发版 2-体验版 * @param {String} path - 拉起小程序页面的可带参路径,不填默认拉起小程序首页 */ export function launchMiniProgram({ userName, miniProgramType = 0, path = "" }: LaunchMiniProgramMetadata) { return new Promise((resolve, reject) => { if (miniProgramType !== 0 && miniProgramType !== 1 && miniProgramType !== 2) { reject( new WechatError({ errStr: "拉起小程序的类型不对,0-正式版 1-开发版 2-体验版", errCode: -1, }) ); return; } const onLaunchMiniRes = (resp: any) => { WechatLib.unregisterCallback("WXLaunchMiniProgramReq.Resp"); if (resp.errCode === 0) { resolve(resp); } else { reject(new WechatError(resp)); } }; WechatLib.registerCallback("WXLaunchMiniProgramReq.Resp", onLaunchMiniRes); nativeLaunchMiniProgram?.({ userName, miniProgramType, path }); }); } /** * 一次性订阅消息 * @method shareVideo * @param {Object} data */ export function subscribeMessage(data: SubscribeMessageMetadata) { if (data && data.scene == null) { data.scene = 0; } return new Promise((resolve, reject) => { nativeSubscribeMessage?.(data); emitter.once("WXSubscribeMsgReq.Resp", (resp) => { if (resp.errCode === 0) { resolve(resp); } else { reject(new WechatError(resp)); } }); }); } interface PayResponse { errCode: number; errStr?: string; [key: string]: any; } /** * 支付 * @param data PaymentLoad * @returns Promise<PayResponse> */ export function pay(data: PaymentLoad): Promise<PayResponse> { function correct(actual: keyof PaymentLoad, fixed: keyof PaymentLoad) { if (!data[fixed] && data[actual]) { data[fixed] = data[actual]; delete data[actual]; } } correct("prepayid" as keyof PaymentLoad, "prepayId"); correct("noncestr" as keyof PaymentLoad, "nonceStr"); correct("partnerid" as keyof PaymentLoad, "partnerId"); correct("timestamp" as keyof PaymentLoad, "timeStamp"); data.timeStamp = String(data.timeStamp); return new Promise((resolve, reject) => { const onPayRes = (resp: any) => { WechatLib.unregisterCallback("Pay.Resp"); if (resp.errCode === 0) { resolve(resp); } else { reject(new WechatError(resp)); } }; WechatLib.registerCallback("Pay.Resp", onPayRes); WechatLib.pay(data, (result: any) => { if (result) reject(result); }); }); } /** * promises will reject with this error when API call finish with an errCode other than zero. */ interface WechatResponse { errCode: number; errStr?: string; } export class WechatError extends Error { code: number; constructor(resp: WechatResponse) { const message = resp.errStr || resp.errCode.toString(); super(message); this.name = "WechatError"; this.code = resp.errCode; // 处理 Babel 对 Error 类继承的限制 if (typeof Object.setPrototypeOf === "function") { Object.setPrototypeOf(this, WechatError.prototype); } else { // @ts-ignore this.__proto__ = WechatError.prototype; } } }