Jump to content
McKay Development

IdiNium

Member
  • Posts

    10
  • Joined

  • Last visited

Posts posted by IdiNium

  1. Hey @vrtgn!

    I think I've solve this. Since getAvatarUrl is not working properly (maybe due to my mistake or idk why), so I decided to get avatarHash instead, and it turned out to be working fine after about 20 times of accepted trades.

    avatarHash.PNG.f3e6b8b4d533e9f4c077a73f7215cf03.PNG

    Here's my coding:

    Myhandler.ts (only the part that I'm working on):
     

        private sendWebHookReviewOfferSummary(offer: TradeOfferManager.TradeOffer, reason: string): void {
            const request = new XMLHttpRequest();
            request.open('POST', process.env.DISCORD_WEBHOOK_REVIEW_OFFER_URL);
            request.setRequestHeader('Content-type', 'application/json');
    
            const partnerSteamID = offer.partner.toString();
            const tradeSummary = offer.summarize(this.bot.schema);
    
            let partnerAvatar;
            let partnerName;
            log.debug('getting partner Avatar and Name...');
            offer.getUserDetails(function(err, me, them) {
                if (err) {
                    log.debug('Error retrieving partner Avatar and Name: ', err);
                    partnerAvatar =
                        'https://p7.hiclipart.com/preview/313/980/1020/question-mark-icon-question-mark-png.jpg';
                    partnerName = 'unknown';
                } else {
                    log.debug('partner Avatar and Name retrieved. Applying...');
                    partnerAvatar = them.avatarFull;
                    log.debug(partnerAvatar);
                    partnerName = them.personaName;
                    log.debug(partnerName);
                }
                const stringified = JSON.stringify(discordReviewOfferSummary)
                    .replace(/%partnerId%/g, partnerSteamID)
                    .replace(/%partnerName%/g, partnerName)
                    .replace(/%partnerAvatar%/g, partnerAvatar)
                    .replace(/%offerId%/g, offer.id)
                    .replace(/%reason%/g, reason)
                    .replace(/%tradeSummary%/g, tradeSummary.replace('Offered:', '\\n Offered:'))
                    .replace(/%ownerDiscordId%/g, process.env.OWNER_DISCORD_ID)
                    .replace(/%currentTime%/g, moment().format('MMMM Do YYYY, HH:mm:ss') + ' UTC');
    
                const jsonObject = JSON.parse(stringified);
                request.send(JSON.stringify(jsonObject));
                log.debug('Review offer summary sent to webhook');
            });
        }
    
        private sendWebHookTradeSummary(offer: TradeOfferManager.TradeOffer): void {
            const request = new XMLHttpRequest();
            request.open('POST', process.env.DISCORD_WEBHOOK_TRADE_SUMMARY_URL);
            request.setRequestHeader('Content-type', 'application/json');
    
            const partnerSteamID = offer.partner.toString();
            const tradeSummary = offer.summarize(this.bot.schema);
    
            let tradesTotal = 0;
            const offerData = this.bot.manager.pollData.offerData;
            for (const offerID in offerData) {
                if (!Object.prototype.hasOwnProperty.call(offerData, offerID)) {
                    continue;
                }
    
                if (offerData[offerID].handledByUs === true && offerData[offerID].isAccepted === true) {
                    // Sucessful trades handled by the bot
                    tradesTotal++;
                }
            }
            const tradesMade = process.env.TRADES_MADE_STARTER_VALUE
                ? +process.env.TRADES_MADE_STARTER_VALUE + tradesTotal
                : 0 + tradesTotal;
    
            let personaName;
            let avatarFull;
            let avatarFullPrint;
            log.debug('getting partner Avatar and Name...');
            this.getPartnerDetails(offer, function(err, details) {
                if (err) {
                    log.debug('Error retrieving partner Avatar and Name: ', err);
                    personaName = 'unknown';
                    avatarFullPrint =
                        'https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/72/72f78b4c8cc1f62323f8a33f6d53e27db57c2252_full.jpg'; //default "?" image
                } else {
                    log.debug('partner Avatar and Name retrieved. Applying...');
                    personaName = details.personaName;
                    log.debug(personaName);
                    avatarFull = details.avatarFull ? details.avatarFull : '72f78b4c8cc1f62323f8a33f6d53e27db57c2252'; //if something wrong, it'll use the default "?"" image
                    log.debug(avatarFull);
                    avatarFullPrint =
                        'https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/' +
                        avatarFull.substring(0, 2) +
                        '/' +
                        avatarFull +
                        '_full.jpg';
                    log.debug(avatarFullPrint);
                }
                const stringified = JSON.stringify(discordTradeSummary)
                    .replace(/%partnerId%/g, partnerSteamID)
                    .replace(/%partnerName%/g, personaName)
                    .replace(/%partnerAvatar%/g, avatarFullPrint)
                    .replace(/%offerId%/g, offer.id)
                    .replace(/%tradeNum%/g, tradesMade.toString())
                    .replace(/%tradeSummary%/g, tradeSummary.replace('Offered:', '\\n Offered:'))
                    .replace(/%currentTime%/g, moment().format('MMMM Do YYYY, HH:mm:ss') + ' UTC');
    
                const jsonObject = JSON.parse(stringified);
    
                request.send(JSON.stringify(jsonObject));
                log.debug('Accepted trade summmary sent to webhook');
            });
        }
    
        private getPartnerDetails(offer: TradeOfferManager.TradeOffer, callback: (err: any, details: any) => void): any {
            // check state of the offer
            if (offer.state === TradeOfferManager.ETradeOfferState.active) {
                offer.getUserDetails(function(err, me, them) {
                    if (err) {
                        callback(err, {});
                    } else {
                        callback(null, them);
                    }
                });
            } else {
                this.bot.community.getSteamUser(offer.partner, (err, user) => {
                    if (err) {
                        callback(err, {});
                    } else {
                        callback(null, {
                            personaName: user.name,
                            avatarFull: user.avatarHash
                        });
                    }
                });
            }
        }

    And here's the steamcommunity module (index.d.ts):

            
    	getSteamUser(id: SteamID | string, callback: (err?: Error, user?: SteamCommunity.User) => void): void;
    
            acceptConfirmationForObject(identitySecret: string, objectID: string, callback: (err?: Error) => void): void;
        }
    
        namespace SteamCommunity {
            interface Group {
                steamID: SteamID;
                name: string;
                url: string;
                headline: string;
                summary: string;
                avatarHash: Buffer;
                members: number;
                membersInChat: number;
                membersInGame: number;
                membersOnline: number;
    
                join: (callback?: (err?: Error) => void) => void;
            }
            interface User {
                steamID: SteamID;
                name: string;
                onlineState: string;
                stateMessage: string;
                privacyState: string;
                visibilityState: string;
                avatarHash: string;
                vacBanned: string;
                tradeBanState: string;
                isLimitedAccount: string;
                customURL: string;
                groups: null;
                primaryGroup: null;
            }
        }
    
        export = SteamCommunity;
    }

    I think I'll stick on this solution for now.

    If you have any other alternative or maybe make it look nicer, I'd like to know it!

    Thank you very much :)

  2. 14 hours ago, vrtgn said:

    Oh damn, I never realised that there are two separate functions for review offer and trade summary function but now I come to think of it it makes sense why. 

    @vrtgn Sorry for the long late reply, yes there are two separate function that I am working on. The review offer is working just fine since the offer is still active, but not for when the trade is accepted.

    14 hours ago, vrtgn said:

    Do you have any idea how I can enable discord webhooks to my account to test this feature and give you a solid answer rather than just guessing?

    Sure, but I am not sure if here is the correct place to do this, but there you go.

    You can git clone the repo that I am working on, do navigate to where you want the tf2-automatic folder to be created first and run in terminal or cmd (I assume you have installed git and nodejs on your system):

    git clone https://github.com/idinium96/tf2-automatic.git && cd tf2-automatic && git checkout partner-avatar-and-name && npm install

    If you haven't yet install TypeScript, then install it globally:

    npm install typescript@latest -g

    and then compile the code (navigated to tf2-automatic folder):

    npm run build

    then you need to edit the template.env file and fill in the required variables.

    env.thumb.png.d83ae263b55fbef8424d83e30ce831ac.png

    Note that you need to use Steam Desktop Authenticator (SDA) to extract the shared_secret and identity_secret of your alt steam account. It can be found inside maFiles folder inside SDA main folder.

    For getting the webhook URL, first make sure you have created your own Discord server and create a channel. Click on the channel and click Edit Channel (⚙), and click on Webhooks. Click Create Webhook and copy the Webhook URL there and paste it the env. You can have separate webhook for accepted trade summary and for review offer (create another one and copy and paste the link). 

    For your discord ID, make sure you've enabled Developer mode in your Discord settings, then right click on yourself and click copy ID and paste it there. This is just to make the webhook ping (mentioned) you when there's an offer to be reviewed.

    After you've completed filled in the required variables, save the template.env as only .env (only the extension without any name).

    Then to run the bot, run node dist/app.js

    Then to test to see if the sendWebHookReviewOfferSummary and sendWebHookTradeSummary is working or not, first make sure you send some items to the bot (the bot will accept any trade from ADMINS) so that an exchange of item can be done. Then, since you're still not added any item to the bot's price list, then any offer that you send using another alt account (or with the help of your friend) to the bot will triggered an offer to be reviewed. This will be sent to the webhook you've set.

    Then, to see if sendWebHookTradeSummary (that is currently not working), copy the trade number or and offerId (in bracket) and send "!accepttrade <offerId>" to the bot via steam chat. Then if you see the log it will show the value for both avatarFull and personaName are undefined.

    14 hours ago, vrtgn said:

    Hey, just looked over your code and saw that in the getPartnerDetails function in getSteamUser callback you return the object with the property personName rather than personaName. In addition, in the sendSummary you assign partnerAvatar to details.personaName rather than details.avatarFull. 

    Oh ya, I have not realised that. Thank you for noticing it.

    14 hours ago, vrtgn said:

    You may also want to if else in the summary as you are assigning the values of partnerName and partnerAvatar but returning before you send them. 

    I am not sure by what you mean by this.
    Btw, thank you very much and feel free to ask if you got any problem running the bot. You may also read more about it here (but the original one does not include the Discord Webhook Integration): https://github.com/Nicklason/tf2-automatic

  3. Update:

    It seems that I've put the log.debug things at the wrong place, that's why it print out that it has sent to webhook first. I've update the coding and here's the whole coding for function sendWebHookReviewOfferSummary (which use the getUserDetails with no problem at all), sendWebHookTradeSummary (which you'll find out at the log that I'll show after the coding) and the getPartnerDetails (which is yours):

        private sendWebHookReviewOfferSummary(offer: TradeOfferManager.TradeOffer, reason: string): void {
            const request = new XMLHttpRequest();
            request.open('POST', process.env.DISCORD_WEBHOOK_REVIEW_OFFER_URL);
            request.setRequestHeader('Content-type', 'application/json');
    
            const partnerSteamID = offer.partner.toString();
            const tradeSummary = offer.summarize(this.bot.schema);
    
            let partnerAvatar;
            let partnerName;
            log.debug('getting partner Avatar and Name...');
            offer.getUserDetails(function(err, me, them) {
                if (err) {
                    log.debug('Error retrieving partner Avatar and Name: ', err);
                    partnerAvatar =
                        'https://p7.hiclipart.com/preview/313/980/1020/question-mark-icon-question-mark-png.jpg';
                    partnerName = 'unknown';
                    return;
                }
    
                log.debug('partner Avatar and Name retrieved. Applying...');
                partnerAvatar = them.avatarFull;
                log.debug(partnerAvatar);
                partnerName = them.personaName;
                log.debug(partnerName);
    
                const stringified = JSON.stringify(discordReviewOfferSummary)
                    .replace(/%partnerId%/g, partnerSteamID)
                    .replace(/%partnerName%/g, partnerName)
                    .replace(/%partnerAvatar%/g, partnerAvatar)
                    .replace(/%offerId%/g, offer.id)
                    .replace(/%reason%/g, reason)
                    .replace(/%tradeSummary%/g, tradeSummary.replace('Offered:', '\\n Offered:'))
                    .replace(/%ownerDiscordId%/g, process.env.OWNER_DISCORD_ID)
                    .replace(/%currentTime%/g, moment().format('MMMM Do YYYY, HH:mm:ss') + ' UTC');
    
                const jsonObject = JSON.parse(stringified);
                request.send(JSON.stringify(jsonObject));
                log.debug('Review offer summary sent to webhook');
            });
        }
    
        private sendWebHookTradeSummary(offer: TradeOfferManager.TradeOffer): void {
            const request = new XMLHttpRequest();
            request.open('POST', process.env.DISCORD_WEBHOOK_TRADE_SUMMARY_URL);
            request.setRequestHeader('Content-type', 'application/json');
    
            const partnerSteamID = offer.partner.toString();
            const tradeSummary = offer.summarize(this.bot.schema);
    
            let tradesTotal = 0;
            const offerData = this.bot.manager.pollData.offerData;
            for (const offerID in offerData) {
                if (!Object.prototype.hasOwnProperty.call(offerData, offerID)) {
                    continue;
                }
    
                if (offerData[offerID].handledByUs === true && offerData[offerID].isAccepted === true) {
                    // Sucessful trades handled by the bot
                    tradesTotal++;
                }
            }
            const tradesMade = process.env.TRADES_MADE_STARTER_VALUE
                ? +process.env.TRADES_MADE_STARTER_VALUE + tradesTotal
                : 0 + tradesTotal;
    
            let personaName;
            let avatarFull;
            log.debug('getting partner Avatar and Name...');
            this.getPartnerDetails(offer, function(err, details) {
                if (err) {
                    log.debug('Error retrieving partner Avatar and Name: ', err);
                    personaName = 'unknown';
                    avatarFull = 'https://p7.hiclipart.com/preview/313/980/1020/question-mark-icon-question-mark-png.jpg';
                    return;
                }
    
                log.debug('partner Avatar and Name retrieved. Applying...');
                personaName = details.personaName;
                log.debug(personaName);
                avatarFull = details.personaName;
                log.debug(avatarFull);
    
                const stringified = JSON.stringify(discordTradeSummary)
                    .replace(/%partnerId%/g, partnerSteamID)
                    .replace(/%partnerName%/g, personaName)
                    .replace(/%partnerAvatar%/g, avatarFull)
                    .replace(/%offerId%/g, offer.id)
                    .replace(/%tradeNum%/g, tradesMade.toString())
                    .replace(/%tradeSummary%/g, tradeSummary.replace('Offered:', '\\n Offered:'))
                    .replace(/%currentTime%/g, moment().format('MMMM Do YYYY, HH:mm:ss') + ' UTC');
    
                const jsonObject = JSON.parse(stringified);
    
                request.send(JSON.stringify(jsonObject));
                log.debug('Accepted trade summmary sent to webhook');
            });
        }
    
        private getPartnerDetails(offer: TradeOfferManager.TradeOffer, callback: (err: any, details: any) => void): any {
            // check state of the offer
            if (offer.state === TradeOfferManager.ETradeOfferState.active) {
                offer.getUserDetails(function(err, me, them) {
                    if (err) {
                        callback(err, {});
                    } else {
                        callback(null, them);
                    }
                });
            } else {
                this.bot.community.getSteamUser(offer.partner, (err, user) => {
                    if (err) {
                        callback(err, {});
                    } else {
                        callback(null, {
                            personName: user.name,
                            avatarFull: user.getAvatarURL('full')
                        });
                    }
                });
            }
        }

    And here's the log:

    //sendWebHookReviewOfferSummary part↓
    2020-04-18 11:04:34 debug: getting partner Avatar and Name...
    2020-04-18 11:04:34 debug: Processing next offer
    2020-04-18 11:04:34 debug: Already processing offer or queue is empty
    2020-04-18 11:04:35 debug: partner Avatar and Name retrieved. Applying...
    2020-04-18 11:04:35 debug: https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/02/02d8e088a531ac2603cde55c826cf06a1e335f9c_full.jpg (✔)
    2020-04-18 11:04:35 debug: IdiNium-Fumino (✔)
    2020-04-18 11:04:35 debug: Review offer summary sent to webhook
    //sendWebHookReviewOfferSummary part↑ - Received both avatar (in url) and name perfectly.
    
    2020-04-18 11:05:05 info: Message from IdiNium | Quicksell.store (76561198013127982): !accepttrade 4000953535
    2020-04-18 11:05:05 info: Message sent to IdiNium | Quicksell.store (76561198013127982): Accepting offer...
    2020-04-18 11:05:08 trade: Offer #4000953535 from 76561198077208792 successfully accepted; confirmation required
    2020-04-18 11:05:08 debug: Accepting mobile confirmation... {"offerId":"4000953535"}
    2020-04-18 11:05:08 debug: Offer #4000953535 from 76561198077208792 done doing action on offer
    2020-04-18 11:05:12 debug: Checking account info
    2020-04-18 11:05:13 verbose: Offer #4000953535 from 76561198077208792 state changed: Active -> Accepted (reason: MANUAL)
    2020-04-18 11:05:13 debug: Took unknown ms to process offer {"offerId":"4000953535","state":3,"finishTime":null}
    2020-04-18 11:05:15 info: Message sent to 76561198077208792: Success! The offer went through successfully. 
    
    Feel free to join our Discord server for support and full tips to setup tf2-automatic and tf2-autocord using VPS and other stuffs: https://discord.gg/AXTGF4g
    2020-04-18 11:05:15 trade: Offer #4000953535 from 76561198077208792 has been accepted.
    
    //sendWebHookTradeSummary part↓
    2020-04-18 11:05:15 debug: getting partner Avatar and Name...
    2020-04-18 11:05:15 debug: Enqueueing smelt job for 5002
    2020-04-18 11:05:15 debug: Can't handle job {"job":{"type":"smelt","defindex":5002}}  
    2020-04-18 11:05:15 debug: Ensuring TF2 GC connection...
    2020-04-18 11:05:15 debug: Not playing TF2
    2020-04-18 11:05:15 debug: Enqueueing smelt job for 5002
    2020-04-18 11:05:15 debug: Already handling queue
    2020-04-18 11:05:15 debug: Enqueueing sort job   
    2020-04-18 11:05:15 debug: Already handling queue
    2020-04-18 11:05:15 debug: partner Avatar and Name retrieved. Applying...
    2020-04-18 11:05:15 debug: undefined ()
    2020-04-18 11:05:15 debug: undefined ()
    2020-04-18 11:05:15 debug: Accepted trade summmary sent to webhook
    //sendWebHookTradeSummary part↑ - Does not received both avatar (in url) and name, does it actually failed to send to webhook.
    

    Both were returned undefined. Should that actually an error?

  4. Hello @vrtgn thanks again for your help.

    7 hours ago, vrtgn said:

    Instantiated in other words means created like you have done:

    I get it now, really don't know that before.

    
    	}
        	
    		getSteamUser(id: SteamID | string, callback: (err?: Error, user?: any) => void): void;
            
    	}
    
    	namespace SteamCommunity {
            interface Group {
                
            }
            interface User {
                name: string;
                getAvatarUrl: (size: string) => void;
            }
        }

    To be honest, I have the same idea before of adding this to the steamcommunity index.d.ts, but I don't really sure at that time that I had to cancel doing it, and also at that time, I don't know about the "getAvatarUrl: (size: string) => void; thing.

    When I do apply this to the code, it does not throw any error, also I've changed back from what I did (the sComm thing) to the (this.bot.community) and it also does not detect any error and the compilation is done perfectly.

    I also had try to run the bot, and I seems to no have crashed as before, but it does not wait until it get the personaName and avatarFull does make the bot send to discord the wrong format of JSON and discord rejected it.

    Here's the logging:

    log.png.70272f76d1dcdee11822f48c70466d99.png

    And this is the current coding for sendWebHookTradeSummary:

        private sendWebHookTradeSummary(offer: TradeOfferManager.TradeOffer): void {
            const request = new XMLHttpRequest();
            request.open('POST', process.env.DISCORD_WEBHOOK_TRADE_SUMMARY_URL);
            request.setRequestHeader('Content-type', 'application/json');
    
            const partnerSteamID = offer.partner.toString();
            const tradeSummary = offer.summarize(this.bot.schema);
    
            let tradesTotal = 0;
            const offerData = this.bot.manager.pollData.offerData;
            for (const offerID in offerData) {
                if (!Object.prototype.hasOwnProperty.call(offerData, offerID)) {
                    continue;
                }
    
                if (offerData[offerID].handledByUs === true && offerData[offerID].isAccepted === true) {
                    // Sucessful trades handled by the bot
                    tradesTotal++;
                }
            }
            const tradesMade = process.env.TRADES_MADE_STARTER_VALUE
                ? +process.env.TRADES_MADE_STARTER_VALUE + tradesTotal
                : 0 + tradesTotal;
    
            let personaName;
            let avatarFull;
            log.debug('getting partner Avatar and Name...');  // It does read here but then it does not wait until it get the personaName or avatarFull
            this.getPartnerDetails(offer, function(err, details) {
                if (err) {
                    log.debug('Error retrieving partner Avatar and Name: ', err);
                    personaName = 'unknown';
                    avatarFull = 'https://p7.hiclipart.com/preview/313/980/1020/question-mark-icon-question-mark-png.jpg';
                } else {
                    log.debug('partner Avatar and Name retrieved. Applying...');  // It read here after sent to webhook
                    personaName = details.personaName;
                    avatarFull = details.personaName;
                }
    
                const stringified = JSON.stringify(discordTradeSummary)
                    .replace(/%partnerId%/g, partnerSteamID)
                    .replace(/%partnerName%/g, personaName)
                    .replace(/%partnerAvatar%/g, avatarFull)
                    .replace(/%offerId%/g, offer.id)
                    .replace(/%tradeNum%/g, tradesMade.toString())
                    .replace(/%tradeSummary%/g, tradeSummary.replace('Offered:', '\\n Offered:'))
                    .replace(/%currentTime%/g, moment().format('MMMM Do YYYY, HH:mm:ss') + ' UTC');
    
                const jsonObject = JSON.parse(stringified);
    
                request.send(JSON.stringify(jsonObject)); // Got sent before getting avatarFull and personaName
            });
            log.debug('Accepted trade summmary sent to webhook');
        }

    Does the callback function is not working?

  5. I've now put the function in the body of MyHandler and set it to private and have added "this" to the getPartnerDetails inside the sendWebHookReviewOfferSummary and sendWebHookTradeSummary, but then TypeScript still detect some error when I add back "this.bot" to the community.getSteamUser function.

    thisbotcommunity.png.699b52dac2e3697bb404e7b006024ce3.png

    I think I get this error because as I mentioned before, the steamcommunity module is modified and declared at ./src/types/modules/steamcommunity that does not contained getSteamUser inside that, so, I then try to import CSteamUser from '../../node_modules/steamcommunity' which in my understanding, it will get the CSteamUser directly from node_modules instead of the module that have been made in ./src/types/modules/steamcommunity.

    Then I tried this and got no problem, so I compile it and try run the bot and make a trade and accept it:
    failed-accept-trade.PNG.cdadb33d1acc1bd657ef56c93504bbdf.PNG

    And the error as shown in the terminal. When I mouse over the sComm.community.getSteamUser(...) they all typed as any.

    Now I really not sure what to do.

  6. 2 hours ago, vrtgn said:

    Happy to help, but note that a function is assignable to a variable; you just can't return that value from the function. You will progress as you learn. 

    I'll be using callbacks below so here is a tutorial/explanation if you still don't entirely understand.

    Thank you for the link on the tutorial/explanation about it. It's a good video than the others that I've watched. It's a good speed for a beginner like me to catch up with it.

    Well, back to the coding, TypeScript detects some problem from the function that you've shared to me and this is what I came back nicer:

    function getPartnerDetails(offer: TradeOfferManager.TradeOffer, callback: (err: any, details: any) => void): any {  // I need to put arrow function there
        // check state of the offer
        if (offer.state === TradeOfferManager.ETradeOfferState.active) {
            offer.getUserDetails(function(err, me, them) {    // It seems you missed this part.
                if (err) {
                    callback(err, {});
                } else {
                    callback(null, them);
                }
            });
        } else {
            this.bot.community.getSteamUser(offer.partner, (err, user) => {
                if (err) {
                    callback(err, {});
                } else {
                    callback(null, {
                        personName: user.name,
                        avatarFull: user.getAvatarURL('full')
                    });
                }
            });
        }
    }

    However, I am not really sure where I should put this function into. Currently, I put these lines of code between the import modules and the main body of the MyHandler.ts file.

    codes.thumb.PNG.73f4e6b066fcb3b2af147ab7a4525ffc.PNG

    I've also tried do as you do for the sendWebhookTradeSummary, and it's all good there.

    However, there's an error at "this" on the function getPartnerDetails as shown below:

    this-error.png.f2dce68feca9605078a885a40c59db1a.png

    And I am not so sure how to solve this issue.

    I've tried as shown below and import SteamCommunity from 'steamcommunity':

    steamcommunity.PNG.18c08ad3b36f241b41b95a4910cbdf41.PNG

    Move hovering on the highlighted getSteamUser show it does not exist:

    steamcommunity2.PNG.b605a67da9d1ff426bf293382277f197.PNG

    Then I take a look into the ./src/types/modules/ and found a folder named steamcommunity, and when I open the index.d.ts file there, I can not found the getSteamUser function.

    Here is the content of the index.d.ts for steamcommunity module (this is the one that the developer made it himself right?):

    declare module 'steamcommunity' {
        import { EventEmitter } from 'events';
        import SteamID from 'steamid';
        import { CookieJar } from 'request';
    
        interface Events {
            sessionExpired: () => void;
            confKeyNeeded: (tag: string, callback: (err?: Error, time?: number, confKey?: string) => void) => void;
        }
    
        class SteamCommunity extends EventEmitter {
            constructor(options?: object);
    
            steamID: SteamID | null;
    
            _jar: CookieJar;
    
            loggedIn(callback: Function): void;
    
            getSessionID(): string;
    
            getWebAPIKey(domain: string, callback: (err?: Error, key?: string) => void);
    
            setCookies(cookies: string[]): void;
    
            editProfile(
                settings: {
                    name?: string;
                    realName?: string;
                    summary?: string;
                    country?: string;
                    state?: string;
                    city?: string;
                    customURL?: string;
                    featuredBadge?: number;
                    primaryGroup?: SteamID | string;
                },
                callback?: (err?: Error) => void
            ): void;
    
            profileSettings(
                settings: {
                    profile?: number;
                    comments?: number;
                    inventory?: number;
                    inventoryGifts?: boolean;
                    gameDetails?: number;
                    playTime?: boolean;
                    friendsList?: number;
                },
                callback?: (err?: Error) => void
            ): void;
    
            uploadAvatar(
                image: Buffer | string /* , format?: string */,
                callback?: (err?: Error, url?: string) => void
            ): void;
    
            inviteUserToGroup(userID: SteamID | string, groupID: SteamID | string, callback?: (err?: Error) => void): void;
    
            getSteamGroup(id: SteamID | string, callback: (err?: Error, group?: SteamCommunity.Group) => void): void;
    
            getTradeURL(callback: (err?: Error, url?: string, token?: string) => void): void;
    
            acceptConfirmationForObject(identitySecret: string, objectID: string, callback: (err?: Error) => void): void;
        }
    
        namespace SteamCommunity {
            interface Group {
                steamID: SteamID;
                name: string;
                url: string;
                headline: string;
                summary: string;
                avatarHash: Buffer;
                members: number;
                membersInChat: number;
                membersInGame: number;
                membersOnline: number;
    
                join: (callback?: (err?: Error) => void) => void;
            }
        }
    
        export = SteamCommunity;
    }

    So I got confused on how to go for another steps.

    Btw I've pushed these changes to my git repo for tracking. (https://github.com/idinium96/tf2-automatic/tree/partner-avatar-and-name)

    Again, I am sorry for your time and effort and thank you so much.

  7. Hello @vrtgn,

    Thank you for your time and effort explaining to me how it should be working and etc! I really don't know that a variable is not assignable to a function. At first I thought the function will return as a value to the variable, but in reality it's not. I'll keep that in mind and learn more about this.

    About the code you've shared to me, it's working with some small replacement made and yes, it really is working!
    Here's the one that is working:

    private sendWebHookReviewOfferSummary(offer: TradeOfferManager.TradeOffer, reason: string): void {
            const request = new XMLHttpRequest();
            request.open('POST', process.env.DISCORD_WEBHOOK_REVIEW_OFFER_URL);
            request.setRequestHeader('Content-type', 'application/json');
    
            const partnerSteamID = offer.partner.toString();
            const tradeSummary = offer.summarize(this.bot.schema); // I replace this to here, because "this" will be undefined if placed as before
    
            let partnerAvatar; // I declare variables before the function
            let partnerName;
            log.debug('getting partner Avatar and Name...');
            offer.getUserDetails(function(err, me, them) {
                if (err) {
                    partnerAvatar =
                        'https://p7.hiclipart.com/preview/313/980/1020/question-mark-icon-question-mark-png.jpg'; // Giving it "?" image.
                    partnerName = 'unknown'; // Set it to unknown
                } else {
                    partnerAvatar = them.avatarFull;
                    partnerName = them.personaName;
                }
                const stringified = JSON.stringify(discordReviewOfferSummary)
                    .replace(/%partnerId%/g, partnerSteamID)
                    .replace(/%partnerName%/g, partnerName)
                    .replace(/%partnerAvatar%/g, partnerAvatar)
                    .replace(/%offerId%/g, offer.id)
                    .replace(/%reason%/g, reason)
                    .replace(/%tradeSummary%/g, tradeSummary.replace('Offered:', '\\n Offered:'))
                    .replace(/%ownerDiscordId%/g, process.env.OWNER_DISCORD_ID)
                    .replace(/%currentTime%/g, moment().format('MMMM Do YYYY, HH:mm:ss') + ' UTC');
    
                const jsonObject = JSON.parse(stringified);
                request.send(JSON.stringify(jsonObject));
            });
            log.debug('Review offer summary sent to webhook');
        }

    discord-test.PNG.e2138b5a552617e258ccf49b7c7fbc79.PNG

     

    But, then, when I try to accept the trade, and this function should be called when it accept the trade:

    private sendWebHookTradeSummary(offer: TradeOfferManager.TradeOffer): void {
            const request = new XMLHttpRequest();
            request.open('POST', process.env.DISCORD_WEBHOOK_TRADE_SUMMARY_URL);
            request.setRequestHeader('Content-type', 'application/json');
    
            const partnerSteamID = offer.partner.toString();
            const tradeSummary = offer.summarize(this.bot.schema);
    
            let tradesTotal = 0;
            const offerData = this.bot.manager.pollData.offerData;
            for (const offerID in offerData) {
                if (!Object.prototype.hasOwnProperty.call(offerData, offerID)) {
                    continue;
                }
    
                if (offerData[offerID].handledByUs === true && offerData[offerID].isAccepted === true) {
                    // Sucessful trades handled by the bot
                    tradesTotal++;
                }
            }
            const tradesMade = process.env.TRADES_MADE_STARTER_VALUE
                ? +process.env.TRADES_MADE_STARTER_VALUE + tradesTotal
                : 0 + tradesTotal;
    
            let partnerAvatar;
            let partnerName;
            log.debug('getting partner Avatar and Name...');
            offer.getUserDetails(function(err, me, them) {
                if (err) {
                    log.debug('Error retrieving partner Avatar and Name: ', err);
                    partnerAvatar =
                        'https://p7.hiclipart.com/preview/313/980/1020/question-mark-icon-question-mark-png.jpg';
                    partnerName = 'unknown';
                } else {
                    log.debug('partner Avatar and Name retrieved. Applying...');
                    partnerAvatar = them.avatarFull;
                    partnerName = them.personaName;
                }
    
                const stringified = JSON.stringify(discordTradeSummary)
                    .replace(/%partnerId%/g, partnerSteamID)
                    .replace(/%partnerName%/g, partnerName)
                    .replace(/%partnerAvatar%/g, partnerAvatar)
                    .replace(/%offerId%/g, offer.id)
                    .replace(/%tradeNum%/g, tradesMade.toString())
                    .replace(/%tradeSummary%/g, tradeSummary.replace('Offered:', '\\n Offered:'))
                    .replace(/%currentTime%/g, moment().format('MMMM Do YYYY, HH:mm:ss') + ' UTC');
    
                const jsonObject = JSON.parse(stringified);
    
                request.send(JSON.stringify(jsonObject));
            });
            log.debug('Accepted trade summmary sent to webhook');
        }

    Which I believe it shouldn't have any problem, because it's almost identical to the sendWebhookReviewOfferSummary, but on the Discord I've always received this:
    discord-test-accept.PNG.dbff10e9919fd063e9f3f24a8f35dc96.PNG

    And when I check on the log, this is the error that it thrown:
    discord-test-accept-log.PNG.b6d038ddcf2491162bb8246b19edf1bf.PNG

    Is that mean I have to use another function to get partnerAvatar and partnerName from the trade that has been already been accepted?

    Again, thank you and I really appreciate your help!

  8. Hello,
    I am new to the coding world, and I have problem that confuses me on the utilizing of getUserDetails function. I've read about this here - getUserDetails but I am not sure how to make it happen actually.
    Here's my attempt on doing it on tf2-automatic trading bot, which I've successfully added the Discord Webhook Integration feature, but the only missing things is that the trade partner Avatar and Name. The webhook function has two, which it sends a successful trade summary and an offer that need to be reviewed. The picture attached is only for function that sends to discord for reviewing offer.

    I also tried creating a function to be called, but not shown in the picture (but in the file).

    Language used: TypeScript.

    If you don't mind trying to edit it for me, you can git clone my forked repo that I'm currently been working on this: 

    git clone https://github.com/idinium96/tf2-automatic.git && git checkout partner-avatar-and-name && npm install

    and open the file MyHandler.ts in tf2automatic/src/classes/Myhandler.ts

    Thank you and I appreciate your help regarding this matters.

    sendWebhookReviewOffer.PNG

    sendWebhookReviewOffer-errors.PNG

    I've edit the git repo to the branch that related to this topic.

×
×
  • Create New...