Skip to content

Add optional Salesforce -> Discord rich-presence bridge (#145) - #146

Open
jdjioe5-cpu wants to merge 1 commit into
JustTemmie:mainfrom
jdjioe5-cpu:feature/salesforce-integration
Open

Add optional Salesforce -> Discord rich-presence bridge (#145)#146
jdjioe5-cpu wants to merge 1 commit into
JustTemmie:mainfrom
jdjioe5-cpu:feature/salesforce-integration

Conversation

@jdjioe5-cpu

Copy link
Copy Markdown

Summary

Adds a disabled-by-default SALESFORCE config block that, when enabled, runs a configured SOQL query against a Salesforce org whenever no Steam / local / webscraped game is detected, and maps the first record's selected fields into the existing Discord rich-presence model.

Closes #145.

Changes

  • salesforce.py — pure stdlib + requests (no new pip dependency). Supports both OAuth 2.0 flows:
    • client_credentials (server-to-server)
    • password (username-password with security-token concatenation)
      Tokens are cached in-process and re-used until ~60 s before declared expiry; a 401 from the SOQL endpoint drops the cache so the next cycle re-auths. The module never logs secrets.
  • main.py — adds the SALESFORCE default config block, a getSalesforcePresence() probe, and Salesforce-aware short-circuits in getGameSteamID(), getGameDiscordID() and getGameImage() so the Steam store/SGDB lookups are skipped when the presence is Salesforce-driven.
  • exampleconfig.json — adds the disabled-by-default SALESFORCE block.
  • README.md — adds a full Salesforce setup section covering auth flows, config keys, templated SOQL, and security notes.
  • tests/test_salesforce.py — 14 deterministic mocked tests covering both auth flows, the disabled state, network failures, empty / missing-name records, the SOQL_TEMPLATE path, the field-extraction helpers, and 401 token-cache eviction. No live Salesforce dependency.

Verification

  • python3 -m py_compile main.py salesforce.py tests/test_salesforce.py — OK
  • python3 -m unittest tests.test_salesforce — 14 / 14 pass
  • python3 -c "import json; json.load(open('exampleconfig.json'))" — OK
  • Live integration smoke test (mocked requests.Session) returns the expected presence dict shape.

Notes for reviewer

The OWNER's most recent comment on #145 ("i am unsure how to best implement it, do whatever you believe to be most efficient") was taken as the green light to ship a bounded, opt-in implementation. The integration is disabled by default so existing users see no behavioural change. If the desired UX is to default-on or to drive the Discord application ID from the Salesforce org URL rather than the user's existing app ID, that's a one-line config tweak — happy to follow up.

Adds a disabled-by-default SALESFORCE config block that runs a SOQL query
when no Steam / local / webscraped game is detected, and maps the first
record's selected fields into the existing Discord presence model.

The new salesforce.py module is pure stdlib + requests (already required
by the rest of the script) and supports both OAuth 2.0 client-credentials
and username-password flows. Tokens are cached in-process and re-used
until ~60s before expiry; a 401 response automatically clears the cache
so the next cycle re-auths. The module never logs secrets.

main.py is wired up so:
  * the SALESFORCE block is added to the default config (ENABLED=false);
  * a new getSalesforcePresence() runs after the other presence probes;
  * getGameSteamID() and getGameImage() are skipped when the presence is
    Salesforce-driven (no Steam store/SGDB lookups make sense);
  * getGameDiscordID() falls back to defaultAppID for the same reason.

exampleconfig.json is updated with the new disabled-by-default block,
README.md gets a full setup section, and tests/test_salesforce.py adds
14 deterministic mocked tests covering both auth flows, the disabled
state, network failures, empty records, missing-name records, the
SOQL_TEMPLATE path, and the field-extraction helpers.

Closes JustTemmie#145
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bounty: $300] Salesforce integration

1 participant