binsee / padchat-sdk

padchat项目,sdk开发包,提供直接对协议服务的对接。本项目已停止维护,请转向新方案 https://github.com/botorange/wechaty-puppet-padpro
261 stars 88 forks source link

发送添加好友,目标未收到请求 #58

Closed tiandimeihua closed 5 years ago

tiandimeihua commented 5 years ago

在使用该方法时出现异常 https://github.com/binsee/padchat-sdk/blob/master/docs/index.md#padchataddcontactstranger-ticket-type-content--promiseobject

目标,添加群内好友

逻辑处理,使用padchat.getRoomMembers(groupId),查询群内所有好友,提取目标wx_id,使用 padchat.getContact(userId) ,并提取所需要参数,stranger 和ticket,传入 https://github.com/binsee/padchat-sdk/blob/master/docs/index.md#padchataddcontactstranger-ticket-type-content--promiseobject,获取返回值

message: 'user need verify', status: -44 

index.js

"use strict";

const Padchat = require("padchat-sdk");
const fs = require("fs");
const log4js = require("log4js");
const qrcode = require("qrcode-terminal");
const url = "**************";
const token = "**********";
const wx = new Padchat(url + token);

/**
 * 创建日志目录
 */

try {
  require("fs").mkdirSync("./logs");
} catch (e) {
  if (e.code !== "EEXIST") {
    console.error("Could not set up log directory, error: ", e);
    process.exit(1);
  }
}

try {
  log4js.configure("./log4js.json");
} catch (e) {
  console.error("载入log4js日志输出配置错误: ", e);
  process.exit(1);
}

const logger = log4js.getLogger("app");
const dLog = log4js.getLogger("dev");

/*
***************************************************** 
*/

wx.on("open", async () => {
  let ret;
  ret = await wx.init();
  if (!ret.success) {
    console.error("初始化失败! ret:", ret);
    logger.error("初始化失败! ret:", ret);
    return;
  }
  console.log("初始化成功! ret:", ret);
  logger.info("初始化成功! ret:", ret);

  ret = await wx.login();
  if (!ret.success) {
    console.error("请求登录失败! ret:", ret);
    logger.error("请求登录失败! ret:", ret);
    return;
  }
  console.log("请求登录成功! ret:", ret);
  logger.info("请求登录成功! ret:", ret);
})
  .on("qrcode", data => {
    if (data.url) {
      console.log("登陆二维码url: %s ,请扫码登陆:", data.url);
      logger.info("登陆二维码url: %s ,请扫码登陆:", data.url);
      qrcode.generate(data.url);
      return;
    } else if (data.qrCode) {
      console.log("登陆二维码图片数据,请输出到文件扫码。");
      logger.info("登陆二维码图片数据,请输出到文件扫码。");
      return;
    }
    console.error("没有发现二维码数据!");
    logger.error("没有发现二维码数据!");
  })
  .on("scan", data => {
    switch (data.status) {
      case 0:
        console.log("等待扫码...", data);
        logger.info("等待扫码...", data);
        break;
      case 1:
        console.log("已扫码,请在手机端确认登陆...", data);
        logger.info("已扫码,请在手机端确认登陆...", data);
        break;
      case 2:
        switch (data.subStatus) {
          case 0:
            console.log("扫码成功!登陆成功!", data);
            logger.info("扫码成功!登陆成功!", data);
            break;
          case 1:
            console.log("扫码成功!登陆失败!", data);
            logger.info("扫码成功!登陆失败!", data);
            break;
          default:
            console.log("扫码成功!未知状态码!", data);
            logger.info("扫码成功!未知状态码!", data);
            break;
        }
        break;
      case 3:
        console.log("二维码已过期", data);
        logger.info("二维码已过期", data);
        break;
      case 4:
        console.log("手机端已取消登陆!", data);
        logger.info("手机端已取消登陆!", data);
        break;
      default:
        break;
    }
  })
  .on("login", async () => {
    let ret;

    ret = await wx.getMyInfo();
    console.log(`${ret.data.userName} 登陆成功!`);
    logger.info(`${ret.data.userName} 登陆成功!`);

    try {
      ret = await wx.getRoomMembers("********@chatroom"); //拿到这个群内用户信息;
      if (ret.success) {
        for (let index = 0; index < ret.data.member.length; index++) {
          let userId = ret.data.member[index].userName; //拿到wx_id;
          console.log(`userID is ${userId}`);
          logger.info(`userID is ${userId}`);
          try {
            let getContact = await wx.getContact(userId); //拿到wx_id 对应的个人信息;
            if (getContact.success) {
              logger.info(getContact.data);
              let stranger = getContact.data.stranger;
              let ticket = getContact.data.ticket;
              try {
                //发送好友请求;
                let addContact = await wx.addContact(stranger, ticket, 8, [
                  "hhh2222222222"
                ]);
                if (addContact.success) {
                  console.log(addContact.data.message);
                  console.log(addContact.data.status);
                  logger.info(addContact.data);
                }
              } catch (error) {
                console.log(
                  `${error.message}\nfail and error to add ${userId} friend`
                );
              }
            }
          } catch (error) {
            console.log(
              `${error.message}\nfail and error to get ${userId} information`
            );
          }          
        }
        //console.log(ret.data);    //打印群内所有用户信息;
      }
    } catch (e) {
      console.log(`find err ${e.message}`);
    }
  })
  .on("loaded", async () => {
    console.log("载入通讯录完成!");
  });

