whatsapp-web.js moduleRaid 主动通信

1,765 阅读2分钟

前言:

最近在升级chrome extension插件,其实大部分chrome 插件主要通过inject script 脚本注入到页面中增强用户获取页面信息或与页面进行交互。而大部分注入脚本都只是通过获取页面dom来实现用户或产品需要的功能。最近看到whatsapp-web.js 关于与whatsapp 实现通信,发送信息等等一系列功能,尝试接入chrome 插件实现群发或自动发送信息功能。

whatsapp-web.js 实现后支持api

编辑切换为居中

whatsapp-web.js support api

参与whatsapp 通信主要逻辑

通过moduleRaid 解析whatsapp 页面window中暴露出来的webpackchunk,通过指定module实现不同功能

  • 控制台window对象是否存在webpackChunkwhatsapp_web_client (否则无法获取指定api)

编辑切换为居中

web.whatsapp.com 页面控制台 window对象

  • chrome 插件inject script 中注入moduleRaid

moduleRaid 5.0.2 yarn or npm 安装 例如:npm install moduleraid, npm地址:@pedroslopez/moduleraid

我这边直接讲moduleRaid 代码 未压缩混淆部分copy到代码中

const moduleRaid = function () {
  moduleRaid.mID  = Math.random().toString(36).substring(7);
  moduleRaid.mObj = {};

  var fillModuleArray = function() {
    (window.webpackChunkbuild || window.webpackChunkwhatsapp_web_client).push([
      [moduleRaid.mID], {}, function(e) {
        Object.keys(e.m).forEach(function(mod) {
          moduleRaid.mObj[mod] = e(mod);
        })
      }
    ]);
  }

  fillModuleArray();

  function get (id) {
    return moduleRaid.mObj[id]
  }

  function findModule (query) {
    var results = [];
    var modules = Object.keys(moduleRaid.mObj);

    modules.forEach(function(mKey) {
      var mod = moduleRaid.mObj[mKey];

      if (typeof mod !== 'undefined') {
        if (typeof query === 'string') {
          if (typeof mod.default === 'object') {
            for (var key in mod.default) {
              if (key == query) results.push(mod);
            }
          }

          for (var key in mod) {
            if (key == query) results.push(mod);
          }
        } else if (typeof query === 'function') { 
          if (query(mod)) {
            results.push(mod);
          }
        } else {
          throw new TypeError('findModule can only find via string and function, ' + (typeof query) + ' was passed');
        }
        
      }
    })

    return results;
  }

  return {
    modules: moduleRaid.mObj,
    constructors: moduleRaid.cArr,
    findModule: findModule,
    get: get
  }
}

if (typeof module === 'object' && module.exports) {
  module.exports = moduleRaid;
} else {
  window.mR = moduleRaid();
}

此时在whatsapp页面注入该段脚本,window对象中存在window.mR 这个对象

  • 组织module 获取指定api
  window.WebJS = Object.assign({}, window.mR.findModule(m => m.default && m.default.Chat)[0].default);

  // 抛出function 支持脚本调用发送消息
  window.WebJS.__send_whatsapp_msg__ = function(whatsppNo, content) {
    const chat = window.WebJS.Chat.get(`${whatsppNo}@c.us`)
    const meUser = window.mR.findModule('getMaybeMeUser')[0].getMaybeMeUser();
  
    const MsgKey = window.mR.findModule((module) => module.default && module.default.fromString)[0].default
    const genId = window.mR.findModule('newTag')?.[0]?.newTag || MsgKey.newId()
    const newMsgId = new MsgKey({
      from: meUser,
      to: chat.id,
      id: genId,
      participant: undefined,
      selfDir: 'out',
    });

    const message = {
      id: newMsgId,
      ack: 0,
      body: content,
      from: meUser,
      to: chat.id,
      local: true,
      self: 'out',
      t: parseInt(new Date().getTime() / 1000),
      isNewMsg: true,
      type: 'chat',
    };
  
    window.mR.findModule('addAndSendMsgToChat')[0].addAndSendMsgToChat(chat, message)
  }

最后在控制台中通过window调用__send_whatsapp_msg__ 方法并传入whatsapp 绑定手机号(注意⚠️:需要携带国际区号,例如:86132xxxx1234)及需要发送内容就可以实现。

思考:

竟然whatsapp-web.js 能支持上面一些列api, 通过moduleRaid 解析whatsapp_web_client 也是可以实现的,那我们就可以给项目赋能,例如群发(方便客户询盘等)

whatsapp-web.js moduleRaid 主动通信 - 知乎