Meteor.wrapAsync和NPM包(Steam)

时间:2018-01-30 09:14:24

标签: javascript node.js meteor

我正在尝试为我的Meteor应用程序构建一个简单的STEAM机器人,但我遇到了障碍,因为我无法弄清楚如何正确使用Meteor.wrapAsync以便在前面正确显示结果。

我的代码如下所示:

1。服务器

import SteamUser from 'steam-user';
import SteamTotp from 'steam-totp';
import SteamCommunity from 'steamcommunity';
import TradeOfferManager from 'steam-tradeoffer-manager';

tradeBot1 = Meteor.settings.SteamTradeBot1;

// Vars
const client = new SteamUser();

const community = new SteamCommunity();

const manager = new TradeOfferManager({
    steam: client,
    community: community,
    language: 'en'
});

const logOnOptionsBot1 = {
    accountName: tradeBot1.username,
    password: tradeBot1.password,
    twoFactorCode: SteamTotp.generateAuthCode(tradeBot1.sharedSecret)
};

// Bot login
client.logOn(logOnOptionsBot1);

// After login set bot as online
client.on('loggedOn', Meteor.bindEnvironment(function(){
    console.log('Steam Trade Bot #1 online.');
    client.setPersona(SteamUser.Steam.EPersonaState.Online);
}));

// Set cookies
client.on('webSession', Meteor.bindEnvironment(function(sessionid, cookies){
    manager.setCookies(cookies);
    community.setCookies(cookies);
}));


Meteor.methods({
    "sendTradeOffer": function(tradeUrl, winId, uid){
        try {
            var assetId = "1111111111";
            var appid = "730";
            var itemName = "itemnamexxxxxxx";

            // Create new offer
            // https://github.com/DoctorMcKay/node-steam-tradeoffer-manager/wiki/TradeOfferManager
            const offer = manager.createOffer(tradeUrl);

            // Add item to offer
            offer.addMyItem({
                'assetid': assetId,
                'appid': appid,
                'contextid': 2,
                'amount': 1
            });

            // Set custom message
            offer.setMessage(`Congrats! You got "${itemName}"! Ref: "` + winId + `"`);

            // Send offer
            offer.send(Meteor.bindEnvironment(function(err, status){
                if (err) {
                    console.log(err);
                    return err;
                } else {
                    console.log(`Sent offer. Status: ${status}. Waiting for auto confirmation ...`);

                    // Set a 5 second delay before confirmation
                    Meteor.setTimeout(function(){
                        community.acceptConfirmationForObject(tradeBot1.indentitySecret, offer.id, Meteor.bindEnvironment(function(err){

                            if (err) {
                                console.log(err);
                                return err;
                            } else {
                                console.log("Offer confirmed.");
                                console.log("Sent Steam item with ID: " + assetId);

                                // Update data in mongo
                                // .....

                                // Return something to the front ???
                                var outcome = {
                                    message: "Trade offer sent!"
                                }

                                return outcome;

                            }

                        }));
                    }, 5000);
                }

            }));

        } catch(error){
            console.log(error);
            return error;
        }
    }

});

2。 FRONT

'submit form#send-trade': function(event, t){
    event.preventDefault();

    var tradeUrl = $("#user-trade-url").val();
    var winId = "winidxxxxxxx";
    var uid = "uidxxxxxxx";

    Meteor.call("sendTradeOffer", tradeUrl, winId, uid, function(error, result){
        if (error){
            console.log(error);
        } else {
            console.log(result);

        }
    });
 }

这应该做的是:

  • Bot login - working
  • 登录后将机器人状态设置为在线 - 正常工作
  • 用户在前台工作
  • 输入他们的tradeUrl
  • Meteor方法sendTradeOffer已执行 - 正在运行
  • 优惠已发送并确认 - 正在运作
  • 返回错误或结果在前面 - 不工作

服务器上的Console.logs工作得很好,但我无法返回任何内容,它总是未定义。

过去几天我搜索了很多,根据我的理解,我应该使用Meteor.wrapAsync来正确返回错误或结果,但我根本无法绕过它。 Meteor.wrapAsync如何适用于我的情况?

非常感谢任何帮助。

非常感谢!

1 个答案:

答案 0 :(得分:0)

此答案的信用额来自官方Meteor论坛的@robfallows

Meteor.methods({
  sendTradeOffer(tradeUrl, winId, uid) {
    // Create new offer
    const offer = manager.createOffer(tradeUrl);
    // Meter.wrapAsync
    const offerSend = Meteor.wrapAsync(offer.send, offer);
    const communityAcceptConfirmationForObject = Meteor.wrapAsync(community.acceptConfirmationForObject, community);
    try {
      const assetId = '1111111111';
      const appid = '730';
      const itemName = 'itemnamexxxxxxx';

      // Add item to offer
      offer.addMyItem({
        'assetid': assetId,
        'appid': appid,
        'contextid': 2,
        'amount': 1
      });

      // Set custom message
      offer.setMessage(`Congrats! You got ${itemName}! Ref: ${winId}`);

      // Send offer
      const status = offerSend(); // will throw error on failure
      console.log(`Sent offer. Status: ${status}. Waiting for auto confirmation ...`);

      // Set a 5 second delay before confirmation
      Meteor._sleepForMs(5000); // Fiber based inline sleep
      communityAcceptConfirmationForObject(tradeBot1.indentitySecret, offer.id);  // will throw error on failure

      console.log('Offer confirmed.');
      console.log('Sent Steam item with ID: ', assetId);

      // Update data in mongo
      // .....

      // Return something to the front ???
      const outcome = {
        message: 'Trade offer sent!'
      }

      return outcome;

    } catch (err) {
      throw new Meteor.Error('oops', err.message); // return error to client
    }
  },
});

根据他的说明:

  • 删除所有回调以使用Fibers。这意味着代码可以工作 顺序地,返回对象恰好在它的位置 似乎。
  • Meteor.wrapAsync用于似乎的两个调用 需要它。
  • 收拾ES6(ESLint是个苛刻的情妇!)