log 日志


[2018-10-11T04:13:42.537] [INFO] app - 初始化成功! ret: { success: true, data: {} }
[2018-10-11T04:13:43.644] [INFO] app - 登陆二维码url: http://weixin.qq.com/x/IeSolAsCpQFi******** ,请扫码登陆:
[2018-10-11T04:13:43.702] [INFO] app - 请求登录成功! ret: { success: true, data: {}, msg: '请使用手机微信扫码登陆!' }
[2018-10-11T04:13:44.974] [INFO] app - 等待扫码... { status: 0, expiredTime: 239 }
[2018-10-11T04:13:45.984] [INFO] app - 等待扫码... { status: 0, expiredTime: 238 }
[2018-10-11T04:13:54.784] [INFO] app - 扫码成功!登陆成功! { password: '***hide***',
  status: 2,
  external: '1',
  email: '',
  message: 'Everything is ok',
  uin: 308522720,
  deviceType: 'iphone',
  expiredTime: 238,
  headUrl:
   'http://wx.qlogo.cn/mmhead/xNdVQ5mzLVIgg7yNyv4h********GqaOzd8KeCrH0Jg/0',
  nickName: 'con***',
  userName: '*********',
  subStatus: 0,
  phoneNumber: '*********',
  longLinkServer: '',
  shortLinkServer: '' }
[2018-10-11T04:13:55.069] [INFO] app - ******* 登陆成功!
[2018-10-11T04:13:56.020] [INFO] app - userID is ********
[2018-10-11T04:13:57.701] [INFO] app - { city: '',
  country: '**',
  intro: '',
  label: '',
  message: '',
  provincia: '',
  remark: '',
  sex: 2,
  signature: '*****************',
  status: 0,
  stranger: '*******',
  ticket: '',
  bigHead:
   'http://wx.qlogo.cn/mmhead/xNdVQ5mzLVIgg7yNyv4*************d8KeCrH0Jg/0',
  nickName: 'con********',
  pyInitial: 'CON******',
  quanPin: 'con******',
  remarkPyInitial: '',
  remarkQuanPin: '',
  smallHead:
   'http://wx.qlogo.cn/mmhead/xNdVQ5mzLVIgg7yNyv4*************d8KeCrH0Jg/132',
  userName: '*********' }
[2018-10-11T04:13:59.679] [INFO] app - { message: '', status: 0 }
[2018-10-11T04:13:59.679] [INFO] app - userID is wxid_1**************
[2018-10-11T04:14:00.574] [INFO] app - { city: '',
  country: '',
  intro: '',
  label: '',
  message: '',
  provincia: '',
  remark: '',
  sex: 0,
  signature: '********',
  status: 0,
  stranger:
   'v1_2e285477d1758f228ccc5be50ad9cd0676bb618980c13c1dee450234fbf6cc1b98d6ebed**************c67e37c96@stranger',
  ticket: '',
  bigHead:
   'http://wx.qlogo.cn/mmhead/ver_1/SNrytc9wpdcGvkcqtHungMvOLYs5Mf57VmIFu6cKdt****************03x2dcmyO8m6pz6FIFiakl2DB2rmjA9vNZhf59ibTHnnyA/0',
  nickName: '都*******',
  pyInitial: '******',
  quanPin: '***************',
  remarkPyInitial: '',
  remarkQuanPin: '',
  smallHead:
   'http://wx.qlogo.cn/mmhead/ver_1/SNrytc9wpdcGvkcqtHungMvOLYs5Mf57VmIFu6cKdt****************03x2dcmyO8m6pz6FIFiakl2DB2rmjA9vNZhf59ibTHnnyA/132',
  userName: 'wxid_1amnytlsidzg12' }
[2018-10-11T04:14:01.890] [INFO] app - { message: 'user need verify', status: -44 }
[2018-10-11T04:14:01.891] [INFO] app - userID is wxid_av***********
[2018-10-11T04:14:03.396] [INFO] app - { city: '',
  country: '',
  intro: '',
  label: '',
  message: '',
  provincia: '',
  remark: '',
  sex: 0,
  signature: '',
  status: 0,
  stranger:
   'v1_0eea6a210b5a12cacd3e0b9f71394566da49d8154df71a955b42d3ee****************e377d2c9bc4be68f@stranger',
  ticket: '',
  bigHead:
   'http://wx.qlogo.cn/mmhead/SYeWkon6C6L5ElG0qEXPW1stYjcibywk*************lM7K5fXJQg/0',
  nickName: 'YU********',
  pyInitial: 'YU********',
  quanPin: 'YU*********',
  remarkPyInitial: '',
  remarkQuanPin: '',
  smallHead:
   'http://wx.qlogo.cn/mmhead/SYeWkon6C6L5ElG0qEXPW1stYjcibywk*************M7K5fXJQg/132',
  userName: 'wxid_a************' }
[2018-10-11T04:14:04.687] [INFO] app - { message: 'user need verify', status: -44 }
binsee commented 5 years ago

你代码中调用的是 padchat.sayHello(stranger, ticket, content) 而非 padchat.addContact(stranger, ticket, type, [content])

其用途是不一样的,sayHello只对好友或没有开启加好友验证的用户有效

tiandimeihua commented 5 years ago

使用padchat.addContact(stranger, ticket, type, [content]) 的问题

在使用method padchat.addContact(stranger, ticket, type, [content]) 如果对方打开了好友验证,那么他无法收到我的请求。


searchAndAddFriend.js

"use strict";

const Padchat = require("padchat-sdk");
const fs = require("fs");
const log4js = require("log4js");
const qrcode = require("qrcode-terminal");
const url = "******************";
const token = "****************";
const wx = new Padchat(url + token);

/**
 * 创建日志目录
 */

try {
  require("fs").mkdirSync("./logs");
} catch (e) {
  if (e.code !== "EEXIST") {
    console.error("Could not set up log directory, error: ", e);
    process.exit(1);
  }
}

try {
  log4js.configure("./log4js.json");
} catch (e) {
  console.error("载入log4js日志输出配置错误: ", e);
  process.exit(1);
}

const logger = log4js.getLogger("app");
const dLog = log4js.getLogger("dev");

/*
*****************************************************
*/

