Skip to content

feat(salesforce): add Salesforce CRM integration#271

Merged
TheRealAgentK merged 12 commits intomasterfrom
feat/salesforce-clean
Apr 24, 2026
Merged

feat(salesforce): add Salesforce CRM integration#271
TheRealAgentK merged 12 commits intomasterfrom
feat/salesforce-clean

Conversation

@Shubhank-Jonnada
Copy link
Copy Markdown
Contributor

Summary

Adds a brand new Salesforce CRM integration covering searching/updating records and summarising task & event activity.

Actions (7)

Action Description
search_records Run a SOQL query against any Salesforce object
get_record Fetch a single record by ID and object type
update_record Update fields on any record via PATCH
list_tasks List Task records with optional status, date, and owner filters
list_events List Event records with optional date and owner filters
get_task_summary Retrieve a Task by ID with human-readable summary
get_event_summary Retrieve an Event by ID with human-readable summary

Auth

  • OAuth 2.0 via Salesforce Connected App (platform auth type)
  • instance_url resolved from context.metadata — Salesforce returns this at token time and the platform stores it separately from credentials

Tests

  • 56 pytest unit tests, fully mocked, zero credentials required (pytest -m unit)
  • Integration test file included for live credential testing (pytest -m integration)

Test plan

  • pytest salesforce/tests/test_salesforce_unit.py -v — all 56 pass
  • validate_integration.py salesforce — no errors
  • check_code.py salesforce — no errors
  • Connect Salesforce Developer Edition via OAuth and test search_records, list_tasks, list_events

- 7 actions: search_records, get_record, update_record, list_tasks,
  list_events, get_task_summary, get_event_summary
- OAuth 2.0 platform auth, instance_url resolved from context.metadata
- 56 pytest unit tests, zero credentials required
- Real Salesforce logo icon (512x512)
- README with auth setup, actions table, troubleshooting
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 24, 2026

🔍 Integration Validation Results

Commit: 100126d862bea2d52e7bc10277099532bb2d2a54 · chore(salesforce): remove context.py — no longer required by validator
Updated: 2026-04-24T04:27:49Z

Changed directories: salesforce

Check Result
Structure ✅ Passed
Code ✅ Passed
Tests ✅ Passed
README ✅ Passed
Version ✅ Passed
✅ Structure Check output
Validating 1 integration(s)...

============================================================
Integration: salesforce
============================================================
✅ All checks passed!

============================================================
SUMMARY
============================================================
Integrations validated: 1
Total errors: 0
Total warnings: 0

✅ All validations passed!
✅ Code Check output
----------------------------------------
Checking: salesforce
----------------------------------------

📦 Installing dependencies...

🐍 Checking Python syntax...
   ✅ Syntax OK

📥 Checking imports...
   ✅ Imports OK

📄 Checking JSON files...
   ✅ JSON files OK

🔍 Linting with ruff...
   ✅ Lint OK

🎨 Checking formatting with ruff...
   ✅ Formatting OK

🔒 Scanning for security issues with bandit...
   ✅ Security OK

🛡️ Checking dependencies for vulnerabilities with pip-audit...
   ✅ Dependencies OK

🔗 Checking config-code sync...
   ✅ Config-code sync OK

🔄 Checking fetch patterns...
   ✅ Fetch patterns OK

========================================
✅ CODE CHECK PASSED
========================================
✅ Tests output

Integration    Tests  Coverage        Status
--------------------------------------------
salesforce     63/63       99%      ✅ Passed
--------------------------------------------
Total          63/63            ✅ All passed

✅ Tests passed: salesforce
✅ README Check output
========================================
✅ README CHECK PASSED
========================================
✅ Version Check output
✅ salesforce: New integration with version 1.0.0

========================================
✅ VERSION CHECK PASSED
========================================

@TheRealAgentK TheRealAgentK self-requested a review April 24, 2026 03:38
@TheRealAgentK
Copy link
Copy Markdown
Collaborator

@Shubhank-Jonnada Can you please change the integration tests to match the setup from other integrations that have them now.

For instance, they should load the required credentials from your local .env and match an entry in .env.example (empty value) and there are standard patterns for this that the skill should be able to easily mimic and create.

Copy link
Copy Markdown
Collaborator

@TheRealAgentK TheRealAgentK left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment on main thread re integration tests.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6de77be8db

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread salesforce/salesforce.py
…etchResponse, live_context

- Rewrote test_salesforce_unit.py using importlib.util.spec_from_file_location loader
  and FetchResponse(status, headers, data) mocks per writing-unit-tests skill
- Added test_salesforce_integration.py with live_context Variant 3 (platform OAuth
  with real aiohttp), require_*_id() skip helpers, and @pytest.mark.destructive guard
