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.
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