Skip to content

微信小程序 隐私协议指南

基于2023-09-15小程序隐私协议开发指南Taro框架接入

注意

微信官方最新公告已经不需要开发手动设置。此文档仅作参考

⚠️ 在小程序后台填写用户隐私协议

【注:这一步未完成前,后续步骤在调用隐私相关 Api 时将一直报错,且无法调试完整流程】

  1. 根据微信提供的表格,排查项目中涉及的隐私 API https://developers.weixin.qq.com/miniprogram/dev/framework/user-privacy/miniprogram-intro.html
  2. 对涉及的 API 做好 try catch 处理,防止用户【拒绝隐私协议】时 API 没有对应的处理
  3. 业务方需在微信后台填写【左侧栏“设置” - 基本设置 - 服务内容声明 - 用户隐私保护指引】
  4. 如下参考:

img

1. 开发者工具基础库改为 3.0.0 以上,并开启【独立域调试】

2. app.config.ts

js
{
  ...,
  // 2023.09.15 之后可以不加
  __usePrivacyCheck__: true
}

3. 引入 @tarojs/plugin-inject 使 taro 支持 bindagreeprivacyauthorization

sh
pnpm add -D @tarojs/plugin-inject --filter @wmeimob/mini-app
js
// packages/mini-app/config/index.js

module.exports = {
  plugins: [
    [
      '@tarojs/plugin-inject',
      {
        components: {
          Button: {
            bindagreeprivacyauthorization: ''
          }
        }
      }
    ]
  ]
}

4. 入口文件 app.ts

js
if (isWeapp && wx.onNeedPrivacyAuthorization) {
  // 调试用
  // wx.getPrivacySetting({
  //   success: (res) => {
  //     console.log(`res  ______  `, res)
  //   }
  // })

  const callbacks = new Set<(result: TWeappPrivacyResult) => void>()

  // 基于事件通知 pageContainer 的协议弹窗
  Taro.eventCenter.on('weappPrivacyResult', (agree: boolean) => {
    const res: TWeappPrivacyResult = agree ? { event: 'agree', buttonId: 'privacy-agree-btn' } : { event: 'disagree' }
    callbacks.forEach((callback) => callback(res))
    callbacks.clear()
  })

  wx.onNeedPrivacyAuthorization((resolve) => {
    callbacks.add(resolve)
    Taro.eventCenter.trigger('weappPrivacy')
  })
}

// 入口文件其他代码
export default (props) => {
  useApp()
  return props.children
}

5. pageContainer 埋入协议弹窗,并监听 app.ts 的事件通知

js
// components/taro-design/src/layout/pageContainer/index.tsx

import Privacy from './privacy';

function () {
  return (
    <View {...rest} className={classNames(className, isLinear && 'LinearBackground')}>
      {props.children}

      ... 
      
      // 引入下面的协议组件
      <Privacy />
    </View>
  )
}

隐私组件。可以按具体实际情况进行调整

js
// components/taro-design/src/layout/pageContainer/privacy/index.tsx

const appName = '美萌'
const privacyName = '《美萌软件隐私保护指引》'

const Component: FC<IPrivacyProps> = (props) => {
  const [visible, setVisible] = useState(false)

  useEffect(() => {
    const self = getCurrentInstance().router?.path

    const listener = (pageUrl: string) => {
      pageUrl === self && setVisible(true)
    }

    Taro.eventCenter.on('weappPrivacy', listener)

    return () => {
      Taro.eventCenter.off('weappPrivacy', listener)
    }
  }, [])

  function handleAgree() {
    Taro.eventCenter.trigger('weappPrivacyResult', true)
    setVisible(false)
  }

  function handleDisagree() {
    Taro.eventCenter.trigger('weappPrivacyResult', false)
    setVisible(false)
  }

  const okText = (
    <View className={styles.agree}>
      <Text>同意</Text>
      <Button
        className={styles.openTypeButton}
        // 这个 id 与 app.ts 中的保持一致
        id="privacy-agree-btn"
        open-type="agreePrivacyAuthorization"
        // @ts-ignore
        onAgreePrivacyAuthorization={handleAgree}
        // 微信真机低版本基础库不会响应 onAgreePrivacyAuthorization ,因此需要做兜底处理
        onClick={wx.onAgreePrivacyAuthorization ? undefined : handleAgree}
      />
    </View>
  )

  return (
    <MMDialog visible={visible} title="用户隐私保护提示" okText={okText} cancelText="拒绝" onCancel={handleDisagree}>
      <View>
        在您使用【{appName}】服务之前,请仔细阅读
        <Text
          className={styles.link}
          onClick={() => {
            // 低基础库小程序不存在 openPrivacyContract api
            wx.openPrivacyContract 
              ? wx.openPrivacyContract() 
              : Taro.navigateTo('你项目中原来的隐私协议页面')
          }}
        >
          {privacyName}
        </Text>
        。如您同意{privacyName},请点击“同意”开始使用【{appName}】
      </View>
    </MMDialog>
  )
}

另一种方案【未实践,理论上可行】

方案思路

不在页面中弹出协议弹窗,而是小程序告知需要弹隐私协议时,跳转到一个统一的空白页,空白页中弹出【隐私协议弹窗】。
该方案可以避免上一个方案在 pageContainer 中埋入隐私协议这类业务代码的弊端