WeChatLoginBridge.ets 3.33 KB
import Want from '@ohos.app.ability.Want';
import common from '@ohos.app.ability.common';
import {
  BaseReq,
  BaseResp,
  ErrCode,
  SendAuthReq,
  SendAuthResp,
  WXAPIFactory,
  WXApi,
  WXApiEventHandler,
} from '@tencent/wechat_open_sdk';
import { FlutterError, Result, WeChatHostApi } from '../pigeon/WeChatApi';

/**
 * Fill in the AppID created for the HarmonyOS application in WeChat Open
 * Platform. Keep AppSecret on the server only.
 */
const WECHAT_APP_ID = '';

/** Bridges the native OpenSDK authorization callback to Flutter. */
export class WeChatLoginBridge extends WeChatHostApi implements WXApiEventHandler {
  private readonly context: common.UIAbilityContext;
  private readonly wxApi: WXApi;
  private pendingResult: Result<string> | null = null;

  constructor(context: common.UIAbilityContext) {
    super();
    this.context = context;
    this.wxApi = WXAPIFactory.createWXAPI(WECHAT_APP_ID, context);
  }

  requestAuthorizationCode(result: Result<string>): void {
    if (WECHAT_APP_ID.length === 0) {
      result.error(new FlutterError(
        'wechat_app_id_missing',
        'WeChatError',
        'Set WECHAT_APP_ID in WeChatLoginBridge.ets first.',
      ));
      return;
    }
    if (this.pendingResult !== null) {
      result.error(new FlutterError(
        'wechat_authorization_in_progress',
        'WeChatError',
        'WeChat authorization is already in progress.',
      ));
      return;
    }
    if (!this.wxApi.isWXAppInstalled()) {
      result.error(new FlutterError(
        'wechat_not_installed',
        'WeChatError',
        'WeChat is not installed.',
      ));
      return;
    }

    const request = new SendAuthReq();
    request.scope = 'snsapi_userinfo';
    request.state = 'none';
    request.callbackAbility = 'EntryAbility';
    this.pendingResult = result;

    try {
      const sent = this.wxApi.sendReq(this.context, request);
      if (sent instanceof Promise) {
        sent.then((success) => this.onRequestSent(success)).catch((error: Error) => {
          this.finishWithError('wechat_request_failed', error.message);
        });
      } else {
        this.onRequestSent(sent);
      }
    } catch (error) {
      this.finishWithError('wechat_request_failed', (error as Error).message);
    }
  }

  handleWant(want: Want): void {
    this.wxApi.handleWant(want, this);
  }

  onReq(_request: BaseReq): void {}

  onResp(response: BaseResp): void {
    if (!(response instanceof SendAuthResp)) {
      return;
    }
    if (response.errCode === ErrCode.ERR_OK && response.code?.length) {
      this.finishWithCode(response.code);
      return;
    }
    this.finishWithError(
      'wechat_authorization_failed',
      response.errStr ?? `WeChat authorization failed with error ${response.errCode}.`,
    );
  }

  private onRequestSent(success: boolean): void {
    if (!success) {
      this.finishWithError('wechat_request_failed', 'Unable to open WeChat.');
    }
  }

  private finishWithCode(code: string | undefined): void {
    const result = this.pendingResult;
    this.pendingResult = null;
    if (result !== null && code !== undefined) {
      result.success(code);
    }
  }

  private finishWithError(code: string, message: string): void {
    const result = this.pendingResult;
    this.pendingResult = null;
    if (result !== null) {
      result.error(new FlutterError(code, 'WeChatError', message));
    }
  }
}