Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,12 @@
# HUBSPOT_TEST_NOTE_ID=
# HUBSPOT_TEST_OWNER_ID=

# -- Salesforce --
# SALESFORCE_ACCESS_TOKEN=
# SALESFORCE_INSTANCE_URL=
# SALESFORCE_TEST_RECORD_ID=
# SALESFORCE_TEST_TASK_ID=
# SALESFORCE_TEST_EVENT_ID=

# -- Xero --
# (uses platform OAuth — tokens are short-lived, typically not set here)
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ Supports basic HTTP authentication and Bearer token authentication via the SDK.

[float](float): Comprehensive resource management and project scheduling integration with Float API for team capacity planning, time tracking, and project coordination. Supports full CRUD operations for team members (people) with roles, departments, rates, and availability management. Includes complete project lifecycle management with client associations, budgets, timelines, and team assignments. Features task/allocation scheduling across team members, time off management with leave types, logged time tracking with billable hours, and client relationship management. Provides access to organizational structure (departments, roles), account settings, project stages, phases, milestones, and expenses. Includes comprehensive reporting capabilities (people utilization, project analytics) with date range filtering. Features 60 actions covering all Float API v3 endpoints, custom API key authentication with required User-Agent header, connected account information display, pagination support (up to 200 items per page), rate limiting awareness (200 GET/min, 100 non-GET/min), field filtering, sorting, modified-since sync capabilities, and ActionResult return type for cost tracking. Ideal for resource planning, capacity management, project scheduling, time tracking workflows, and team utilization analysis.

### Salesforce

[salesforce](salesforce): Salesforce is the world's leading CRM platform for managing sales pipelines, customer relationships, and activity tracking. This integration provides 7 focused actions covering record search via SOQL, single-record retrieval and update, task and event listing with filters, and human-readable summaries of task and event records. Supports OAuth 2.0 (platform) authentication. Ideal for sales automation, CRM data updates, and surfacing task and event activity within workflows.

### Shopify Admin

[shopify-admin](shopify-admin): Integrates with the Shopify Admin API for backend store management. Currently enables comprehensive customer lifecycle management including searching, creating, updating, and deleting customer records via the GraphQL API.
Expand Down
66 changes: 66 additions & 0 deletions salesforce/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Salesforce

Salesforce is the world's leading CRM platform, used to manage sales pipelines, customer relationships, tasks, events, and more. This integration provides 7 focused actions for searching and updating records, and for retrieving summaries of task and event activity.

## Auth Setup

This integration uses **OAuth 2.0** via a Salesforce Connected App.

1. Log in to Salesforce and go to **Setup → App Manager → New Connected App**.
2. Enable **OAuth Settings** and set a callback URL.
3. Add the **`api`** scope under Selected OAuth Scopes.
4. Save and copy the **Consumer Key** (Client ID) and **Consumer Secret**.
5. Use those credentials to connect via the Autohive platform OAuth flow.

## Actions

| Action | Description | Key Inputs | Key Outputs |
|--------|-------------|------------|-------------|
| `search_records` | Run a SOQL query against any object | `soql` | `records`, `total_size` |
| `get_record` | Fetch a single record by ID | `object_type`, `record_id` | `record` |
| `update_record` | Update fields on a record | `object_type`, `record_id`, `fields` | `result`, `record_id` |
| `list_tasks` | List Task records with optional filters | `status`, `due_date_from`, `due_date_to`, `limit` | `tasks`, `total_size` |
| `list_events` | List Event records with optional date filters | `start_date_from`, `start_date_to`, `limit` | `events`, `total_size` |
| `get_task_summary` | Get a readable summary of a Task | `task_id` | `summary`, `task` |
| `get_event_summary` | Get a readable summary of an Event | `event_id` | `summary`, `event` |

## API Info

- **Base URL:** `https://{instance_url}/services/data/v62.0/`
- **Docs:** https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/
- **Rate limits:** Typically 15,000 API calls per 24 hours (varies by Salesforce edition)
- **Query endpoint:** `GET /query?q={SOQL}`
- **Record endpoint:** `GET /sobjects/{ObjectType}/{Id}`

## Running Tests

Copy `.env.example` to `.env` in the repo root and fill in your credentials:

```bash
SALESFORCE_ACCESS_TOKEN=your_access_token
SALESFORCE_INSTANCE_URL=https://yourorg.my.salesforce.com
# Optional — tests that need real object IDs will skip if unset
SALESFORCE_TEST_RECORD_ID=003XXXXXXXXXXXXXXX
SALESFORCE_TEST_TASK_ID=00TXXXXXXXXXXXXXXX
SALESFORCE_TEST_EVENT_ID=00UXXXXXXXXXXXXXXX
```

```bash
# Unit tests (no credentials needed)
pytest salesforce/ -v

# Integration tests (read-only, requires .env)
pytest salesforce/tests/test_salesforce_integration.py -m "integration and not destructive"

# Destructive integration tests (updates real data)
pytest salesforce/tests/test_salesforce_integration.py -m "integration and destructive"
```

## Troubleshooting

| Error | Cause | Fix |
|-------|-------|-----|
| `401 Unauthorized` | Expired or invalid access token | Re-authenticate via Autohive OAuth flow |
| `400 MALFORMED_QUERY` | Invalid SOQL syntax | Check field names, quote strings with single quotes |
| `404 NOT_FOUND` | Record ID doesn't exist or wrong object type | Verify ID and object type match |
| `REQUEST_LIMIT_EXCEEDED` | Daily API call limit hit | Wait until the 24-hour window resets |
3 changes: 3 additions & 0 deletions salesforce/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .salesforce import salesforce

__all__ = ["salesforce"]
269 changes: 269 additions & 0 deletions salesforce/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,269 @@
{
"name": "Salesforce",
"display_name": "Salesforce",
"version": "1.0.0",
"description": "Salesforce CRM integration for searching and updating records, and summarising task and event activity.",
"entry_point": "salesforce.py",
"auth": {
"type": "platform",
"provider": "salesforce",
"scopes": [
"api"
]
},
"actions": {
"search_records": {
"display_name": "Search Records",
"description": "Run a SOQL query to search any Salesforce object (e.g. Contact, Lead, Opportunity, Account). Returns matching records.",
"input_schema": {
"type": "object",
"properties": {
"soql": {
"type": "string",
"description": "A valid SOQL query string, e.g. SELECT Id, Name, Email FROM Contact WHERE LastName = 'Smith' LIMIT 10"
}
},
"required": [
"soql"
]
},
"output_schema": {
"type": "object",
"properties": {
"records": {
"type": "array",
"items": {
"type": "object"
},
"description": "List of matching Salesforce records"
},
"total_size": {
"type": "integer",
"description": "Total number of records matched"
},
"done": {
"type": "boolean",
"description": "Whether all results have been returned"
}
}
}
},
"get_record": {
"display_name": "Get Record",
"description": "Retrieve a single Salesforce record by its ID and object type (e.g. Contact, Lead, Opportunity).",
"input_schema": {
"type": "object",
"properties": {
"object_type": {
"type": "string",
"description": "Salesforce object type, e.g. Contact, Lead, Account, Opportunity"
},
"record_id": {
"type": "string",
"description": "The Salesforce record ID (15 or 18 character)"
},
"fields": {
"type": "string",
"description": "Comma-separated list of fields to return. If omitted, all fields are returned."
}
},
"required": [
"object_type",
"record_id"
]
},
"output_schema": {
"type": "object",
"properties": {
"record": {
"type": "object",
"description": "The Salesforce record fields"
}
}
}
},
"update_record": {
"display_name": "Update Record",
"description": "Update one or more fields on an existing Salesforce record by ID and object type.",
"input_schema": {
"type": "object",
"properties": {
"object_type": {
"type": "string",
"description": "Salesforce object type, e.g. Contact, Lead, Account, Opportunity"
},
"record_id": {
"type": "string",
"description": "The Salesforce record ID to update"
},
"fields": {
"type": "object",
"description": "Key-value pairs of fields to update, e.g. {\"Phone\": \"0400000000\", \"Title\": \"Manager\"}"
}
},
"required": [
"object_type",
"record_id",
"fields"
]
},
"output_schema": {
"type": "object",
"properties": {
"record_id": {
"type": "string"
},
"object_type": {
"type": "string"
}
}
}
},
"list_tasks": {
"display_name": "List Tasks",
"description": "List Salesforce Task records with optional filters for status, due date, and assigned user.",
"input_schema": {
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "Filter by task status, e.g. Not Started, In Progress, Completed, Waiting on someone else, Deferred"
},
"assigned_to_id": {
"type": "string",
"description": "Filter by assigned user ID (OwnerId)"
},
"due_date_from": {
"type": "string",
"description": "Filter tasks due on or after this date (YYYY-MM-DD)"
},
"due_date_to": {
"type": "string",
"description": "Filter tasks due on or before this date (YYYY-MM-DD)"
},
"limit": {
"type": "integer",
"description": "Maximum number of tasks to return (default 25, max 200)",
"default": 25
}
},
"required": []
},
"output_schema": {
"type": "object",
"properties": {
"tasks": {
"type": "array",
"items": {
"type": "object"
},
"description": "List of Task records"
},
"total_size": {
"type": "integer"
}
}
}
},
"list_events": {
"display_name": "List Events",
"description": "List Salesforce Event (calendar) records with optional date range filters.",
"input_schema": {
"type": "object",
"properties": {
"start_date_from": {
"type": "string",
"description": "Return events starting on or after this date (YYYY-MM-DD)"
},
"start_date_to": {
"type": "string",
"description": "Return events starting on or before this date (YYYY-MM-DD)"
},
"assigned_to_id": {
"type": "string",
"description": "Filter by assigned user ID (OwnerId)"
},
"limit": {
"type": "integer",
"description": "Maximum number of events to return (default 25, max 200)",
"default": 25
}
},
"required": []
},
"output_schema": {
"type": "object",
"properties": {
"events": {
"type": "array",
"items": {
"type": "object"
},
"description": "List of Event records"
},
"total_size": {
"type": "integer"
}
}
}
},
"get_task_summary": {
"display_name": "Get Task Summary",
"description": "Retrieve a single Salesforce Task record by ID and return a human-readable summary of its details.",
"input_schema": {
"type": "object",
"properties": {
"task_id": {
"type": "string",
"description": "The Salesforce Task record ID"
}
},
"required": [
"task_id"
]
},
"output_schema": {
"type": "object",
"properties": {
"summary": {
"type": "string",
"description": "Human-readable summary of the task"
},
"task": {
"type": "object",
"description": "Raw task record fields"
}
}
}
},
"get_event_summary": {
"display_name": "Get Event Summary",
"description": "Retrieve a single Salesforce Event record by ID and return a human-readable summary of its details.",
"input_schema": {
"type": "object",
"properties": {
"event_id": {
"type": "string",
"description": "The Salesforce Event record ID"
}
},
"required": [
"event_id"
]
},
"output_schema": {
"type": "object",
"properties": {
"summary": {
"type": "string",
"description": "Human-readable summary of the event"
},
"event": {
"type": "object",
"description": "Raw event record fields"
}
}
}
}
}
}
Binary file added salesforce/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions salesforce/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
autohive-integrations-sdk~=2.0.0
Loading
Loading