Skip to content

Instantly share code, notes, and snippets.

@joekiller
Last active November 19, 2023 23:07
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joekiller/9045906cd4419fab5f50e1f8775b050b to your computer and use it in GitHub Desktop.
Save joekiller/9045906cd4419fab5f50e1f8775b050b to your computer and use it in GitHub Desktop.
example backpack.tf notification

Below are two notifications from the Backpack.tf websocket. One is a normal listing and the other is a Marketplace.tf listing.

Also attached is the logic for detecting a "postlife" spell. A postlife spell is an items that was only avaliable after spells were removed from the game however thought gitches it still got a spell.

// using my utility https://github.com/joekiller/socket-to-interface I've managed to come up with the following interface for BP socket messages:
interface RootObject {
BPSocketEvent: BPSocketEvent[];
}
interface BPSocketEvent {
id: string;
event: string;
payload: Payload;
}
interface Payload {
id: string;
steamid: string;
appid: number;
currencies: Currencies;
value: Value;
tradeOffersPreferred?: boolean;
buyoutOnly?: boolean;
details?: string;
listedAt: number;
bumpedAt: number;
intent: string;
count: number;
status: string;
item: Item2;
user: User;
source?: string;
userAgent?: UserAgent;
deal?: Deal;
promoted?: boolean;
}
interface Deal {
percent: number;
value: number;
}
interface UserAgent {
client: string;
lastPulse: number;
}
interface User {
id: string;
name: string;
avatar: string;
avatarFull: string;
premium: boolean;
online: boolean;
banned: boolean;
customNameStyle: string;
acceptedSuggestions: number;
class: string;
style: string;
role?: Role;
tradeOfferUrl?: string;
isMarketplaceSeller: boolean;
flagImpersonated?: boolean;
bans: any[] | Bans2 | Bans3;
}
interface Bans3 {
'11': number;
}
interface Bans2 {
'4': number;
}
interface Role {
id: string;
name: string;
description: string;
nameColor: string;
}
interface Item2 {
appid: number;
baseName?: string;
defindex?: number;
id: string;
imageUrl: string;
marketName: string;
name: string;
origin?: Origin;
originalId: string;
price: Price | any[] | Price3 | Price4 | Price5;
quality?: Quality;
summary: string;
texture?: Texture;
class?: string[];
wearTier?: WearTier;
slot?: string;
particle?: Particle;
tradable: boolean;
craftable?: boolean;
priceindex?: string;
level?: number | string;
craftedBy?: CraftedBy;
tag?: Tag;
killstreakTier?: number;
killEaters?: KillEater2[];
australium?: boolean;
giftedBy?: CraftedBy;
recipe?: Recipe2;
sheen?: Origin;
paint?: Paint;
paintSecondaryHex?: string;
style?: Style3;
customName?: string;
crateSeries?: number;
customDesc?: string;
equipped?: Equipped[];
killstreaker?: Origin;
tradableAfter?: number;
elevatedQuality?: Quality;
festivized?: boolean;
craftNumber?: number;
strangeParts?: StrangePart[];
rarity?: Quality;
spells?: Spell[];
marketplaceTfListing?: MarketplaceTfListing;
dupe?: boolean;
decal?: Decal;
quantity?: number;
attributes?: Attribute2[];
medalNumber?: number;
containedItem?: ContainedItem;
}
interface ContainedItem {
appid: number;
baseName: string;
defindex: number;
id: string;
imageUrl: string;
marketName: string;
name: string;
origin: Origin;
originalId: string;
price: any[] | Price3;
quality: Quality;
summary: string;
level: number;
tradable?: boolean;
craftable: boolean;
class?: string[];
slot?: string;
}
interface Attribute2 {
field: string;
value: number | string;
}
interface Decal {
url: string;
}
interface MarketplaceTfListing {
value: number;
raw: number;
short: string;
currency: string;
}
interface Spell {
id: string;
spellId: string;
name: string;
type: string;
defindex?: number;
color?: string;
}
interface StrangePart {
score: number;
killEater: KillEater3;
}
interface KillEater3 {
id: number;
name: string;
item: Item;
}
interface Item {
appid: number;
baseName: string;
defindex: number;
id: string;
imageUrl: string;
marketName: string;
name: string;
origin?: any;
originalId: string;
price: Price3;
quality: Quality;
summary: string;
tradable: boolean;
craftable: boolean;
}
interface Equipped {
class: number;
slot: number;
}
interface Style3 {
name: string;
additional_hidden_bodygroups?: Additionalhiddenbodygroups2;
}
interface Additionalhiddenbodygroups2 {
headphones?: number;
hat?: number;
head?: number;
grenades?: number;
}
interface Paint {
id?: number;
name: string;
color: string;
}
interface Recipe2 {
estimatedCraftingCost: Value | any[];
inputItems: InputItem[];
outputItem?: OutputItem;
targetItem?: TargetItem2;
}
interface TargetItem2 {
itemName: string;
imageUrl: string;
_source: Source2;
}
interface Source2 {
_id: string;
name: string;
defindex: number;
item_class: string;
item_type_name: string;
item_name: string;
proper_name: boolean;
item_slot: string;
item_quality: number;
image_inventory: string;
min_ilevel: number;
max_ilevel: number;
image_url: string;
image_url_large: string;
item_set?: string;
craft_class?: string;
craft_material_type?: string;
capabilities: Capabilities2;
used_by_classes?: string[];
attributes?: Attribute[];
first_sale_date?: number;
release_date?: number;
appid: number;
_keywords: string[];
styles?: Style2[];
per_class_loadout_slots?: Perclassloadoutslots;
item_description?: string;
drop_type?: string;
}
interface Style2 {
name: string;
additional_hidden_bodygroups?: Additionalhiddenbodygroups;
}
interface Additionalhiddenbodygroups {
hat: number;
headphones?: number;
}
interface Capabilities2 {
nameable: boolean;
can_gift_wrap: boolean;
can_craft_mark: boolean;
can_be_restored: boolean;
strange_parts: boolean;
can_card_upgrade: boolean;
can_strangify: boolean;
can_killstreakify: boolean;
can_consume: boolean;
can_craft_count?: boolean;
can_craft_if_purchased?: boolean;
can_unusualify?: boolean;
can_customize_texture?: boolean;
paintable?: boolean;
can_collect?: boolean;
}
interface OutputItem {
appid: number;
baseName: string;
defindex: number;
id: string;
imageUrl: string;
marketName: string;
name: string;
origin?: any;
originalId: string;
price: Price2;
quality: Quality;
summary: string;
tradable: boolean;
craftable: boolean;
recipe?: Recipe;
priceindex?: string;
sheen?: Origin;
killstreaker?: Origin;
class?: string[];
slot?: string;
}
interface Recipe {
estimatedCraftingCost: any[];
inputItems: any[];
outputItem?: any;
targetItem: TargetItem;
}
interface TargetItem {
itemName: string;
imageUrl: string;
_source: Source;
}
interface Source {
_id: string;
name: string;
defindex: number;
item_class: string;
item_type_name: string;
item_name: string;
proper_name: boolean;
item_slot: string;
item_quality: number;
image_inventory: string;
min_ilevel: number;
max_ilevel: number;
image_url: string;
image_url_large: string;
item_set?: string;
craft_class?: string;
craft_material_type?: string;
capabilities: Capabilities;
styles?: Style[];
used_by_classes: string[];
attributes?: Attribute[];
first_sale_date?: number;
release_date: number;
appid: number;
_keywords: string[];
item_description?: string;
drop_type?: string;
per_class_loadout_slots?: Perclassloadoutslots;
}
interface Perclassloadoutslots {
Soldier: string;
Heavy: string;
Pyro: string;
Engineer: string;
}
interface Attribute {
name: string;
class: string;
value: number;
}
interface Style {
name: string;
}
interface Capabilities {
nameable: boolean;
can_gift_wrap: boolean;
can_craft_count?: boolean;
can_craft_mark: boolean;
can_be_restored: boolean;
strange_parts: boolean;
can_card_upgrade: boolean;
can_strangify: boolean;
can_killstreakify: boolean;
can_consume: boolean;
can_customize_texture?: boolean;
paintable?: boolean;
can_craft_if_purchased?: boolean;
can_collect?: boolean;
}
interface Price2 {
steam: Steam;
suggested: Suggested;
community?: Community;
}
interface InputItem {
quantity: number;
name: string;
}
interface KillEater2 {
score: number;
killEater: KillEater;
}
interface KillEater {
id?: number;
name: string;
}
interface Tag {
id: string;
steamId: string;
itemId: number;
color: string;
text: string;
}
interface CraftedBy {
personaname: string;
steamid: string;
}
interface Particle {
id: number;
name: string;
shortName: string;
imageUrl: string;
type: string;
}
interface WearTier {
id: number;
name: string;
short: string;
}
interface Texture {
id: number;
itemDefindex: number;
rarity: Quality;
name: string;
}
interface Quality {
id: number;
name: string;
color: string;
}
interface Price5 {
community: Community;
suggested: Suggested;
}
interface Price4 {
steam: Steam;
suggested: Suggested;
}
interface Price3 {
steam: Steam;
community: Community;
suggested: Suggested;
}
interface Suggested {
raw: number;
short: string;
long: string;
usd: number;
}
interface Community {
value: number;
valueHigh: number;
currency: string;
raw: number;
short: string;
long: string;
usd: number;
updatedAt: number;
difference: number;
}
interface Price {
steam: Steam;
}
interface Steam {
currency: string;
short: string;
long: string;
raw: number;
value: number;
}
interface Origin {
id: number;
name: string;
}
interface Value {
raw: number;
short: string;
long: string;
}
interface Currencies {
keys?: number;
metal?: number;
usd?: number;
}
{
"id": "440_11488812491",
"steamid": "76561199111073161",
"appid": 440,
"currencies": {
"metal": 33,
"keys": 14
},
"value": {
"raw": 981.01,
"short": "14.49 keys",
"long": "14 keys, 33 ref"
},
"tradeOffersPreferred": true,
"buyoutOnly": true,
"details": "⛔ This item is for sale on Quicksell.store ⛔ Send me a trade, visit https://quicksell.store/buy/11488812491 or add me and type !buy Professional Killstreak Festive Huntsman 👍 We're selling more than 9",
"listedAt": 1650721622,
"bumpedAt": 1650721622,
"intent": "sell",
"count": 1,
"status": "active",
"source": "steam",
"item": {
"appid": 440,
"baseName": "Festive Huntsman",
"defindex": 1005,
"id": "11488812491",
"imageUrl": "https://steamcdn-a.akamaihd.net/apps/440/icons/c_bow_xmas.7365eae1f56ceb4f6b14f1fb81bc9495a5e30dca.png",
"marketName": "Professional Killstreak Festive Huntsman",
"name": "Professional Killstreak Festive Huntsman",
"origin": {
"id": 8,
"name": "Found in Crate"
},
"originalId": "1331977225",
"price": {
"steam": {
"currency": "usd",
"short": "$15.36",
"long": "614.40 ref, 9.07 keys",
"raw": 468.5145945945946,
"value": 1536
},
"suggested": {
"raw": 468.5145945945946,
"short": "6.92 keys",
"long": "468.51 ref, 6.92 keys, $11.71",
"usd": 11.712864864864866
}
},
"quality": {
"id": 6,
"name": "Unique",
"color": "#FFD700"
},
"summary": "Level 10 Bow",
"level": 10,
"killstreakTier": 3,
"class": ["Sniper"],
"spells": [{
"id": "weapon-SPELL: Halloween death ghosts",
"spellId": "SPELL: Halloween death ghosts",
"name": "Exorcism",
"type": "weapon"
}],
"slot": "primary",
"tradable": true,
"craftable": true,
"customDesc": "Ayo the pizza here",
"customName": "Yoinky Sploinky",
"sheen": {
"id": 2,
"name": "Deadly Daffodil"
},
"killstreaker": {
"id": 2006,
"name": "Singularity"
},
"tag": null
},
"userAgent": {
"client": "-",
"lastPulse": 1650721500
},
"user": {
"id": "76561199111073161",
"name": "Harry",
"avatar": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/d8/d8ebede431682097c76492df1c2209b552c8f61b_medium.jpg",
"avatarFull": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/d8/d8ebede431682097c76492df1c2209b552c8f61b_full.jpg",
"premium": true,
"online": true,
"banned": false,
"customNameStyle": "awesome3",
"acceptedSuggestions": 0,
"class": "awesome3",
"style": "",
"role": null,
"tradeOfferUrl": "https://steamcommunity.com/tradeoffer/new/?partner=1150807433&token=LrC_zX4E",
"isMarketplaceSeller": false,
"flagImpersonated": null,
"bans": []
}
}
{
"id": "440_11927604786",
"steamid": "76561198289040457",
"appid": 440,
"currencies": {
"usd": 349.99
},
"value": {
"raw": 12726.909090909092,
"short": "$349.99",
"long": ""
},
"details": "For price in keys divide $ price by 1.83. Always interested in item offers. Feel free to add me on steam to discuss. Also buying TF2 backpacks (>400$).",
"listedAt": 1659348250,
"bumpedAt": 1659348250,
"intent": "sell",
"count": 1,
"status": "active",
"source": "marketplaceTf",
"item": {
"appid": 440,
"baseName": "Gunslinger",
"defindex": 142,
"id": "11927604786",
"imageUrl": "https://steamcdn-a.akamaihd.net/apps/440/icons/gunslinger.f6030adf78acc107d937c74904d7358a84648355.png",
"marketName": "Strange Professional Killstreak Gunslinger",
"name": "Strange Professional Killstreak Gunslinger",
"origin": {
"id": 0,
"name": "Timed Drop"
},
"originalId": "595994794",
"price": {
"steam": {
"currency": "usd",
"short": "$227.95",
"long": "8,289.09 ref, 141.18 keys",
"raw": 5844.57827510917,
"value": 22795
},
"suggested": {
"raw": 5844.57827510917,
"short": "99.54 keys",
"long": "5,844.58 ref, 99.54 keys, $160.73",
"usd": 160.72590256550217
}
},
"quality": {
"id": 11,
"name": "Strange",
"color": "#CF6A32"
},
"summary": "Level 15 Robot Arm",
"level": 15,
"killstreakTier": 3,
"class": ["Engineer"],
"spells": [{
"id": "weapon-SPELL: Halloween death ghosts",
"spellId": "SPELL: Halloween death ghosts",
"name": "Exorcism",
"type": "weapon"
}],
"slot": "melee",
"killEaters": [{
"score": 0,
"killEater": {
"id": 3,
"name": "Sentry Kills"
}
}, {
"score": 0,
"killEater": {
"name": "Kills"
}
}],
"tradable": true,
"craftable": true,
"sheen": {
"id": 1,
"name": "Team Shine"
},
"killstreaker": {
"id": 2004,
"name": "Tornado"
},
"marketplaceTfListing": {
"value": 349.99,
"raw": 12726.909090909092,
"short": "216.76 keys",
"currency": "usd"
},
"tag": null
},
"user": {
"id": "76561198289040457",
"name": "Quantex buying Backpacks",
"avatar": "https://avatars.akamai.steamstatic.com/41adfbbe5c60956738edfb022d17d615d972751e_medium.jpg",
"avatarFull": "https://avatars.akamai.steamstatic.com/41adfbbe5c60956738edfb022d17d615d972751e_full.jpg",
"premium": true,
"online": true,
"banned": false,
"customNameStyle": "premium",
"acceptedSuggestions": 10,
"class": "premium",
"style": "",
"role": null,
"tradeOfferUrl": "https://steamcommunity.com/tradeoffer/new/?partner=328774729&token=4aJbvC1t",
"isMarketplaceSeller": false,
"flagImpersonated": true,
"bans": []
}
}
(
(
// a misc
"misc" === spellItem.slot &&
(
// that has a defindex >= 30538
spellItem.defindex >= 30538
// or that has an unu effect >= 87
|| (spellItem.particle && spellItem.particle.id >= 87)
|| (spellItem.quality.id === 11
&& [
180, // Strange Frenchman's Beret
94 // Strange Texas Ten Gallon
].includes(spellItem.defindex)
)
)
)
// or
||
(
// a weapon
(spellItem.slot && ["melee", "primary", "secondary"].includes(spellItem.slot)) &&
(
// with def index between these
(
(1127 <= spellItem.defindex && spellItem.defindex <= 1178)
|| (15000 <= spellItem.defindex && spellItem.defindex <= 16102)
|| (30538 <= spellItem.defindex && spellItem.defindex <= 31182)
)
// or it has an unu effect, but not the HHHH ty
|| (spellItem.quality.id === 5 && 266 !== spellItem.defindex)
// or it is a "strange normal"
|| (spellItem.quality.id === 0 && spellItem.elevatedQuality?.id === 11)
// or it is strange of these particular items
|| (spellItem.quality.id === 11 && [
851,// strange awper hand
449,// strange winger
317, // strange candy cane
587, // strange Apoco-Fists
140, // strange wrangler
401, // strange Shahanshah
327, // strange Claidheamohmor
310, // strange Warrior's Spirit
].includes(spellItem.defindex))
)
) ||
// or just is a decorated weapon
spellItem.quality.id === 15)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment