Giter Club home page Giter Club logo

wechat-api's Issues

updateMatieral有错

exports.updateNewsMaterial = function (news, callback) {
this.preRequest(this._uploadNewsMaterial, arguments);
};

/*!

  • 新增永久图文素材的未封装版本
    */
    // 这里的地址有错/add_news?access_token应该是update_news吧
    exports._updateNewsMaterial = function (news, callback) {
    var url = this.prefix + 'material/add_news?access_token=' + this.token.accessToken;
    this.request(url, postJSON(news), wrapper(callback));
    };

获取设备状态api有误

lib/api_device.js

make(exports, 'getDeviceStatus', function (deviceId, callback) {
  // https://api.weixin.qq.com/device/get_stat?access_token=ACCESS_TOKEN&device_id=DEVICE_ID
  var url = 'https://api.weixin.qq.com/device/compel_unbind?access_token=' + this.token.accessToken + "&device_id=" + deviceId;
  this.request(url, {dataType: 'json'}, wrapper(callback));
});

请改正.

多个进程同时用access_token的问题

每次new API的时候,都要写回调吗?
我有多个页面,都有new API(,) 这样貌似很不方便

var api = new API('appid', 'secret', function (callback) {
  // 传入一个获取全局token的方法
  fs.readFile('access_token.txt', 'utf8', function (err, txt) {
    if (err) {return callback(err);}
    callback(null, JSON.parse(txt));
  });
}, function (token, callback) {
  // 请将token存储到全局,跨进程、跨机器级别的全局,比如写到数据库、redis等
  // 这样才能在cluster模式及多机情况下使用,以下为写入到文件的示例
  fs.writeFile('access_token.txt', JSON.stringify(token), callback);
});

token过期的处理

微信的token管理有时候和过期时间不一致,在收到40001错误的时候,应该重新获取token。修改api_common.js方式如下,此代码经过验证可行:

API.prototype.preRequest = function (method, args, retryed) {
var that = this;
var callback = args[args.length - 1];
// 调用用户传入的获取token的异步方法,获得token之后使用(并缓存它)。
that.getToken(function (err, token) {
if (err) {
return callback(err);
}

//修改建议,重发时清除token,重新获取            
if(retryed){
    token = null;
}


var accessToken;
// 有token并且token有效直接调用
if (token && (accessToken = AccessToken(token.accessToken, token.expireTime)).isValid()) {
  // 暂时保存token
  that.token = accessToken;
  if (!retryed) {
    var retryHandle = function (err, data, res) {
      // 40001 重试
      if (data && data.errcode && data.errcode === 40001) {
            return that.preRequest(method, args, true);
      }
      callback(err, data, res);
    };
    // 替换callback
    var newargs = Array.prototype.slice.call(args, 0, -1);
    newargs.push(retryHandle);
    method.apply(that, newargs);
  } else {
    method.apply(that, args);
  }
} else {
  // 使用appid/appsecret获取token
  that.getAccessToken(function (err, token) {
    // 如遇错误,通过回调函数传出
    if (err) {
      return callback(err);
    }
    // 暂时保存token
    that.token = token;
    method.apply(that, args);
  });
}

});
};

AccessToken,TicketToken错误回调

API文档里,错误回调返回return callback(err),如果更改为return callback(null,null),就可以在accessToken不存在的情况下,调用getAccessToken方法。
cvi _ ol5s3g rc4 b8z8

this.registerTicketHandle is not a function

用的是最新的1.22.0,代码也很简单,部署在了heroku上

const WechatAPI = require('wechat-api');
...
...
app.use('/wechat', WechatAPI(config, function (req, res, next) {
  res.send('test');
}));

相关的错误log如下:

: > [email protected] start /app
: > node ./bin/www
:
: /app/node_modules/wechat-api/lib/api_common.js:85
:        ^
:
:   this.registerTicketHandle();
:     at API (/app/node_modules/wechat-api/lib/api_common.js:85:8)
: TypeError: this.registerTicketHandle is not a function
:     at Object.<anonymous> (/app/app.js:17:20)
:     at Function.Module._load (module.js:311:12)
:     at Object.Module._extensions..js (module.js:432:10)
:     at Module._compile (module.js:425:26)
:     at Module.load (module.js:356:32)
:     at Object.<anonymous> (/app/bin/www:3:11)
:     at Module.require (module.js:366:17)
:     at require (module.js:385:17)
:     at Module._compile (module.js:425:26)

api_common.js: 85看上去好像也没啥问题,函数是在api_js.js#L46,看了下blame,@xuming314 很久之前commit的,所以估计也不是他那的问题,不知道这个问题究竟出在哪里。小白搞不定:dizzy_face::dizzy_face:
麻烦了,谢谢!:pray::pray::pray:

getMaterial return a buffer but a json

Q: I get a buffer result but a json when I use the getMaterial api.

check the file: lib/api_material.js
at the row 253, u just give a opts before request and do not postJSON the opts. this results in the weixin return a buffer result in callback.

u should postJSON opts or set dataType when post with urllib.

api_common.js 中偶尔会出现的一个错误

我这边的版本 (可能和github上的有差异) , 该文件第 161 行 有时候会报错.
错误的原因是, data 为空

API.prototype.getAccessToken = function (callback) {
  var that = this;
  var url = this.prefix + 'token?grant_type=client_credential&appid=' + this.appid + '&secret=' + this.appsecret;
  this.request(url, {dataType: 'json'}, wrapper(function (err, data) {
    if (err) {
      return callback(err);
    }
    // 过期时间,因网络延迟等,将实际过期时间提前10秒,以防止临界点

// *************************** 这里就是  161 行 *************************** //
    var expireTime = (new Date().getTime()) + (data.expires_in - 10) * 1000;
// ************************************************************************** //

    var token = AccessToken(data.access_token, expireTime);
    that.saveToken(token, function (err) {
      if (err) {
        return callback(err);
      }
      callback(err, token);
    });
  }));
  return this;
};

建议此处 data如果为空 当做错误处理.
或者是在外层的某个地方生成 err .

循环调用api.sendText()

当我循环调用这个api的时候 发现access_token 在不断的覆盖,很快2000个就用完了,为什么循环调用一个api会出现这个问题呢?

永久二维码请求无法发送字符串式的id

当前请求永久二维码接口为:api.createLimitQRCode(100, callback);
而腾讯文档中:
永久二维码请求说明

http请求方式: POST
URL: https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN
POST数据格式:json
POST数据例子:{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 123}}}
或者也可以使用以下POST数据创建字符串形式的二维码参数:
{"action_name": "QR_LIMIT_STR_SCENE", "action_info": {"scene": {"scene_str": "123"}}}

可以创建字符串形式的二维码参数。

上传永久MP3文件报错

1、MP3只有10k
2、临时素材的接口没有问题。

api.uploadMedia("/material/a.mp3", "voice", function(err, result) {

    console.log(result);
});

3、永久的报错

{ [WeChatAPIRequestError: socket hang up (req "error"), POST xxxxxXbM&type=voice -1
headers: {}]
code: 'ECONNRESET',
name: 'WeChatAPIRequestError',
data: undefined,
status: -1,
headers: {},
res:
{ status: -1,
statusCode: -1,
headers: {},
size: 0,
aborted: false,
rt: 1467 } }

sendTemplate 第一次成功,第二次失败。

第一次可以成功发送,第二次sendTemplate 的error 部分有值,打印了一下是accessToken, 不明白怎么用。。 我看定义,有 callbackcallback2, example里面没有讲 callback2 怎么用。

 var sendOrderStatus = function sendOrderStatus(wechatUnionId, orderSequence, orderDate, orderStatus, remark) {

var templateId = 'wrFqkJ4S5Neco8ARbFQHaE0ZLI4a9BoPfW7wAG8ayMI';
var url = "http://wash.saltyegg.cn";
var data = {
  title: {
    value: "下单成功",
    color: "#173177"
  },
  orderId: {
    value: orderSequence,
    color: "#173177"
  },
  orderDate: {
    value: orderDate,
    color: "#173177"
  },
  orderStatus: {
    value: orderStatus,
    color: "#173177"
  },
  remark: {
    value: remark,
    order: "#173177"
  }
};

app.wechatAPI.sendTemplate(wechatUnionId, templateId, url, data, function (err, result) {

  console.log('send template');

  if (err){
    console.error('error in sending template');
    console.error(err);
    console.log('what this is error');
  }
  else {
    console.log(result);
  }

});

};

registerTicketHandle这个方法不会自动去更新ticket

      api.registerTicketHandle(function (type, callback) {
         console.log(type);

        // 传入一个获取全局ticket的方法
        fs.readFile('./token/ticketToken.txt', 'utf8', function (err, txt) {
            console.log(txt);console.log('read');
            //console.log(err,txt);//return;
            if (err) {return callback(err);}
            callback(null, JSON.parse(txt));
        });
    }, function (type, _ticketToken, callback) {
        console.log(type,_ticketToken);console.log('write');

        fs.writeFile('./token/ticketToken.txt', JSON.stringify(_ticketToken), function(err){
            if(err) return callack(err);
            callback(null)
        });

    }
)

删除组请求出错

我的代码:

      console.log('Remove group '+ ctx.where.id);
      gWechatApi.removeGroup(ctx.where.id, function(err,result){
        if(err){
          console.log(err);
          console.log(result);
          return next(err);
        }
        next();
      });

结果:
image

多写了个逗号?

var WechatAPI = require('wechat-api');

var api = new WechatAPI(appid, appsecret, );
api.updateRemark('open_id', 'remarked', function (err, data, res) {
  // TODO
});

WechatAPI(appid, appsecret, ); 此处是否最后多写了一个 ',' 号

卡券调用问题,获得的cardExt,用于jssdk打开领取卡券的页面显示“签名错误”

如题
通过cardId获得的getCardExt,用于jssdk打开领取卡券的页面显示“签名错误”,

文档说

领取页面提示签名错误
核对签名时间戳是否和 card_ext 中的一致

但这个sign的timestamp是一样的


831804737

初始化jsconfig是正常的。

用获得的cardExt生成的cardList

wx.addCard({
      cardList: cardList,
      success: function (res) {
        alert('已添加卡券:' + JSON.stringify(res));
      }
    });

how to get started

Your examples don't seem to work to get started...

'use strict';

let debug = require('debug')('wechat-api');
let path = require('path');
let fs = require('fs');

let AppConfig = require('../../private/AppConfig');

var WechatAPI = require('wechat-api');

let tokenFilePath = path.join(__dirname, 'access_token.txt');

debug('init', tokenFilePath);

var api = new WechatAPI(AppConfig.APP_ID, AppConfig.APP_SECRET, function (callback) {
  // 传入一个获取全局token的方法
  fs.readFile(tokenFilePath, 'utf8', function (err, txt) {
    debug('read token ', tokenFilePath, txt);
    if (err) {return callback(err);}
    callback(null, JSON.parse(txt));
  });
}, function (token, callback) {
  // 请将token存储到全局,跨进程、跨机器级别的全局,比如写到数据库、redis等
  // 这样才能在cluster模式及多机情况下使用,以下为写入到文件的示例
  debug('write token to ', tokenFilePath, token);
  fs.writeFile(tokenFilePath, JSON.stringify(token), callback);
});

// var api = new WechatAPI(AppConfig.APP_ID, AppConfig.APP_SECRET);
api.updateRemark('open_id', 'remarked', function (err, data, res) {
  debug('updateRemark', data, res);
});

results:

wechat-api init +56ms /Users/dc/dev/rikai/boteditor/lib/wechat/access_token.txt
wechat-api read token +11ms /Users/dc/dev/rikai/boteditor/lib/wechat/access_token.txt undefined
wechat-api updateRemark +1ms undefined undefined

so no token is being created or read.

获得全局token的例子有点问题

var api = new API('appid', 'secret', function (callback) {
// 传入一个获取全局token的方法
fs.readFile('access_token.txt', 'utf8', function (err, txt) {
if (err) {return callback(err);}
callback(null, JSON.parse(txt));
});
}, function (token, callback) {
// 请将token存储到全局,跨进程、跨机器级别的全局,比如写到数据库、redis等
// 这样才能在cluster模式及多机情况下使用,以下为写入到文件的示例
fs.writeFile('access_token.txt', JSON.stringify(token), callback);
});

只要建个空白文件 access_token.txt 就可以了吗? 首先得把token写入进去吧,后面的writeFile 没看到被调用哦

看日志发现一个崩溃的情况

source/node_modules/wechat/node_modules/wechat-api/lib/util.js:12
    if (data.errcode) {
            ^
TypeError: Cannot read property 'errcode' of null
    at source/node_modules/wechat/node_modules/wechat-api/lib/util.js:12:13
    at done (source/node_modules/wechat/node_modules/wechat-api/node_modules/urllib/lib/urllib.js:346:5)
    at source/node_modules/wechat/node_modules/wechat-api/node_modules/urllib/lib/urllib.js:547:9
    at decodeContent (source/node_modules/wechat/node_modules/wechat-api/node_modules/urllib/lib/urllib.js:407:14)
    at IncomingMessage.<anonymous> (source/node_modules/wechat/node_modules/wechat-api/node_modules/urllib/lib/urllib.js:513:7)
    at IncomingMessage.emit (events.js:119:20)
    at _stream_readable.js:888:16
    at process._tickCallback (node.js:337:11)

对应的是util.js中第12行

exports.wrapper = function (callback) {
  return function (err, data, res) {
    callback = callback || function () {};
    if (err) {
      err.name = 'WeChatAPI' + err.name;
      return callback(err, data, res);
    }
    if (data.errcode) { //这一行,data为空进崩溃
      err = new Error(data.errmsg);
      err.name = 'WeChatAPIError';
      err.code = data.errcode;
      return callback(err, data, res);
    }
    callback(null, data, res);
  };
};

追查到urllib.js的547行调用,再之前是对data的处理,不知是否有极端情况没考虑到。

      decodeContent(res, body, function (err, data, encoding) {
        if (err) {
          return done(err, body, res);
        }
        // if body not decode, dont touch it
        if (!encoding && TEXT_DATA_TYPES.indexOf(args.dataType) >= 0) {
          // try to decode charset
          try {
            data = decodeBodyByCharset(data, res);
          } catch (_) {
            // if error, dont touch it
            return done(null, data, res);
          }

          if (args.dataType === 'json') {
            if (responseSize === 0) {
              data = null;
            } else {
              var r = parseJSON(data);
              if (r.error) {
                err = r.error;
              } else {
                data = r.data;
              }
            }
          }
        }

        if (responseAborted) {
          // err = new Error('Remote socket was terminated before `response.end()` was called');
          // err.name = 'RemoteSocketClosedError';
          debug('Request#%d %s: Remote socket was terminated before `response.end()` was called', reqId, url);
        }

        done(err, data, res); //547行,data为空
      });

生成带参数的二维码接口

我的需求是生成带参数的临时二维码。
研究了下官方的文档,好像只能通过sceneId去传整型参数。

场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)。

上面为官方文档的原文,临时二维码支持32位非0整型的场景值ID。

我这边用wechat-api的createTmpQRCode方法测试了下,在服务器后台可以通过req.weixin.EventKey拿到所传的场景值,格式类似为qrscene_1234。

但我发现如果场景值ID超过999999999九位数字后,到了后台会变成qrscene_0。
诚求各路大神指点。

文档不能访问

NOTICE: This domain name expired on 1/9/2016 and is pending renewal or deletion.

多进程获取access_token代码的问题

按照代码,调用getLatestToken获取不到token的。像示例一样把access_token写入文件的话,这个文件是要我手动初始化写入内容?

var api = new API('appid', 'secret', function (callback) {
  // 传入一个获取全局token的方法
  fs.readFile('access_token.txt', 'utf8', function (err, txt) {
    if (err) {return callback(err);}
    callback(null, JSON.parse(txt));
  });
}, function (token, callback) {
  // 请将token存储到全局,跨进程、跨机器级别的全局,比如写到数据库、redis等
  // 这样才能在cluster模式及多机情况下使用,以下为写入到文件的示例
  fs.writeFile('access_token.txt', JSON.stringify(token), callback);
});

为何没有用户分组删除接口呢?

如题

我看了下以为官方没有提供这个接口呢,是拉下了,还是有其他原因呢?
麻烦大神告下
只有下面这几个

  • getGroups
  • getWhichGroup
  • createGroup
  • updateGroup
  • moveUserToGroup

AccessToken框架会自动刷新吗?

微信文档说AccessToken 7200S过期,getLatestToken()获得的AccessToken一定是没有过期的吗?
调用getLatestToken()时会去微信服务器那里更新一次AccessToken还是返回缓存的?
希望在文档里说明一下

data为null,导制出错,重启二十多次。

/usr/local/software/node/nodeWechat/node_modules/wechat-api/lib/util.js:12
if (data.errcode) {
^
TypeError: Cannot read property 'errcode' of null
at /usr/local/software/node/nodeWechat/node_modules/wechat-api/lib/util.js:12:13
at done (/usr/local/software/node/nodeWechat/node_modules/wechat-api/node_modules/urllib/lib/urllib.js:346:5)
at /usr/local/software/node/nodeWechat/node_modules/wechat-api/node_modules/urllib/lib/urllib.js:547:9
at decodeContent (/usr/local/software/node/nodeWechat/node_modules/wechat-api/node_modules/urllib/lib/urllib.js:407:14)
at IncomingMessage. (/usr/local/software/node/nodeWechat/node_modules/wechat-api/node_modules/urllib/lib/urllib.js:513:7)
at IncomingMessage.emit (events.js:117:20)
at _stream_readable.js:943:16
at process._tickCallback (node.js:419:13)
error: Forever detected script exited with code: 8
error: Script restart attempt #24

new API 异步问题

因为项目的前后台分别在两个不同的node进程,下面是代码
1、 var api = new API(appid, appsecret, function(){....}, function(){....});
2、api.getFollowers(function(){....});

当实际执行时第二行代码总是在第一行还没获取到token就执行了,我想在 new API的回调函数中获取已经初始化完成的api,但是看了源码在调用getToken和saveToken后还要做对prefix等url赋值的操作,因此这时的api并没有初始化完成,我该如何解决这个问题?

设置按钮总是报 socket hang up

朴大大,我想锻炼一下自己的node水平,所以没有用您的库。问题是这样的,我先是用https.request ,发送GET请求,拿到access_token,然后再request的end()回调函数中再次发送request POST请求,设置按钮,但是总是报** socket hang up**,调试了老半天了,求朴大大 指教,感激不尽!!!

关于Access Token的存储(access_token.txt不存在)

README里面给的例子似乎不太对
如果在readFile时处理按照fs.readFile('access_token.txt', 'utf8', function (err, txt) { if (err) {return callback(err);} 这样处理错误的话,假如刚开始跑,没有access_token.txt文件就会一直报错,而不是去获取新Token

{"errno":34,"code":"ENOENT","path":"access_token.txt"}

我把它替换为if (err) {return callback(null,null);}之后就好了(参照默认callback的处理方式,这样会让他去请求一次access token),这样处理对么?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.