wx.on("open", async () => {
  let ret;
  ret = await wx.init();
  if (!ret.success) {
    console.error("初始化失败! ret:", ret);
    logger.error("初始化失败! ret:", ret);
    return;
  }
  console.log("初始化成功! ret:", ret);
  logger.info("初始化成功! ret:", ret);

  ret = await wx.login();
  if (!ret.success) {
    console.error("请求登录失败! ret:", ret);
    logger.error("请求登录失败! ret:", ret);
    return;
  }
  console.log("请求登录成功! ret:", ret);
  logger.info("请求登录成功! ret:", ret);
})
  .on("qrcode", data => {
    if (data.url) {
      console.log("登陆二维码url: %s ,请扫码登陆:", data.url);
      logger.info("登陆二维码url: %s ,请扫码登陆:", data.url);
      qrcode.generate(data.url);
      return;
    } else if (data.qrCode) {
      console.log("登陆二维码图片数据,请输出到文件扫码。");
      logger.info("登陆二维码图片数据,请输出到文件扫码。");
      return;
    }
    console.error("没有发现二维码数据!");
    logger.error("没有发现二维码数据!");
  })
  .on("scan", data => {
    switch (data.status) {
      case 0:
        console.log("等待扫码...", data);
        logger.info("等待扫码...", data);
        break;
      case 1:
        console.log("已扫码,请在手机端确认登陆...", data);
        logger.info("已扫码,请在手机端确认登陆...", data);
        break;
      case 2:
        switch (data.subStatus) {
          case 0:
            console.log("扫码成功!登陆成功!", data);
            logger.info("扫码成功!登陆成功!", data);
            break;
          case 1:
            console.log("扫码成功!登陆失败!", data);
            logger.info("扫码成功!登陆失败!", data);
            break;
          default:
            console.log("扫码成功!未知状态码!", data);
            logger.info("扫码成功!未知状态码!", data);
            break;
        }
        break;
      case 3:
        console.log("二维码已过期", data);
        logger.info("二维码已过期", data);
        break;
      case 4:
        console.log("手机端已取消登陆!", data);
        logger.info("手机端已取消登陆!", data);
        break;
      default:
        break;
    }
  })

  /**
   * 执行
   * 通过指定wx_id 使用Method searchContact() 找到参数stranger 和ticket;
   * 使用Method addCOntact(),传入参数stranger, ticket, type(方式为0,通过微信号搜索)
   * 在目标微信未开启好友验证的时候成功收到了添加好友消息,同时日志打印参数返回正常 status:0
   * 在目标微信开启好友验证时,无法收到添加好友消息,日志参数打印返回正常 status:-44
   */

  .on("login", async () => {
    let ret;

    ret = await wx.getMyInfo();
    console.log(`${ret.data.userName} 登陆成功!`);
    logger.info(`${ret.data.userName} 登陆成功!`);

    try {
      let searchContact = await wx.searchContact("************");

      if (searchContact.success) {
        console.log(searchContact.data);
        logger.info(searchContact.data);

        let stranger = `${searchContact.data.userName}`;
        let ticket = `${searchContact.data.stranger}`;

        try {
          console.log(stranger);
          logger.info(stranger);
          console.log(ticket);
          logger.info(ticket);

          let addContact = await wx.addContact(stranger, ticket, 0);
          console.log(addContact.success);
          logger.info(addContact.success);
          if (addContact.success) {
            console.log("-----------------------------------");
            logger.info("-----------------------------------");
            console.log(addContact.data);
            logger.info(addContact.data);
          }
        } catch (error) {
          console.log(error.message + `fail to send add friends require`);
        }
      }
    } catch (error) {
      console.log(error.message + `fail to search this contact`);
    }
  })
  .on("loaded", async () => {
    console.log("载入通讯录完成!");
  });

未开启好友验证时日志


[2018-10-11T17:30:28.913] [INFO] app - 初始化成功! ret: { success: true, data: {} }
[2018-10-11T17:30:29.729] [INFO] app - 登陆二维码url: http://weixin.qq.com/x/4aUwC************ ,请扫码登陆:
[2018-10-11T17:30:29.785] [INFO] app - 请求登录成功! ret: { success: true, data: {}, msg: '请使用手机微信扫码登陆!' }
[2018-10-11T17:30:30.686] [INFO] app - 等待扫码... { status: 0, expiredTime: 239 }
[2018-10-11T17:30:32.054] [INFO] app - 等待扫码... { status: 0, expiredTime: 238 }
[2018-10-11T17:30:33.275] [INFO] app - 等待扫码... { status: 0, expiredTime: 237 }
[2018-10-11T17:30:34.341] [INFO] app - 等待扫码... { status: 0, expiredTime: 236 }
[2018-10-11T17:30:35.417] [INFO] app - 等待扫码... { status: 0, expiredTime: 235 }
[2018-10-11T17:30:36.314] [INFO] app - 等待扫码... { status: 0, expiredTime: 234 }
[2018-10-11T17:30:37.538] [INFO] app - 等待扫码... { status: 0, expiredTime: 232 }
[2018-10-11T17:30:38.651] [INFO] app - 等待扫码... { status: 0, expiredTime: 232 }
[2018-10-11T17:30:40.000] [INFO] app - 已扫码,请在手机端确认登陆... { status: 1,
  expiredTime: 239,
  headUrl:
   'http://wx.qlogo.cn/mmhead/xNdVQ5mzLVI************GqaOzd8KeCrH0Jg/0',
  nickName: '******' }
[2018-10-11T17:30:40.876] [INFO] app - 已扫码,请在手机端确认登陆... { status: 1,
  expiredTime: 238,
  headUrl:
   'http://wx.qlogo.cn/mmhead/xNdVQ5mzLVI************GqaOzd8KeCrH0Jg/0',
  nickName: '******' }
[2018-10-11T17:30:41.617] [INFO] app - 已扫码,请在手机端确认登陆... { status: 1,
  expiredTime: 237,
  headUrl:
   'http://wx.qlogo.cn/mmhead/xNdVQ5mzLVI************GqaOzd8KeCrH0Jg/0',
  nickName: '******' }
[2018-10-11T17:30:43.201] [INFO] app - 已扫码,请在手机端确认登陆... { status: 1,
  expiredTime: 236,
  headUrl:
   'http://wx.qlogo.cn/mmhead/xNdVQ5mzLVI************GqaOzd8KeCrH0Jg/0',
  nickName: '******' }
[2018-10-11T17:30:44.525] [INFO] app - 已扫码,请在手机端确认登陆... { status: 1,
  expiredTime: 235,
  headUrl:
   'http://wx.qlogo.cn/mmhead/xNdVQ5mzLVI************GqaOzd8KeCrH0Jg/0',
  nickName: '******' }
[2018-10-11T17:30:51.859] [INFO] app - 扫码成功!登陆成功! { password: '***hide***',
  status: 2,
  external: '1',
  email: '',
  message: 'Everything is ok',
  uin: ******,
  deviceType: 'iphone',
  expiredTime: 234,
  headUrl:
   'http://wx.qlogo.cn/mmhead/xNdVQ5mzLVI************GqaOzd8KeCrH0Jg/0',
  nickName: '******',
  userName: '******',
  subStatus: 0,
  phoneNumber: '******',
  longLinkServer: '',
  shortLinkServer: '' }
[2018-10-11T17:30:52.114] [INFO] app - ****** 登陆成功!
[2018-10-11T17:30:52.914] [INFO] app - { city: '',
  country: '',
  message: 'Everything is OK',
  provincia: '',
  sex: 0,
  signature: '******',
  status: 0,
  stranger:
   'v2_fbb1423a3247f365cc365333d4e2898d1fd317628a172c37e8c4d875a867a0550e1f******f7d@stranger',
  bigHead:
   'http://wx.qlogo.cn/mmhead/ver_1/g5PEicSFXLymnL3XHhGrfp7YVDDxzMG******neEibSuiauCAB3olvickCsvyia7liaCqkIt6zC2Zp1f2znGkbTjesxhNlDJoKfYDs/0',
  nickName: '************',
  pyInitial: '************',
  quanPin: '************',
  smallHead:
   'http://wx.qlogo.cn/mmhead/ver_1/g5PEicSFXLymnL3XHhGrfp7YVDDxzMG******neEibSuiauCAB3olvickCsvyia7liaCqkIt6zC2Zp1f2znGkbTjesxhNlDJoKfYDs/132',
  userName:
   'v1_2e285477d1758f228ccc5be50ad9cd0676bb618980c13c1dee450234fb******f7891d85dc67e37c96@stranger' }
[2018-10-11T17:30:53.015] [INFO] app - v1_2e285477d1758f228ccc5be50ad9cd0676bb618980c13c1dee450234fb******f7891d85dc67e37c96@stranger
[2018-10-11T17:30:53.015] [INFO] app - v2_fbb1423a3247f365cc365333d4e2898d1fd317628a172c37e8c4d875a867a0550e1f******f7d@stranger
[2018-10-11T17:30:54.690] [INFO] app - true
[2018-10-11T17:30:54.691] [INFO] app - -----------------------------------
[2018-10-11T17:30:54.691] [INFO] app - { message: '', status: 0 }

开启好友验证日志

[2018-10-11T17:54:15.226] [INFO] app - 初始化成功! ret: { success: true, data: {} }
[2018-10-11T17:54:16.130] [INFO] app - 登陆二维码url: http://weixin.qq.com/x/AaFp************0We6t ,请扫码登陆:
[2018-10-11T17:54:16.194] [INFO] app - 请求登录成功! ret: { success: true, data: {}, msg: '请使用手机微信扫码登陆!' }
[2018-10-11T17:54:17.418] [INFO] app - 等待扫码... { status: 0, expiredTime: 239 }
[2018-10-11T17:54:18.907] [INFO] app - 等待扫码... { status: 0, expiredTime: 237 }
[2018-10-11T17:54:19.822] [INFO] app - 等待扫码... { status: 0, expiredTime: 236 }
[2018-10-11T17:54:20.987] [INFO] app - 等待扫码... { status: 0, expiredTime: 235 }
[2018-10-11T17:54:22.005] [INFO] app - 已扫码,请在手机端确认登陆... { status: 1,
  expiredTime: 240,
  headUrl:
   'http://wx.qlogo.cn/mmhead/xNdVQ5mzLVIgg7************qaOzd8KeCrH0Jg/0',
  nickName: '************' }
[2018-10-11T17:54:23.426] [INFO] app - 已扫码,请在手机端确认登陆... { status: 1,
  expiredTime: 238,
  headUrl:
   'http://wx.qlogo.cn/mmhead/xNdVQ5mzLVIgg7************qaOzd8KeCrH0Jg/0',
  nickName: '************' }
[2018-10-11T17:54:29.983] [INFO] app - 扫码成功!登陆成功! { password: '***hide***',
  status: 2,
  external: '1',
  email: '',
  message: 'Everything is ok',
  uin: ************,
  deviceType: 'iphone',
  expiredTime: 237,
  headUrl:
   'http://wx.qlogo.cn/mmhead/xNdVQ5mzLVIgg7************qaOzd8KeCrH0Jg/0',
  nickName: '******',
  userName: '************',
  subStatus: 0,
  phoneNumber: '************',
  longLinkServer: '',
  shortLinkServer: '' }
[2018-10-11T17:54:30.232] [INFO] app - ************ 登陆成功!
[2018-10-11T17:54:31.017] [INFO] app - { city: '',
  country: '',
  message: 'Everything is OK',
  provincia: '',
  sex: 0,
  signature: '************',
  status: 0,
  stranger:
   'v2_fbb1423a3247f365cc365333d4e******************5a867a0550e1f******f7d@stranger',
  bigHead:
   'http://wx.qlogo.cn/mmhead/ver_1/g5PEicSFXLymnL3XHhGrfp7YVDDxzMGxhsFWmAPm8XWXwJcJneEibSuiauCAB3olvickCsvyia7liaCqkIt6zC2Zp1f2znGkbTjesxhNlDJoKfYDs/0',
  nickName: '************',
  pyInitial: '************',
  quanPin: '************',
  smallHead:
   'http://wx.qlogo.cn/mmhead/ver_1/g5PEicSFXLymnL3XHhGrfp7YVDDxzMGxhsFWmA************liaCqkIt6zC2Zp1f2znGkbTjesxhNlDJoKfYDs/132',
  userName:
   'v1_2e285477d1758f228cc****************34fb******f7891d85dc67e37c96@stranger' }
[2018-10-11T17:54:31.018] [INFO] app - v1_2e285477d1758f228************3c1dee450234fb******f7891d85dc67e37c96@stranger
[2018-10-11T17:54:31.018] [INFO] app - v2_fbb1423a3****************d875a867a0550e1f******f7d@stranger
[2018-10-11T17:54:32.265] [INFO] app - true
[2018-10-11T17:54:32.265] [INFO] app - -----------------------------------
[2018-10-11T17:54:32.266] [INFO] app - { message: 'user need verify', status: -44 }
binsee commented 5 years ago

padchat.addContact(stranger, ticket, type, [content])

返回-44说明对方开启了好友验证,此时需要额外提供验证消息

await wx.addContact(stranger, ticket, 3,"验证消息内容")