- Removed old test_salesforce.py (asyncio.run style, superseded)
- All 56 unit tests pass; ruff + bandit clean
- Rename SALESFORCE_TOKEN → SALESFORCE_ACCESS_TOKEN to match _ACCESS_TOKEN pattern
- Rename SALESFORCE_RECORD/TASK/EVENT_ID → SALESFORCE_TEST_*_ID to match TEST_ prefix pattern
- Expand docstring with full env var reference
- Add Salesforce block to .env.example (SALESFORCE_ACCESS_TOKEN, SALESFORCE_INSTANCE_URL, TEST_RECORD/TASK/EVENT_ID)
Add _validate_sf_id() that enforces 15/18-char alphanumeric format on
record_id, task_id, and event_id before they are interpolated into SOQL
WHERE clauses or sobject URL paths — addresses SOQL injection risk flagged
by code review on get_task_summary and get_event_summary.

- Add TestValidateSfId unit tests (accepts 15/18-char, rejects short/special/empty)
- Update existing test fixtures to use valid 15-char IDs (e.g. 003000000000001)
- 64 unit tests passing
@Shubhank-Jonnada
Copy link
Copy Markdown
Contributor Author

@Shubhank-Jonnada Can you please change the integration tests to match the setup from other integrations that have them now.

For instance, they should load the required credentials from your local .env and match an entry in .env.example (empty value) and there are standard patterns for this that the skill should be able to easily mimic and create.

Done, aligned with the standard pattern env vars renamed to follow the ACCESS_TOKEN / TEST conventionsand added to .env.example @TheRealAgentK

@TheRealAgentK
Copy link
Copy Markdown
Collaborator

Review — Salesforce Integration

Note: This review was performed using the Autohive SDK integration skills (building-integration, writing-unit-tests, writing-integration-tests, upgrading-sdk-v2). All CI-equivalent checks were run locally — validate_integration.py ✅, check_code.py ✅, 64/64 unit tests ✅.


🔴 Must-Fix

1. Missing ActionError — all error paths use the old 1.0.x pattern

The integration pins autohive-integrations-sdk~=2.0.0 and correctly uses FetchResponse, but every error path still returns ActionResult(data={"result": False, "error": str(e)}) instead of ActionError(message=str(e)). This applies to:

  • Every except Exception as e block (lines 68, 87, 109, 189, 218, 266, 299)
  • The "not found" branches in get_task_summary and get_event_summary (lines 259, 288)
# Current (1.0.x pattern)
return ActionResult(data={"result": False, "error": str(e)}, cost_usd=0.0)

# Should be
return ActionError(message=str(e))

ActionError also needs to be added to the SDK import.

2. Output schemas still include "result": { "type": "boolean" }

Once error paths use ActionError, the "result" boolean property in every action's output_schema in config.json becomes unnecessary — happy paths always succeed, and errors bypass schema validation entirely. These should be removed.

3. Unit tests assert the old error pattern

All error tests check result.result.data["result"] is False and result.result.data["error"]. Once ActionError is adopted, these need to change to:

assert result.type == ResultType.ACTION_ERROR
assert "..." in result.result.message

ResultType is not currently imported in the test file.

4. config.json version is 1.0.0 — should be 2.0.0

The SDK dependency is 2.0.0, so the integration version in config.json should be bumped to 2.0.0 to match.


🟡 Should-Fix

5. SOQL injection on assigned_to_id

status is escaped with .replace("'", "\\'"), but assigned_to_id is interpolated directly into SOQL without validation or escaping:

conditions.append(f"OwnerId = '{assigned_to_id}'")

It should either be validated with _validate_sf_id() or at minimum escape single quotes. The date parameters (due_date_from, due_date_to, start_date_from, start_date_to) could also benefit from format validation.

6. conftest.py in tests/ is non-standard

It only does sys.path.insert(0, os.path.dirname(__file__)), which is already handled by the boilerplate in each test file. Other integrations don't use a conftest.py — consider removing it.

7. README "Running Tests" section is incorrect

The README says cd salesforce/tests && python test_salesforce.py. It should be:

# Unit tests
pytest salesforce/ -v

# Integration tests
pytest salesforce/tests/test_salesforce_integration.py -m integration

8. os.environ fallback for instance_url

_get_token_and_instance falls back to os.environ.get("SALESFORCE_INSTANCE_URL"). For a platform OAuth integration, instance_url should come from credentials or metadata only. The env var fallback is a dev convenience that could mask misconfiguration in production.


🟢 Looks Good

  • Structure — all required files present, clean layout
  • FetchResponse handlingresponse.data used correctly everywhere
  • Test coverage — 64 tests total (~8/action), solid coverage across happy path, request verification, error paths, and edge cases
  • Integration tests — correct live_context variant (Platform OAuth), require_* skip helpers, @pytest.mark.destructive on write tests
  • SOQL query builders — clean helpers with limit capping, well-tested
  • ID validation_validate_sf_id regex prevents injection on record IDs
  • All CI checks pass — structure validation, code quality, lint, format, security scan, 64/64 tests

Summary: The integration is well-written and functional, but it's half-upgraded to SDK 2.0.0 — FetchResponse is adopted but ActionError is not. That's the main blocker. The SOQL injection on assigned_to_id and the config version bump are the other important items.

@TheRealAgentK
Copy link
Copy Markdown
Collaborator

Review — Salesforce Integration

Note: This review was performed using the Autohive SDK integration skills (building-integration, writing-unit-tests, writing-integration-tests, upgrading-sdk-v2). All CI-equivalent checks were run locally — validate_integration.py ✅, check_code.py ✅, 64/64 unit tests ✅.

🔴 Must-Fix

1. Missing ActionError — all error paths use the old 1.0.x pattern

The integration pins autohive-integrations-sdk~=2.0.0 and correctly uses FetchResponse, but every error path still returns ActionResult(data={"result": False, "error": str(e)}) instead of ActionError(message=str(e)). This applies to:

  • Every except Exception as e block (lines 68, 87, 109, 189, 218, 266, 299)
  • The "not found" branches in get_task_summary and get_event_summary (lines 259, 288)
# Current (1.0.x pattern)
return ActionResult(data={"result": False, "error": str(e)}, cost_usd=0.0)

# Should be
return ActionError(message=str(e))

ActionError also needs to be added to the SDK import.

2. Output schemas still include "result": { "type": "boolean" }

Once error paths use ActionError, the "result" boolean property in every action's output_schema in config.json becomes unnecessary — happy paths always succeed, and errors bypass schema validation entirely. These should be removed.

3. Unit tests assert the old error pattern

All error tests check result.result.data["result"] is False and result.result.data["error"]. Once ActionError is adopted, these need to change to:

assert result.type == ResultType.ACTION_ERROR
assert "..." in result.result.message

ResultType is not currently imported in the test file.

4. config.json version is 1.0.0 — should be 2.0.0

The SDK dependency is 2.0.0, so the integration version in config.json should be bumped to 2.0.0 to match.

🟡 Should-Fix

5. SOQL injection on assigned_to_id

status is escaped with .replace("'", "\\'"), but assigned_to_id is interpolated directly into SOQL without validation or escaping:

conditions.append(f"OwnerId = '{assigned_to_id}'")

It should either be validated with _validate_sf_id() or at minimum escape single quotes. The date parameters (due_date_from, due_date_to, start_date_from, start_date_to) could also benefit from format validation.

6. conftest.py in tests/ is non-standard

It only does sys.path.insert(0, os.path.dirname(__file__)), which is already handled by the boilerplate in each test file. Other integrations don't use a conftest.py — consider removing it.

7. README "Running Tests" section is incorrect

The README says cd salesforce/tests && python test_salesforce.py. It should be:

# Unit tests
pytest salesforce/ -v

# Integration tests
pytest salesforce/tests/test_salesforce_integration.py -m integration

8. os.environ fallback for instance_url

_get_token_and_instance falls back to os.environ.get("SALESFORCE_INSTANCE_URL"). For a platform OAuth integration, instance_url should come from credentials or metadata only. The env var fallback is a dev convenience that could mask misconfiguration in production.

🟢 Looks Good

  • Structure — all required files present, clean layout
  • FetchResponse handlingresponse.data used correctly everywhere
  • Test coverage — 64 tests total (~8/action), solid coverage across happy path, request verification, error paths, and edge cases
  • Integration tests — correct live_context variant (Platform OAuth), require_* skip helpers, @pytest.mark.destructive on write tests
  • SOQL query builders — clean helpers with limit capping, well-tested
  • ID validation_validate_sf_id regex prevents injection on record IDs
  • All CI checks pass — structure validation, code quality, lint, format, security scan, 64/64 tests

Summary: The integration is well-written and functional, but it's half-upgraded to SDK 2.0.0 — FetchResponse is adopted but ActionError is not. That's the main blocker. The SOQL injection on assigned_to_id and the config version bump are the other important items.

Item 4 is bs - ignore that @Shubhank-Jonnada - I'll make sure the skill gets an update :)

Item 5: that looks like a correct finding, but verify please

Item 6: I think that's partially wrong - we do have a conftest, but I'll need to double check something

Item 8 is incorrect too - will adjust the skills

1,2 3 and 7 look all correct to me.

@Shubhank-Jonnada
Copy link
Copy Markdown
Contributor Author

Resolved these @TheRealAgentK, please check

  • Item 1 - f4d5b0d - all error paths now return ActionError(message=...) instead of ActionResult(data={"result": False})
  • Item 2 - 720658d - removed result: boolean from all output schemas in config.json
  • Item 3 - ec207ef - unit test error assertions updated to ResultType.ACTION_ERROR and result.result.message
  • Item 5 - a99f73d - assigned_to_id now validated with _validate_sf_id before SOQL interpolation
  • Item 7 - 29c1c0c - README running tests section updated with correct pytest commands and env var names

@Shubhank-Jonnada
Copy link
Copy Markdown
Contributor Author

Also removed context.py - 100126d - updated validator no longer requires it

@TheRealAgentK TheRealAgentK merged commit 6b7bb76 into master Apr 24, 2026
3 checks passed
@TheRealAgentK TheRealAgentK deleted the feat/salesforce-clean branch April 24, 2026 04:31
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.

2 participants