Skip to content

Add DeckySales plugin to Plugin Store - #1124

Open
zarif98 wants to merge 2 commits into
SteamDeckHomebrew:mainfrom
zarif98:add/deckysales
Open

zarif98 wants to merge 2 commits into
SteamDeckHomebrew:mainfrom
zarif98:add/deckysales

Conversation

@zarif98

@zarif98 zarif98 commented Sep 11, 2026

Copy link
Copy Markdown

Add DeckySales to Plugin Store

DeckySales shows you where a game is cheapest anywhere, not just on Steam! It sends you notifications if a game is on sale and shows you the cheapest game available. I built this off of Deckdeals, but it has been disbanded. I've already credited the user as well.

A picture is worth a 1000 words, so here are some images of what I have built.
Wishlist deals
Best price now

It adds a panel with Steam's current price next to the lowest price across 30 stores. Prices are also converted between currencies. Wishlist alerts run in the background, and tapping on the notification opens a list of game deals found.

It differs from IsThereAnyDeal for Deck by adding background wishlist alerts across every store, a deals list, a direct "cheapest right now vs Steam" comparison, sale prediction, and currency conversion. I use the IsThereAnyDeal API to pull the latest prices. Just to forewarn, this is a fork of Deckdeals, which was never on the store.

Task Checklist

Developer

  • I am the original author or an authorized maintainer of this plugin.
  • I have abided by the licenses of the libraries I am utilizing, including attaching license notices where appropriate.
  • Generative AI was NOT used to write a majority of the code I am submitting.

Plugin

  • I have verified that my plugin works properly on the Stable and Beta update channels of SteamOS.
  • I have verified my plugin is unique or provides more/alternative functionality to a plugin already on the store.

Backend

  • No: I am using a custom backend other than Python.
  • No: I am using a tool or software from a 3rd party FOSS project that does not have it's dependencies statically linked.
  • No: I am using a custom binary that has all of it's dependencies statically linked.

Community

  • I have tested and left feedback on two other pull requests for new or updating plugins.
  • I have commented links to my testing report in this PR.

Testing

  • Tested by a third party on SteamOS Stable or Beta update channel.

@zarif98
zarif98 requested a review from a team as a code owner September 11, 2026 04:07
@github-actions github-actions Bot added the not-plugin Not related to plugins themselves label Sep 11, 2026
@github-actions

Copy link
Copy Markdown

Issues Found

No issues with your PR description were found.

Next Steps

  1. If we found any issues above, please edit your pull request description to resolve them and leave a comment saying you've done so.
  2. For the quickest review, please see the Community section of the pull request template for how you can help other developers.
  3. Once your description is correct, a maintainer will review your pull request as soon as possible.

Thank you for your contribution! If you need any help, please reach out on our Discord server. ❤️

@zarif98 zarif98 changed the title Add DeckySales plugin Add DeckySales plugin to Plugin Store Sep 11, 2026
@github-actions github-actions Bot added the plugin-addition Adding a plugin to the Plugin Store label Sep 11, 2026
@datbird

datbird commented Sep 13, 2026

Copy link
Copy Markdown

Testing report

Built from source at the PR pin 362e24b (v1.2.2) and used it on hardware. It works as advertised and I really like it. No notes from an end user point of view. The store page panel is clear, the cheapest price next to Steam's is genuinely useful, and settings do what they say. Everything below is code level, none of it blocking.

Environment: Steam Deck OLED, SteamOS 3.8.16 Stable, Decky Loader v3.2.8. Built on-device with node 22.23.0 and pnpm 9.15.9. Install, typecheck, 163 tests and build all clean, and the bundle hashed identical to my desktop build. Installed root owned, loader logged Loaded DeckySales, no traceback.

What I exercised: the store page panel on a few games, the settings panel in the QAM, and the data path itself from the Deck: credentials endpoint, ITAD lookup, live prices across stores, and the currency API. All returned what the plugin expects. Pulled the panel out of the DOM on Baldur's Gate 3 to be sure: it sits inside .game_area_purchase_game and read CURRENT 59.99 USD Steam, BEST NOW 59.99 USD Steam, All-time low 41.99 USD 7/30/2026, which matches ITAD.

One innerHTML write skips the escaping

StoreInjector.ts:965, the graph tooltip, writes price, date and store straight into innerHTML. Every neighbouring write goes through escapeHtml first, and the comment at line 311 says provider values are escaped. This one isn't. Same fix as line 792, just wrap the three values. Low severity since the names come from ITAD, but the file already set the standard.

The ITAD key rides along in the debug object

getLowestPrice returns debug: { lookupUrl, historyUrl } and both URLs carry key=. Nothing logs it today, so it's one console.log(result) away from landing in a bug report. Strip the key before it goes in debug.

Settings writes aren't atomic

settings.py truncates settings.json then writes into it. Interrupt that (power loss, suspend) and read() swallows the decode error and starts from {}. That silently drops a user's own ITAD key and resets the wishlist baseline. Write to a temp file and os.replace() it.

I saw the quiet half of this on my Deck. After first load settings.json was 0 bytes (not sure what wrote it, the loader doesn't do that for my other plugins), and the "Failed to read settings" error never showed up in the plugin log or the journal, because read() runs at import before logging is wired up. So a bad file is both fatal to settings and invisible.

Smaller notes

main.py's _migration is still the template boilerplate. Harmless, but reviewers usually ask for it to go, and a Deckdeals user gets no settings carried over.

It loads as a legacy plugin and the console warns findModuleChild is deprecated and will be removed soon. Works fine on 3.2.8, just a deadline to keep an eye on.

MAX_WISHLIST_APPS = 500 truncates silently. The wishlist status line could say "checked 500 of 830".

Happy to re-test once you push fixes.

@datbird datbird mentioned this pull request Sep 13, 2026
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

not-plugin Not related to plugins themselves plugin-addition Adding a plugin to the Plugin Store

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants