├── .github ├── PULL_REQUEST_TEMPLATE.md ├── workflows │ ├── sync-labels.yml │ ├── golangci-lint.yml │ ├── steampipe-anywhere.yml │ ├── registry-publish.yml │ ├── add-issue-to-project.yml │ └── stale.yml ├── ISSUE_TEMPLATE │ ├── feature-request---new-table.md │ ├── config.yml │ ├── bug_report.md │ └── feature_request.md └── dependabot.yml ├── Makefile ├── main.go ├── .gitignore ├── .goreleaser.yml ├── salesforce ├── connection_config.go ├── table_salesforce_permission_set_assignment.go ├── table_salesforce_opportunity_contact_role.go ├── table_salesforce_account_contact_role.go ├── table_salesforce_object_permission.go ├── table_salesforce_user.go ├── table_salesforce_pricebook.go ├── table_salesforce_lead.go ├── table_salesforce_permission_set.go ├── table_salesforce_product.go ├── table_salesforce_account.go ├── table_salesforce_object.go ├── table_salesforce_asset.go ├── table_salesforce_contract.go ├── table_salesforce_opportunity.go ├── table_salesforce_order.go ├── table_salesforce_contact.go └── plugin.go ├── config └── salesforce.spc ├── docs ├── tables │ ├── salesforce_contact.md │ ├── salesforce_asset.md │ ├── salesforce_order.md │ ├── salesforce_account_contact_role.md │ ├── salesforce_product.md │ ├── salesforce_permission_set_assignment.md │ ├── salesforce_lead.md │ ├── salesforce_object_permission.md │ ├── salesforce_opportunity_contact_role.md │ ├── salesforce_contract.md │ ├── salesforce_opportunity.md │ ├── salesforce_pricebook.md │ ├── salesforce_user.md │ ├── salesforce_permission_set.md │ ├── salesforce_account.md │ └── salesforce_{object_name}.md └── index.md ├── README.md ├── go.mod ├── CHANGELOG.md └── LICENSE /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Example query results 2 |
3 | Results 4 | 5 | ``` 6 | Add example SQL query results here (please include the input queries as well) 7 | ``` 8 |
9 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | STEAMPIPE_INSTALL_DIR ?= ~/.steampipe 2 | BUILD_TAGS = netgo 3 | install: 4 | go build -o $(STEAMPIPE_INSTALL_DIR)/plugins/hub.steampipe.io/plugins/turbot/salesforce@latest/steampipe-plugin-salesforce.plugin -tags "${BUILD_TAGS}" *.go 5 | -------------------------------------------------------------------------------- /.github/workflows/sync-labels.yml: -------------------------------------------------------------------------------- 1 | name: Sync Labels 2 | on: 3 | schedule: 4 | - cron: "30 22 * * 1" 5 | workflow_dispatch: 6 | 7 | jobs: 8 | sync_labels_workflow: 9 | uses: turbot/steampipe-workflows/.github/workflows/sync-labels.yml@main 10 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/turbot/steampipe-plugin-salesforce/salesforce" 5 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 6 | ) 7 | 8 | func main() { 9 | plugin.Serve(&plugin.ServeOpts{ 10 | PluginFunc: salesforce.Plugin}) 11 | } 12 | -------------------------------------------------------------------------------- /.github/workflows/golangci-lint.yml: -------------------------------------------------------------------------------- 1 | name: golangci-lint 2 | on: 3 | push: 4 | tags: 5 | - v* 6 | branches: 7 | - main 8 | pull_request: 9 | 10 | jobs: 11 | golangci_lint_workflow: 12 | uses: turbot/steampipe-workflows/.github/workflows/golangci-lint.yml@main 13 | -------------------------------------------------------------------------------- /.github/workflows/steampipe-anywhere.yml: -------------------------------------------------------------------------------- 1 | name: Release Steampipe Anywhere Components 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | 9 | jobs: 10 | anywhere_publish_workflow: 11 | uses: turbot/steampipe-workflows/.github/workflows/steampipe-anywhere.yml@main 12 | secrets: inherit 13 | -------------------------------------------------------------------------------- /.github/workflows/registry-publish.yml: -------------------------------------------------------------------------------- 1 | name: Build and Deploy OCI Image 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | registry_publish_workflow_ghcr: 10 | uses: turbot/steampipe-workflows/.github/workflows/registry-publish-ghcr.yml@main 11 | secrets: inherit 12 | with: 13 | releaseTimeout: 60m 14 | -------------------------------------------------------------------------------- /.github/workflows/add-issue-to-project.yml: -------------------------------------------------------------------------------- 1 | name: Assign Issue to Project 2 | 3 | on: 4 | issues: 5 | types: [opened] 6 | 7 | jobs: 8 | add-to-project: 9 | uses: turbot/steampipe-workflows/.github/workflows/assign-issue-to-project.yml@main 10 | with: 11 | issue_number: ${{ github.event.issue.number }} 12 | repository: ${{ github.repository }} 13 | secrets: inherit 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Editor cache and lock files 2 | *.swp 3 | *.swo 4 | 5 | # Binaries for programs and plugins 6 | *.exe 7 | *.exe~ 8 | *.dll 9 | *.so 10 | *.dylib 11 | 12 | # Test binary, built with `go test -c` 13 | *.test 14 | 15 | # Output of the go coverage tool, specifically when used with LiteIDE 16 | *.out 17 | 18 | # Dependency directories (remove the comment below to include it) 19 | # vendor/ 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request---new-table.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request - New table 3 | about: Suggest a new table for this project 4 | title: Add table salesforce_ 5 | labels: enhancement, new table 6 | assignees: "" 7 | --- 8 | 9 | **References** 10 | Add any related links that will help us understand the resource, including vendor documentation, related GitHub issues, and Go SDK documentation. 11 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: Stale Issues and PRs 2 | on: 3 | schedule: 4 | - cron: "30 23 * * *" 5 | workflow_dispatch: 6 | inputs: 7 | dryRun: 8 | description: Set to true for a dry run 9 | required: false 10 | default: "false" 11 | type: string 12 | 13 | jobs: 14 | stale_workflow: 15 | uses: turbot/steampipe-workflows/.github/workflows/stale.yml@main 16 | with: 17 | dryRun: ${{ github.event.inputs.dryRun }} 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Questions 4 | url: https://turbot.com/community/join 5 | about: GitHub issues in this repository are only intended for bug reports and feature requests. Other issues will be closed. Please ask and answer questions through the Steampipe Slack community. 6 | - name: Steampipe CLI Bug Reports and Feature Requests 7 | url: https://github.com/turbot/steampipe/issues/new/choose 8 | about: Steampipe CLI has its own codebase. Bug reports and feature requests for those pieces of functionality should be directed to that repository. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "" 5 | labels: bug 6 | assignees: "" 7 | --- 8 | 9 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **Steampipe version (`steampipe -v`)** 13 | Example: v0.3.0 14 | 15 | **Plugin version (`steampipe plugin list`)** 16 | Example: v0.5.0 17 | 18 | **To reproduce** 19 | Steps to reproduce the behavior (please include relevant code and/or commands). 20 | 21 | **Expected behavior** 22 | A clear and concise description of what you expected to happen. 23 | 24 | **Additional context** 25 | Add any other context about the problem here. 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "" 5 | labels: enhancement 6 | assignees: "" 7 | --- 8 | 9 | **Is your feature request related to a problem? Please describe.** 10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | **Describe the solution you'd like** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | 18 | **Additional context** 19 | Add any other context or screenshots about the feature request here. 20 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "gomod" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | pull-request-branch-name: 13 | separator: "-" 14 | assignees: 15 | - "misraved" 16 | - "madhushreeray30" 17 | labels: 18 | - "dependencies" 19 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | # This is an example goreleaser.yaml file with some sane defaults. 2 | # Make sure to check the documentation at http://goreleaser.com 3 | before: 4 | hooks: 5 | - go mod tidy 6 | builds: 7 | - env: 8 | - CGO_ENABLED=0 9 | - GO111MODULE=on 10 | - GOPRIVATE=github.com/turbot 11 | goos: 12 | - linux 13 | - darwin 14 | 15 | goarch: 16 | - amd64 17 | - arm64 18 | 19 | id: "steampipe" 20 | binary: "{{ .ProjectName }}.plugin" 21 | flags: 22 | - -tags=netgo 23 | 24 | archives: 25 | - format: gz 26 | name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}" 27 | files: 28 | - none* 29 | checksum: 30 | name_template: "{{ .ProjectName }}_{{ .Version }}_SHA256SUMS" 31 | algorithm: sha256 32 | changelog: 33 | sort: asc 34 | filters: 35 | exclude: 36 | - "^docs:" 37 | - "^test:" 38 | -------------------------------------------------------------------------------- /salesforce/connection_config.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 5 | ) 6 | 7 | type NamingConventionEnum string 8 | 9 | const ( 10 | API_NATIVE NamingConventionEnum = "api_native" 11 | SNAKE_CASE NamingConventionEnum = "snake_case" 12 | ) 13 | 14 | type salesforceConfig struct { 15 | URL *string `hcl:"url"` 16 | Username *string `hcl:"username"` 17 | Password *string `hcl:"password"` 18 | Token *string `hcl:"token"` 19 | ClientId *string `hcl:"client_id"` 20 | APIVersion *string `hcl:"api_version"` 21 | Objects *[]string `hcl:"objects"` 22 | NamingConvention *NamingConventionEnum `hcl:"naming_convention"` 23 | } 24 | 25 | func ConfigInstance() interface{} { 26 | return &salesforceConfig{} 27 | } 28 | 29 | // GetConfig :: retrieve and cast connection config from query data 30 | func GetConfig(connection *plugin.Connection) salesforceConfig { 31 | if connection == nil || connection.Config == nil { 32 | return salesforceConfig{} 33 | } 34 | config, _ := connection.Config.(salesforceConfig) 35 | return config 36 | } 37 | -------------------------------------------------------------------------------- /salesforce/table_salesforce_permission_set_assignment.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" 7 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 8 | ) 9 | 10 | func SalesforcePermissionSetAssignment(ctx context.Context, dm dynamicMap, config salesforceConfig) *plugin.Table { 11 | tableName := "PermissionSetAssignment" 12 | return &plugin.Table{ 13 | Name: "salesforce_permission_set_assignment", 14 | Description: "Represents the association between a User and a PermissionSet.", 15 | List: &plugin.ListConfig{ 16 | Hydrate: listSalesforceObjectsByTable(tableName, dm.salesforceColumns), 17 | KeyColumns: dm.keyColumns, 18 | }, 19 | Get: &plugin.GetConfig{ 20 | Hydrate: getSalesforceObjectbyID(tableName), 21 | KeyColumns: plugin.SingleColumn(checkNameScheme(config, dm.cols)), 22 | }, 23 | Columns: mergeTableColumns(ctx, config, dm.cols, []*plugin.Column{ 24 | {Name: "assignee_id", Type: proto.ColumnType_STRING, Description: "ID of the User to assign the permission set specified in PermissionSetId."}, 25 | {Name: "id", Type: proto.ColumnType_STRING, Description: "The Permission Set Assignment ID."}, 26 | {Name: "permission_set_group_id", Type: proto.ColumnType_STRING, Description: "If associated with a permission set group, this is the ID of that group."}, 27 | {Name: "permission_set_id", Type: proto.ColumnType_STRING, Description: "ID of the PermissionSet to assign to the user specified in AssigneeId."}, 28 | {Name: "system_modstamp", Type: proto.ColumnType_TIMESTAMP, Description: "The Date Assigned."}, 29 | }), 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /config/salesforce.spc: -------------------------------------------------------------------------------- 1 | connection "salesforce" { 2 | plugin = "salesforce" 3 | 4 | # Salesforce instance URL, e.g., "https://na01.salesforce.com/" 5 | # url = "https://na01.salesforce.com/" 6 | 7 | # Salesforce account name 8 | # username = "user@example.com" 9 | 10 | # Salesforce account password 11 | # password = "Dummy@~Password" 12 | 13 | # The Salesforce security token is only required If the client's IP address is not added to the organization's list of trusted IPs 14 | # https://help.salesforce.com/s/articleView?id=sf.security_networkaccess.htm&type=5 15 | # token = "ABO5C3PNqOP0BHsPFakeToken" 16 | 17 | # Salesforce client ID of the connected app 18 | # client_id = "3MVG99E3Ry5mh4z_FakeID" 19 | 20 | # List of Salesforce object names to generate additional tables for 21 | # This argument only accepts exact Salesforce standard and custom object names, e.g., AccountBrand, OpportunityStage, CustomApp__c 22 | # For a full list of standard object names, please see https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_list.htm 23 | # All custom object names should end in "__c", following Salesforce object naming standards 24 | # objects = ["AccountBrand", "OpportunityStage", "CustomApp__c"] 25 | 26 | # Salesforce API version to connect to 27 | # api_version = "43.0" 28 | 29 | # The naming_convention allows users to control the naming format for tables and columns in the plugin. Below are the supported values: 30 | # api_native - If set to this value, the plugin will use the native format for table names, meaning there will be no "salesforce_" prefix, and the table and column names will remain as they are in Salesforce. 31 | # snake_case (default) - If the user does not specify any value, the plugin will use snake case for table and column names and table names will have a "salesforce_" prefix. 32 | # naming_convention = "snake_case" 33 | } 34 | -------------------------------------------------------------------------------- /salesforce/table_salesforce_opportunity_contact_role.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" 7 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 8 | ) 9 | 10 | func SalesforceOpportunityContactRole(ctx context.Context, dm dynamicMap, config salesforceConfig) *plugin.Table { 11 | tableName := "OpportunityContactRole" 12 | return &plugin.Table{ 13 | Name: "salesforce_opportunity_contact_role", 14 | Description: "Represents the role that a Contact plays on an Opportunity.", 15 | List: &plugin.ListConfig{ 16 | Hydrate: listSalesforceObjectsByTable(tableName, dm.salesforceColumns), 17 | KeyColumns: dm.keyColumns, 18 | }, 19 | Get: &plugin.GetConfig{ 20 | Hydrate: getSalesforceObjectbyID(tableName), 21 | KeyColumns: plugin.SingleColumn(checkNameScheme(config, dm.cols)), 22 | }, 23 | Columns: mergeTableColumns(ctx, config, dm.cols, []*plugin.Column{ 24 | // Top columns 25 | {Name: "id", Type: proto.ColumnType_STRING, Description: "Unique identifier of the opportunity contact role in Salesforce."}, 26 | {Name: "contact_id", Type: proto.ColumnType_STRING, Description: "ID of an associated Contact."}, 27 | {Name: "is_primary", Type: proto.ColumnType_BOOL, Description: "Indicates whether the associated Contact plays the primary role on the Opportunity (true) or not (false)."}, 28 | {Name: "opportunity_id", Type: proto.ColumnType_STRING, Description: "Required. ID of an associated Opportunity."}, 29 | {Name: "role", Type: proto.ColumnType_STRING, Description: "Name of the role played by the associated Contact on the Opportunity, such as Business User or Decision Maker."}, 30 | 31 | // Other columns 32 | {Name: "created_by_id", Type: proto.ColumnType_STRING, Description: "Id of the user who created contact role record."}, 33 | {Name: "created_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date and time of the creation of the contact role record."}, 34 | {Name: "last_modified_by_id", Type: proto.ColumnType_STRING, Description: "Id of the user who most recently changed the contact role record."}, 35 | {Name: "last_modified_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date of most recent change in the contact role record."}, 36 | }), 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /salesforce/table_salesforce_account_contact_role.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" 7 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 8 | ) 9 | 10 | func SalesforceAccountContactRole(ctx context.Context, dm dynamicMap, config salesforceConfig) *plugin.Table { 11 | tableName := "AccountContactRole" 12 | return &plugin.Table{ 13 | Name: "salesforce_account_contact_role", 14 | Description: "Represents the role that a Contact plays on an Account.", 15 | List: &plugin.ListConfig{ 16 | Hydrate: listSalesforceObjectsByTable(tableName, dm.salesforceColumns), 17 | KeyColumns: dm.keyColumns, 18 | }, 19 | Get: &plugin.GetConfig{ 20 | Hydrate: getSalesforceObjectbyID(tableName), 21 | KeyColumns: plugin.SingleColumn(checkNameScheme(config, dm.cols)), 22 | }, 23 | Columns: mergeTableColumns(ctx, config, dm.cols, []*plugin.Column{ 24 | // Top columns 25 | {Name: "id", Type: proto.ColumnType_STRING, Description: "Unique identifier of the account contact role in Salesforce."}, 26 | {Name: "account_id", Type: proto.ColumnType_STRING, Description: "ID of the Account."}, 27 | {Name: "contact_id", Type: proto.ColumnType_STRING, Description: "ID of the Contact associated with this account."}, 28 | {Name: "is_primary", Type: proto.ColumnType_BOOL, Description: "Specifies whether the Contact plays the primary role on the Account (true) or not (false). Note that each account has only one primary contact role."}, 29 | {Name: "role", Type: proto.ColumnType_STRING, Description: "Name of the role played by the Contact on this Account, such as Decision Maker, Approver, Buyer, and so on."}, 30 | 31 | // Other columns 32 | {Name: "created_by_id", Type: proto.ColumnType_STRING, Description: "Id of the user who created contact role record."}, 33 | {Name: "created_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date and time of the creation of the contact role record."}, 34 | {Name: "last_modified_by_id", Type: proto.ColumnType_STRING, Description: "Id of the user who most recently changed the contact role record."}, 35 | {Name: "last_modified_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date of most recent change in the contact role record."}, 36 | }), 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /salesforce/table_salesforce_object_permission.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" 7 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 8 | ) 9 | 10 | func SalesforceObjectPermission(ctx context.Context, dm dynamicMap, config salesforceConfig) *plugin.Table { 11 | tableName := "ObjectPermissions" 12 | return &plugin.Table{ 13 | Name: "salesforce_object_permission", 14 | Description: "Represents the enabled object permissions for the parent PermissionSet.", 15 | List: &plugin.ListConfig{ 16 | Hydrate: listSalesforceObjectsByTable(tableName, dm.salesforceColumns), 17 | KeyColumns: dm.keyColumns, 18 | }, 19 | Get: &plugin.GetConfig{ 20 | Hydrate: getSalesforceObjectbyID(tableName), 21 | KeyColumns: plugin.SingleColumn(checkNameScheme(config, dm.cols)), 22 | }, 23 | Columns: mergeTableColumns(ctx, config, dm.cols, []*plugin.Column{ 24 | // Top columns 25 | {Name: "id", Type: proto.ColumnType_STRING, Description: "The ObjectPermissions ID."}, 26 | {Name: "parent_id", Type: proto.ColumnType_STRING, Description: "The Id of this object's parent PermissionSet."}, 27 | {Name: "sobject_type", Type: proto.ColumnType_STRING, Description: "The object's API name. For example, Merchandise__c."}, 28 | 29 | // Other columns 30 | {Name: "permissions_create", Type: proto.ColumnType_BOOL, Description: "If true, users assigned to the parent PermissionSet can create records for this object. Requires PermissionsRead for the same object to be true."}, 31 | {Name: "permissions_delete", Type: proto.ColumnType_BOOL, Description: "If true, users assigned to the parent PermissionSet can delete records for this object. Requires PermissionsRead and PermissionsEdit for the same object to be true."}, 32 | {Name: "permissions_edit", Type: proto.ColumnType_BOOL, Description: "If true, users assigned to the parent PermissionSet can edit records for this object. Requires PermissionsRead for the same object to be true."}, 33 | {Name: "permissions_read", Type: proto.ColumnType_BOOL, Description: "If true, users assigned to the parent PermissionSet can view records for this object."}, 34 | {Name: "permissions_modify_all_records", Type: proto.ColumnType_BOOL, Description: "If true, users assigned to the parent PermissionSet can edit all records for this object, regardless of sharing settings. Requires PermissionsRead, PermissionsDelete, PermissionsEdit, and PermissionsViewAllRecords for the same object to be true."}, 35 | {Name: "permissions_view_all_records", Type: proto.ColumnType_BOOL, Description: "If true, users assigned to the parent PermissionSet can view all records for this object, regardless of sharing settings. Requires PermissionsRead for the same object to be true."}, 36 | }), 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /salesforce/table_salesforce_user.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" 7 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 8 | ) 9 | 10 | func SalesforceUser(ctx context.Context, dm dynamicMap, config salesforceConfig) *plugin.Table { 11 | tableName := "User" 12 | return &plugin.Table{ 13 | Name: "salesforce_user", 14 | Description: "Represents a user in organization.", 15 | List: &plugin.ListConfig{ 16 | Hydrate: listSalesforceObjectsByTable(tableName, dm.salesforceColumns), 17 | KeyColumns: dm.keyColumns, 18 | }, 19 | Get: &plugin.GetConfig{ 20 | Hydrate: getSalesforceObjectbyID(tableName), 21 | KeyColumns: plugin.SingleColumn(checkNameScheme(config, dm.cols)), 22 | }, 23 | Columns: mergeTableColumns(ctx, config, dm.cols, []*plugin.Column{ 24 | // Top columns 25 | {Name: "id", Type: proto.ColumnType_STRING, Description: "Unique identifier of the user in Salesforce."}, 26 | {Name: "alias", Type: proto.ColumnType_STRING, Description: "The user's alias. For example, jsmith."}, 27 | {Name: "username", Type: proto.ColumnType_STRING, Description: "Login name of the user."}, 28 | {Name: "name", Type: proto.ColumnType_STRING, Description: "Display name of the user."}, 29 | {Name: "email", Type: proto.ColumnType_STRING, Description: "The user's email address."}, 30 | {Name: "is_active", Type: proto.ColumnType_BOOL, Description: "Indicates whether the user has access to log in (true) or not (false)."}, 31 | 32 | // Other columns 33 | {Name: "account_id", Type: proto.ColumnType_STRING, Description: "ID of the Account associated with a Customer Portal user. This field is null for Salesforce users."}, 34 | {Name: "created_by_id", Type: proto.ColumnType_STRING, Description: "Id of the user who created the user including creation date and time."}, 35 | {Name: "department", Type: proto.ColumnType_STRING, Description: "The company department associated with the user."}, 36 | {Name: "employee_number", Type: proto.ColumnType_STRING, Description: "The user's employee number."}, 37 | {Name: "forecast_enabled", Type: proto.ColumnType_BOOL, Description: "Indicates whether the user is enabled as a forecast manager (true) or not (false)."}, 38 | {Name: "last_login_date", Type: proto.ColumnType_TIMESTAMP, Description: "The date and time when the user last successfully logged in. This value is updated if 60 seconds elapses since the user's last login."}, 39 | {Name: "last_modified_by_id", Type: proto.ColumnType_STRING, Description: "Id of the user who last changed the user fields, including modification date and time."}, 40 | {Name: "profile_id", Type: proto.ColumnType_STRING, Description: "ID of the user's Profile."}, 41 | {Name: "state", Type: proto.ColumnType_STRING, Description: "The state associated with the User."}, 42 | {Name: "user_type", Type: proto.ColumnType_STRING, Description: "The category of user license. Can be one of Standard, PowerPartner, CSPLitePortal, CustomerSuccess, PowerCustomerSuccess, CsnOnly, and Guest."}, 43 | }), 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /salesforce/table_salesforce_pricebook.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" 7 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 8 | ) 9 | 10 | func SalesforcePricebook(ctx context.Context, dm dynamicMap, config salesforceConfig) *plugin.Table { 11 | tableName := "Pricebook2" 12 | return &plugin.Table{ 13 | Name: "salesforce_pricebook", 14 | Description: "Represents a price book that contains the list of products that your org sells.", 15 | List: &plugin.ListConfig{ 16 | Hydrate: listSalesforceObjectsByTable(tableName, dm.salesforceColumns), 17 | KeyColumns: dm.keyColumns, 18 | }, 19 | Get: &plugin.GetConfig{ 20 | Hydrate: getSalesforceObjectbyID(tableName), 21 | KeyColumns: plugin.SingleColumn(checkNameScheme(config, dm.cols)), 22 | }, 23 | Columns: mergeTableColumns(ctx, config, dm.cols, []*plugin.Column{ 24 | // Top columns 25 | {Name: "id", Type: proto.ColumnType_STRING, Description: "Unique identifier of the product in pricebook."}, 26 | {Name: "name", Type: proto.ColumnType_STRING, Description: "The Price Book Name."}, 27 | {Name: "is_active", Type: proto.ColumnType_BOOL, Description: "Indicates whether the price book is active (true) or not (false)."}, 28 | 29 | // Other columns 30 | {Name: "created_by_id", Type: proto.ColumnType_STRING, Description: "The id of the user who created the price book."}, 31 | {Name: "created_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date and time of the creation of the price book record."}, 32 | {Name: "description", Type: proto.ColumnType_STRING, Description: "Description of the price book."}, 33 | {Name: "is_archived", Type: proto.ColumnType_BOOL, Description: "Describes whether the price book is archived. The default value is false."}, 34 | {Name: "is_deleted", Type: proto.ColumnType_BOOL, Description: "Indicates whether the price book has been archived (true) or not (false)."}, 35 | {Name: "is_standard", Type: proto.ColumnType_BOOL, Description: "Indicates whether the price book is the standard price book for the org (true) or not (false). Every org has one standard price book—all other price books are custom price books."}, 36 | {Name: "last_modified_by_id", Type: proto.ColumnType_STRING, Description: "Id of the user who most recently changed the product record."}, 37 | {Name: "last_modified_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date of most recent change in the product record."}, 38 | {Name: "last_referenced_date", Type: proto.ColumnType_TIMESTAMP, Description: "The timestamp for when the current user last viewed a record related to this record."}, 39 | {Name: "last_viewed_date", Type: proto.ColumnType_TIMESTAMP, Description: "The timestamp for when the current user last viewed this record. If this value is null, it's possible that this record was referenced (LastReferencedDate) and not viewed."}, 40 | {Name: "system_modstamp", Type: proto.ColumnType_STRING, Description: "The date and time when order record was last modified by a user or by an automated process."}, 41 | }), 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /salesforce/table_salesforce_lead.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" 7 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 8 | ) 9 | 10 | func SalesforceLead(ctx context.Context, dm dynamicMap, config salesforceConfig) *plugin.Table { 11 | tableName := "Lead" 12 | return &plugin.Table{ 13 | Name: "salesforce_lead", 14 | Description: "Represents a prospect or lead.", 15 | List: &plugin.ListConfig{ 16 | Hydrate: listSalesforceObjectsByTable(tableName, dm.salesforceColumns), 17 | KeyColumns: dm.keyColumns, 18 | }, 19 | Get: &plugin.GetConfig{ 20 | Hydrate: getSalesforceObjectbyID(tableName), 21 | KeyColumns: plugin.SingleColumn(checkNameScheme(config, dm.cols)), 22 | }, 23 | Columns: mergeTableColumns(ctx, config, dm.cols, []*plugin.Column{ 24 | // Top columns 25 | {Name: "id", Type: proto.ColumnType_STRING, Description: "Unique identifier of the lead in Salesforce."}, 26 | {Name: "email", Type: proto.ColumnType_STRING, Description: "The lead's email address."}, 27 | {Name: "is_converted", Type: proto.ColumnType_BOOL, Description: "Indicates whether the lead has been converted (true) or not (false)."}, 28 | {Name: "name", Type: proto.ColumnType_STRING, Description: "Name of the lead, as displayed on lead detail page."}, 29 | {Name: "phone", Type: proto.ColumnType_STRING, Description: "Lead's primary phone number."}, 30 | {Name: "status", Type: proto.ColumnType_STRING, Description: "Status of the lead, for example, Open, Contacted, Qualified."}, 31 | 32 | // Other columns 33 | {Name: "address", Type: proto.ColumnType_JSON, Description: "Street address for the lead."}, 34 | {Name: "annual_revenue", Type: proto.ColumnType_DOUBLE, Description: "Annual revenue for the lead's company."}, 35 | {Name: "company", Type: proto.ColumnType_STRING, Description: "The lead's company."}, 36 | {Name: "converted_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date on which this lead was converted."}, 37 | {Name: "created_by_id", Type: proto.ColumnType_STRING, Description: "Id of the user who created the lead."}, 38 | {Name: "created_date", Type: proto.ColumnType_TIMESTAMP, Description: "Creation date and time of the lead."}, 39 | {Name: "industry", Type: proto.ColumnType_STRING, Description: "Primary business of lead's company."}, 40 | {Name: "last_modified_by_id", Type: proto.ColumnType_STRING, Description: "Id of the user who last changed the lead record."}, 41 | {Name: "last_modified_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date and time of the last changes to lead record."}, 42 | {Name: "lead_source", Type: proto.ColumnType_STRING, Description: "Source of lead, for example, Advertisement, Partner, or Web."}, 43 | {Name: "number_of_employees", Type: proto.ColumnType_INT, Description: "Number of employees at the lead's company."}, 44 | {Name: "owner_id", Type: proto.ColumnType_STRING, Description: "Id of the assigned owner of the lead."}, 45 | {Name: "rating", Type: proto.ColumnType_STRING, Description: "Indicates value or prospect of the lead, for example, Hot, Warm, Cold."}, 46 | {Name: "website", Type: proto.ColumnType_STRING, Description: "URL of the lead's company's website."}, 47 | }), 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /salesforce/table_salesforce_permission_set.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" 7 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 8 | ) 9 | 10 | func SalesforcePermissionSet(ctx context.Context, dm dynamicMap, config salesforceConfig) *plugin.Table { 11 | tableName := "PermissionSet" 12 | return &plugin.Table{ 13 | Name: "salesforce_permission_set", 14 | Description: "Represents a set of permissions that's used to grant more access to one or more users without changing their profile or reassigning profiles.", 15 | List: &plugin.ListConfig{ 16 | Hydrate: listSalesforceObjectsByTable(tableName, dm.salesforceColumns), 17 | KeyColumns: dm.keyColumns, 18 | }, 19 | Get: &plugin.GetConfig{ 20 | Hydrate: getSalesforceObjectbyID(tableName), 21 | KeyColumns: plugin.SingleColumn(checkNameScheme(config, dm.cols)), 22 | }, 23 | Columns: mergeTableColumns(ctx, config, dm.cols, []*plugin.Column{ 24 | // Top columns 25 | {Name: "id", Type: proto.ColumnType_STRING, Description: "The unique id of the permission set."}, 26 | {Name: "name", Type: proto.ColumnType_STRING, Description: "The permission set unique name in the API."}, 27 | {Name: "description", Type: proto.ColumnType_STRING, Description: "The description of the permission set."}, 28 | {Name: "is_custom", Type: proto.ColumnType_BOOL, Description: "If true, the permission set is custom (created by an admin); if false, the permission set is standard and related to a specific permission set license."}, 29 | {Name: "created_date", Type: proto.ColumnType_TIMESTAMP, Description: "The Created Date."}, 30 | 31 | // Other columns 32 | {Name: "created_by_id", Type: proto.ColumnType_STRING, Description: "The contact id of the user who created this permission set."}, 33 | {Name: "has_activation_required", Type: proto.ColumnType_BOOL, Description: "Indicates whether the permission set requires an associated active session (true) or not (false)."}, 34 | {Name: "is_owned_by_profile", Type: proto.ColumnType_BOOL, Description: "If true, the permission set is owned by a profile."}, 35 | {Name: "label", Type: proto.ColumnType_STRING, Description: "The permission set label, which corresponds to Label in the user interface."}, 36 | {Name: "last_modified_by_id", Type: proto.ColumnType_STRING, Description: "The Last Modified By ID."}, 37 | {Name: "last_modified_date", Type: proto.ColumnType_TIMESTAMP, Description: "The Last Modified Date."}, 38 | {Name: "license_id", Type: proto.ColumnType_STRING, Description: "The ID of either the related PermissionSetLicense or UserLicense associated with this permission set."}, 39 | {Name: "namespace_prefix", Type: proto.ColumnType_STRING, Description: "The namespace prefix for a permission set that's been installed as part of a managed package. If the permission set isn't packaged or is part of an unmanaged package, this value is empty."}, 40 | {Name: "permission_set_group_id", Type: proto.ColumnType_STRING, Description: "If the permission set is owned by a permission set group, this field returns the ID of the permission set group."}, 41 | {Name: "profile_id", Type: proto.ColumnType_STRING, Description: "If the permission set is owned by a profile, this field contains the ID of the Profile."}, 42 | {Name: "system_modstamp", Type: proto.ColumnType_TIMESTAMP, Description: "The date and time when order record was last modified by a user or by an automated process."}, 43 | }), 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /salesforce/table_salesforce_product.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" 7 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 8 | ) 9 | 10 | func SalesforceProduct(ctx context.Context, dm dynamicMap, config salesforceConfig) *plugin.Table { 11 | tableName := "Product2" 12 | return &plugin.Table{ 13 | Name: "salesforce_product", 14 | Description: "Represents a product that org sells.", 15 | List: &plugin.ListConfig{ 16 | Hydrate: listSalesforceObjectsByTable(tableName, dm.salesforceColumns), 17 | KeyColumns: dm.keyColumns, 18 | }, 19 | Get: &plugin.GetConfig{ 20 | Hydrate: getSalesforceObjectbyID(tableName), 21 | KeyColumns: plugin.SingleColumn(checkNameScheme(config, dm.cols)), 22 | }, 23 | Columns: mergeTableColumns(ctx, config, dm.cols, []*plugin.Column{ 24 | // Top columns 25 | {Name: "id", Type: proto.ColumnType_STRING, Description: "Unique identifier of the product in Salesforce."}, 26 | {Name: "name", Type: proto.ColumnType_STRING, Description: "The product's name."}, 27 | {Name: "family", Type: proto.ColumnType_STRING, Description: "Name of the product family associated with this record."}, 28 | {Name: "product_code", Type: proto.ColumnType_STRING, Description: "The internal code or product number that you use to identify the product."}, 29 | {Name: "is_active", Type: proto.ColumnType_BOOL, Description: "Indicates that the product is ready for use in a price book, opportunity, or quote, and whether you can see the product in views."}, 30 | 31 | // Other columns 32 | {Name: "created_by_id", Type: proto.ColumnType_STRING, Description: "The id of the user who created the product record, with the date and time of creation."}, 33 | {Name: "created_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date and time of the creation of the product role record."}, 34 | {Name: "description", Type: proto.ColumnType_STRING, Description: "Description of the product."}, 35 | {Name: "display_url", Type: proto.ColumnType_STRING, Description: "URL leading to a specific version of a record in the linked external data source."}, 36 | {Name: "external_data_source_id", Type: proto.ColumnType_STRING, Description: "The id of the related external data source."}, 37 | {Name: "external_id", Type: proto.ColumnType_STRING, Description: "The unique identifier of a record in the linked external data source."}, 38 | {Name: "is_archived", Type: proto.ColumnType_BOOL, Description: "Describes whether the product is archived. The default value is false."}, 39 | {Name: "is_deleted", Type: proto.ColumnType_BOOL, Description: "Indicates whether the object has been moved to the Recycle Bin (true) or not (false)."}, 40 | {Name: "last_modified_by_id", Type: proto.ColumnType_STRING, Description: "Id of the user who most recently changed the product record."}, 41 | {Name: "last_modified_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date of most recent change in the product record."}, 42 | {Name: "last_referenced_date", Type: proto.ColumnType_TIMESTAMP, Description: "The timestamp when the current user last viewed product record."}, 43 | {Name: "last_viewed_date", Type: proto.ColumnType_TIMESTAMP, Description: "The timestamp when the current user last viewed this record. If this value is null, this record might only have been referenced (last_referenced_date) and not viewed by the current user."}, 44 | {Name: "quantity_unit_of_measure", Type: proto.ColumnType_STRING, Description: "Unit of the product—for example, kilograms, liters, or cases."}, 45 | {Name: "stock_keeping_unit", Type: proto.ColumnType_STRING, Description: "The product's SKU, which can be used with or in place of the Product Code field."}, 46 | {Name: "system_modstamp", Type: proto.ColumnType_STRING, Description: "The date and time when order record was last modified by a user or by an automated process."}, 47 | }), 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /docs/tables/salesforce_contact.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Steampipe Table: salesforce_contact - Query Salesforce Contacts using SQL" 3 | description: "Allows users to query Contacts in Salesforce, providing details such as contact name, email, phone number, and associated account information." 4 | --- 5 | 6 | # Table: salesforce_contact - Query Salesforce Contacts using SQL 7 | 8 | Salesforce Contacts is a feature within Salesforce CRM that allows businesses to store and manage information about their customers. It provides a centralized way to keep track of customer details, including their contact information, associated accounts, and any activities or opportunities related to them. Salesforce Contacts helps businesses stay informed about their customer base and maintain strong relationships with them. 9 | 10 | ## Table Usage Guide 11 | 12 | The `salesforce_contact` table provides insights into Contacts within Salesforce CRM. As a sales representative or a customer relationship manager, explore contact-specific details through this table, including name, email, phone number, and associated account information. Utilize it to uncover information about contacts, such as those who are associated with specific accounts, the activities related to them, and their communication details. 13 | 14 | **Important Notes** 15 | - If the `naming_convention` configuration argument is set to `api_native`, please see [API Native Examples](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account#api_native_examples). 16 | 17 | ## Examples 18 | 19 | ### Basic info 20 | Explore the basic information of your Salesforce contacts to understand their source, department, and role within their organization. This can help in tailoring communication and marketing strategies to each contact. 21 | 22 | ```sql+postgres 23 | select 24 | id, 25 | name, 26 | account_id, 27 | email, 28 | lead_source, 29 | title, 30 | department 31 | from 32 | salesforce_contact; 33 | ``` 34 | 35 | ```sql+sqlite 36 | select 37 | id, 38 | name, 39 | account_id, 40 | email, 41 | lead_source, 42 | title, 43 | department 44 | from 45 | salesforce_contact; 46 | ``` 47 | 48 | ## API Native Examples 49 | 50 | If the `naming_convention` config argument is set to `api_native`, the table and column names will match Salesforce naming conventions. 51 | 52 | ### Basic info (with API Native naming convention) 53 | Discover the segments that allow you to gain insights into your contact list, such as identifying the associated account and department for each contact, without delving into overly technical details. 54 | 55 | ```sql+postgres 56 | select 57 | "ID", 58 | "Name", 59 | "AccountID", 60 | "Email", 61 | "Department" 62 | from 63 | "Contact"; 64 | ``` 65 | 66 | ```sql+sqlite 67 | select 68 | "ID", 69 | "Name", 70 | "AccountID", 71 | "Email", 72 | "Department" 73 | from 74 | "Contact"; 75 | ``` 76 | 77 | ### List deleted contacts 78 | Uncover the details of contacts that have been deleted from your database. This can be useful for auditing purposes or for retrieving lost information. 79 | 80 | ```sql+postgres 81 | select 82 | "ID", 83 | "Name", 84 | "AccountID", 85 | "Email", 86 | "Department" 87 | from 88 | "Contact" 89 | where 90 | "IsDeleted"; 91 | ``` 92 | 93 | ```sql+sqlite 94 | select 95 | "ID", 96 | "Name", 97 | "AccountID", 98 | "Email", 99 | "Department" 100 | from 101 | "Contact" 102 | where 103 | "IsDeleted"; 104 | ``` 105 | 106 | ### Show contacts created in last 30 days 107 | Explore which contacts have been added within the past month. This can help you keep track of recent additions and ensure that no new contacts have been missed. 108 | 109 | ```sql+postgres 110 | select 111 | "ID", 112 | "Name", 113 | "AccountID", 114 | "Email", 115 | "Department" 116 | from 117 | "Contact" 118 | where 119 | "CreatedDate" <= now() - interval '30' day; 120 | ``` 121 | 122 | ```sql+sqlite 123 | select 124 | "ID", 125 | "Name", 126 | "AccountID", 127 | "Email", 128 | "Department" 129 | from 130 | "Contact" 131 | where 132 | "CreatedDate" <= datetime('now', '-30 day'); 133 | ``` -------------------------------------------------------------------------------- /docs/tables/salesforce_asset.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Steampipe Table: salesforce_asset - Query Salesforce Assets using SQL" 3 | description: "Allows users to query Assets in Salesforce, providing detailed information about assets associated with a particular account, such as purchase date, asset value, and asset status." 4 | --- 5 | 6 | # Table: salesforce_asset - Query Salesforce Assets using SQL 7 | 8 | Salesforce Assets are items that a company has sold, such as products or services. These assets are associated with a customer's account and can be used to track items like warranty or service information. Assets in Salesforce provide a comprehensive view of customers' purchased products, helping businesses understand their customers' needs and provide better service. 9 | 10 | ## Table Usage Guide 11 | 12 | The `salesforce_asset` table enables users to gain insights into the assets associated with specific accounts in Salesforce. As a sales or customer service professional, you can utilize this table to track detailed information about sold products or services, including their purchase dates, values, and statuses. This information can be beneficial in understanding customer trends, managing warranties, and improving overall customer service. 13 | 14 | **Important Notes** 15 | - If the `naming_convention` configuration argument is set to `api_native`, please see [API Native Examples](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account#api_native_examples). 16 | 17 | ## Examples 18 | 19 | ### Basic info 20 | This example helps you understand the basic details of your assets in Salesforce, such as their ID, name, price, status, and quantity. It's useful for getting a quick overview of your assets and their associated contacts, which can aid in tracking asset performance and managing resources. 21 | 22 | ```sql+postgres 23 | select 24 | id, 25 | name, 26 | price, 27 | status, 28 | asset_level, 29 | contact_id, 30 | quantity 31 | from 32 | salesforce_asset; 33 | ``` 34 | 35 | ```sql+sqlite 36 | select 37 | id, 38 | name, 39 | price, 40 | status, 41 | asset_level, 42 | contact_id, 43 | quantity 44 | from 45 | salesforce_asset; 46 | ``` 47 | 48 | ## API Native Examples 49 | 50 | If the `naming_convention` config argument is set to `api_native`, the table and column names will match Salesforce naming conventions. 51 | 52 | ### Basic info (with API Native naming convention) 53 | Determine the areas in which your assets are allocated by assessing their price, quantity, and status. This can help you manage your resources more effectively and identify areas for potential improvement. 54 | 55 | ```sql+postgres 56 | select 57 | "ID", 58 | "Name", 59 | "Price", 60 | "Status", 61 | "Quantity" 62 | from 63 | "Asset"; 64 | ``` 65 | 66 | ```sql+sqlite 67 | select 68 | "ID", 69 | "Name", 70 | "Price", 71 | "Status", 72 | "Quantity" 73 | from 74 | "Asset"; 75 | ``` 76 | 77 | ### List shipped assets 78 | Explore which assets have been shipped to manage inventory and ensure accurate tracking of asset movement. This is particularly useful for businesses to keep track of their resources and improve their asset management strategies. 79 | 80 | ```sql+postgres 81 | select 82 | "ID", 83 | "Name", 84 | "Price", 85 | "Status", 86 | "Quantity" 87 | from 88 | "Asset" 89 | where 90 | "Status" = 'Shipped'; 91 | ``` 92 | 93 | ```sql+sqlite 94 | select 95 | "ID", 96 | "Name", 97 | "Price", 98 | "Status", 99 | "Quantity" 100 | from 101 | "Asset" 102 | where 103 | "Status" = 'Shipped'; 104 | ``` 105 | 106 | ### List internal assets 107 | Analyze your company's internal assets to gain insights into their status, quantity, and value. This can help in better resource allocation and financial planning. 108 | 109 | ```sql+postgres 110 | select 111 | "ID", 112 | "Name", 113 | "Price", 114 | "Status", 115 | "Quantity" 116 | from 117 | "Asset" 118 | where 119 | "IsInternal"; 120 | ``` 121 | 122 | ```sql+sqlite 123 | select 124 | "ID", 125 | "Name", 126 | "Price", 127 | "Status", 128 | "Quantity" 129 | from 130 | "Asset" 131 | where 132 | "IsInternal"; 133 | ``` -------------------------------------------------------------------------------- /salesforce/table_salesforce_account.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" 7 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 8 | ) 9 | 10 | func SalesforceAccount(ctx context.Context, dm dynamicMap, config salesforceConfig) *plugin.Table { 11 | tableName := "Account" 12 | return &plugin.Table{ 13 | Name: "salesforce_account", 14 | Description: "Represents an individual account, which is an organization or person involved with business (such as customers, competitors, and partners).", 15 | List: &plugin.ListConfig{ 16 | Hydrate: listSalesforceObjectsByTable(tableName, dm.salesforceColumns), 17 | KeyColumns: dm.keyColumns, 18 | }, 19 | Get: &plugin.GetConfig{ 20 | Hydrate: getSalesforceObjectbyID(tableName), 21 | KeyColumns: plugin.SingleColumn(checkNameScheme(config, dm.cols)), 22 | }, 23 | Columns: mergeTableColumns(ctx, config, dm.cols, []*plugin.Column{ 24 | // Top columns 25 | {Name: "id", Type: proto.ColumnType_STRING, Description: "Unique identifier of the account in Salesforce."}, 26 | {Name: "name", Type: proto.ColumnType_STRING, Description: "Name of the account."}, 27 | {Name: "annual_revenue", Type: proto.ColumnType_DOUBLE, Description: "Estimated annual revenue of the account."}, 28 | {Name: "industry", Type: proto.ColumnType_STRING, Description: "Primary business of account."}, 29 | {Name: "owner_id", Type: proto.ColumnType_STRING, Description: "The ID of the user who currently owns this account. Default value is the user logged in to the API to perform the create."}, 30 | {Name: "type", Type: proto.ColumnType_STRING, Description: "Type of account, for example, Customer, Competitor, or Partner."}, 31 | 32 | // Other columns 33 | {Name: "account_source", Type: proto.ColumnType_STRING, Description: "The source of the account record. For example, Advertisement, Data.com, or Trade Show."}, 34 | {Name: "clean_status", Type: proto.ColumnType_STRING, Description: "Indicates the record's clean status as compared with Data.com. Values are: Matched, Different,Acknowledged,NotFound,Inactive,Pending, SelectMatch, or Skipped."}, 35 | {Name: "created_by_id", Type: proto.ColumnType_STRING, Description: "The id of the user who created the account."}, 36 | {Name: "created_date", Type: proto.ColumnType_TIMESTAMP, Description: "The creation date and time of the account."}, 37 | {Name: "description", Type: proto.ColumnType_STRING, Description: "Text description of the account."}, 38 | {Name: "is_deleted", Type: proto.ColumnType_BOOL, Description: "Indicates whether the object has been moved to the Recycle Bin (true) or not (false)."}, 39 | {Name: "last_modified_by_id", Type: proto.ColumnType_STRING, Description: "The id of the user who last changed the contact fields, including modification date and time."}, 40 | {Name: "last_modified_date", Type: proto.ColumnType_TIMESTAMP, Description: "The date and time of last modification to account."}, 41 | {Name: "number_of_employees", Type: proto.ColumnType_DOUBLE, Description: "Number of employees working at the company represented by this account."}, 42 | {Name: "ownership", Type: proto.ColumnType_STRING, Description: "Ownership type for the account, for example Private, Public, or Subsidiary."}, 43 | {Name: "phone", Type: proto.ColumnType_STRING, Description: "The contact's primary phone number."}, 44 | {Name: "rating", Type: proto.ColumnType_STRING, Description: "The account's prospect rating, for example Hot, Warm, or Cold."}, 45 | {Name: "sic", Type: proto.ColumnType_STRING, Description: "Standard Industrial Classification code of the company's main business categorization, for example, 57340 for Electronics."}, 46 | {Name: "ticker_symbol", Type: proto.ColumnType_STRING, Description: "The stock market symbol for this account."}, 47 | {Name: "tradestyle", Type: proto.ColumnType_STRING, Description: "A name, different from its legal name, that an org may use for conducting business. Similar to “Doing business as” or \"DBA\"."}, 48 | {Name: "website", Type: proto.ColumnType_STRING, Description: "The website of this account, for example, www.acme.com."}, 49 | 50 | // JSON columns 51 | {Name: "billing_address", Type: proto.ColumnType_JSON, Description: "The billing adress of the account."}, 52 | {Name: "shipping_address", Type: proto.ColumnType_JSON, Description: "The shipping adress of the account."}, 53 | }), 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /salesforce/table_salesforce_object.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "strings" 7 | 8 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 9 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform" 10 | ) 11 | 12 | //// LIST HYDRATE FUNCTION 13 | 14 | func listSalesforceObjectsByTable(tableName string, salesforceCols map[string]string) func(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { 15 | return func(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { 16 | client, err := connect(ctx, d) 17 | if err != nil { 18 | plugin.Logger(ctx).Error("salesforce.listSalesforceObjectsByTable", "connection error", err) 19 | return nil, err 20 | } 21 | if client == nil { 22 | plugin.Logger(ctx).Error("salesforce.listSalesforceObjectsByTable", "client_not_found: unable to generate dynamic tables because of invalid steampipe salesforce configuration", err) 23 | return nil, fmt.Errorf("salesforce.listSalesforceObjectsByTable: client_not_found, unable to query table %s because of invalid steampipe salesforce configuration", d.Table.Name) 24 | } 25 | 26 | query := generateQuery(d.Table.Columns, tableName) 27 | condition := buildQueryFromQuals(d.Quals, d.Table.Columns, salesforceCols) 28 | if condition != "" { 29 | query = fmt.Sprintf("%s where %s", query, condition) 30 | plugin.Logger(ctx).Debug("salesforce.listSalesforceObjectsByTable", "table_name", d.Table.Name, "query_condition", condition) 31 | } 32 | 33 | for { 34 | result, err := client.Query(query) 35 | if err != nil { 36 | plugin.Logger(ctx).Error("salesforce.listSalesforceObjectsByTable", "query error", err) 37 | return nil, err 38 | } 39 | 40 | AccountList := new([]map[string]interface{}) 41 | err = decodeQueryResult(ctx, result.Records, AccountList) 42 | if err != nil { 43 | plugin.Logger(ctx).Error("salesforce.listSalesforceObjectsByTable", "results decoding error", err) 44 | return nil, err 45 | } 46 | 47 | for _, account := range *AccountList { 48 | d.StreamListItem(ctx, account) 49 | } 50 | 51 | // Paging 52 | if result.Done { 53 | break 54 | } else { 55 | query = result.NextRecordsURL 56 | } 57 | } 58 | 59 | return nil, nil 60 | } 61 | } 62 | 63 | //// GET HYDRATE FUNCTION 64 | 65 | func getSalesforceObjectbyID(tableName string) func(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { 66 | return func(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { 67 | plugin.Logger(ctx).Info("salesforce.getSalesforceObjectbyID", "Table_Name", d.Table.Name) 68 | config := GetConfig(d.Connection) 69 | var id string 70 | if config.NamingConvention != nil && *config.NamingConvention == "api_native" { 71 | id = d.EqualsQualString("Id") 72 | } else { 73 | id = d.EqualsQualString("id") 74 | } 75 | if strings.TrimSpace(id) == "" { 76 | return nil, nil 77 | } 78 | 79 | client, err := connect(ctx, d) 80 | if err != nil { 81 | plugin.Logger(ctx).Error("salesforce.getSalesforceObjectbyID", "connection error", err) 82 | return nil, err 83 | } 84 | if client == nil { 85 | plugin.Logger(ctx).Error("salesforce.getSalesforceObjectbyID", "client_not_found: unable to generate dynamic tables because of invalid steampipe salesforce configuration", err) 86 | return nil, fmt.Errorf("salesforce.getSalesforceObjectbyID: client_not_found, unable to query table %s because of invalid steampipe salesforce configuration", d.Table.Name) 87 | } 88 | 89 | obj := client.SObject(tableName).Get(id) 90 | if obj == nil { 91 | // Object doesn't exist, handle the error 92 | plugin.Logger(ctx).Warn("salesforce.getSalesforceObjectbyID", fmt.Sprintf("%s with id \"%s\" not found", tableName, id)) 93 | return nil, nil 94 | } 95 | 96 | object := new(map[string]interface{}) 97 | err = decodeQueryResult(ctx, obj, object) 98 | if err != nil { 99 | plugin.Logger(ctx).Error("salesforce.getSalesforceObjectbyID", "result decoding error", err) 100 | return nil, err 101 | } 102 | 103 | return *object, nil 104 | } 105 | } 106 | 107 | //// TRANSFORM FUNCTION 108 | 109 | func getFieldFromSObjectMap(ctx context.Context, d *transform.TransformData) (interface{}, error) { 110 | param := d.Param.(string) 111 | ls := d.HydrateItem.(map[string]interface{}) 112 | return ls[param], nil 113 | } 114 | 115 | func getFieldFromSObjectMapByColumnName(ctx context.Context, d *transform.TransformData) (interface{}, error) { 116 | salesforceColumnName := getSalesforceColumnName(d.ColumnName) 117 | ls := d.HydrateItem.(map[string]interface{}) 118 | return ls[salesforceColumnName], nil 119 | } 120 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![image](https://hub.steampipe.io/images/plugins/turbot/salesforce-social-graphic.png) 2 | 3 | # Salesforce Plugin for Steampipe 4 | 5 | Use SQL to query infrastructure accounts, users, oppurtinities and more from your Salesforce instance. 6 | 7 | - **[Get started →](https://hub.steampipe.io/plugins/turbot/salesforce)** 8 | - Documentation: [Table definitions & examples](https://hub.steampipe.io/plugins/turbot/salesforce/tables) 9 | - Community: [Join #steampipe on Slack →](https://turbot.com/community/join) 10 | - Get involved: [Issues](https://github.com/turbot/steampipe-plugin-salesforce/issues) 11 | 12 | ## Quick start 13 | 14 | Install the plugin with [Steampipe](https://steampipe.io): 15 | 16 | ```shell 17 | steampipe plugin install salesforce 18 | ``` 19 | 20 | Configure your [credentials](https://hub.steampipe.io/plugins/turbot/salesforce#credentials) and [config file](https://hub.steampipe.io/plugins/turbot/salesforce#configuration). 21 | 22 | Run a query: 23 | 24 | ```sql 25 | select 26 | name, 27 | amount, 28 | close_date 29 | from 30 | salesforce_opportunity 31 | where 32 | is_won; 33 | ``` 34 | 35 | ## Engines 36 | 37 | This plugin is available for the following engines: 38 | 39 | | Engine | Description 40 | |---------------|------------------------------------------ 41 | | [Steampipe](https://steampipe.io/docs) | The Steampipe CLI exposes APIs and services as a high-performance relational database, giving you the ability to write SQL-based queries to explore dynamic data. Mods extend Steampipe's capabilities with dashboards, reports, and controls built with simple HCL. The Steampipe CLI is a turnkey solution that includes its own Postgres database, plugin management, and mod support. 42 | | [Postgres FDW](https://steampipe.io/docs/steampipe_postgres/overview) | Steampipe Postgres FDWs are native Postgres Foreign Data Wrappers that translate APIs to foreign tables. Unlike Steampipe CLI, which ships with its own Postgres server instance, the Steampipe Postgres FDWs can be installed in any supported Postgres database version. 43 | | [SQLite Extension](https://steampipe.io/docs/steampipe_sqlite/overview) | Steampipe SQLite Extensions provide SQLite virtual tables that translate your queries into API calls, transparently fetching information from your API or service as you request it. 44 | | [Export](https://steampipe.io/docs/steampipe_export/overview) | Steampipe Plugin Exporters provide a flexible mechanism for exporting information from cloud services and APIs. Each exporter is a stand-alone binary that allows you to extract data using Steampipe plugins without a database. 45 | | [Turbot Pipes](https://turbot.com/pipes/docs) | Turbot Pipes is the only intelligence, automation & security platform built specifically for DevOps. Pipes provide hosted Steampipe database instances, shared dashboards, snapshots, and more. 46 | 47 | ## Developing 48 | 49 | Prerequisites: 50 | 51 | - [Steampipe](https://steampipe.io/downloads) 52 | - [Golang](https://golang.org/doc/install) 53 | 54 | Clone: 55 | 56 | ```sh 57 | git clone https://github.com/turbot/steampipe-plugin-salesforce.git 58 | cd steampipe-plugin-salesforce 59 | ``` 60 | 61 | Build, which automatically installs the new version to your `~/.steampipe/plugins` directory: 62 | 63 | ```sh 64 | make 65 | ``` 66 | 67 | Configure the plugin: 68 | 69 | ```sh 70 | cp config/* ~/.steampipe/config 71 | vi ~/.steampipe/config/salesforce.spc 72 | ``` 73 | 74 | Try it! 75 | 76 | ```shell 77 | steampipe query 78 | > .inspect salesforce 79 | ``` 80 | 81 | Further reading: 82 | 83 | - [Writing plugins](https://steampipe.io/docs/develop/writing-plugins) 84 | - [Writing your first table](https://steampipe.io/docs/develop/writing-your-first-table) 85 | 86 | ## Open Source & Contributing 87 | 88 | This repository is published under the [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0) (source code) and [CC BY-NC-ND](https://creativecommons.org/licenses/by-nc-nd/2.0/) (docs) licenses. Please see our [code of conduct](https://github.com/turbot/.github/blob/main/CODE_OF_CONDUCT.md). We look forward to collaborating with you! 89 | 90 | [Steampipe](https://steampipe.io) is a product produced from this open source software, exclusively by [Turbot HQ, Inc](https://turbot.com). It is distributed under our commercial terms. Others are allowed to make their own distribution of the software, but cannot use any of the Turbot trademarks, cloud services, etc. You can learn more in our [Open Source FAQ](https://turbot.com/open-source). 91 | 92 | ## Get Involved 93 | 94 | **[Join #steampipe on Slack →](https://turbot.com/community/join)** 95 | 96 | Want to help but don't know where to start? Pick up one of the `help wanted` issues: 97 | 98 | - [Steampipe](https://github.com/turbot/steampipe/labels/help%20wanted) 99 | - [Salesforce Plugin](https://github.com/turbot/steampipe-plugin-salesforce/labels/help%20wanted) 100 | -------------------------------------------------------------------------------- /salesforce/table_salesforce_asset.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" 7 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 8 | ) 9 | 10 | func SalesforceAsset(ctx context.Context, dm dynamicMap, config salesforceConfig) *plugin.Table { 11 | tableName := "Asset" 12 | return &plugin.Table{ 13 | Name: "salesforce_asset", 14 | Description: "Represents an item of commercial value, such as a product sold by your company or a competitor, that a customer has purchased and installed.", 15 | List: &plugin.ListConfig{ 16 | Hydrate: listSalesforceObjectsByTable(tableName, dm.salesforceColumns), 17 | KeyColumns: dm.keyColumns, 18 | }, 19 | Get: &plugin.GetConfig{ 20 | Hydrate: getSalesforceObjectbyID(tableName), 21 | KeyColumns: plugin.SingleColumn(checkNameScheme(config, dm.cols)), 22 | }, 23 | Columns: mergeTableColumns(ctx, config, dm.cols, []*plugin.Column{ 24 | // Top columns 25 | {Name: "id", Type: proto.ColumnType_STRING, Description: "Unique identifier of the product in asset."}, 26 | {Name: "name", Type: proto.ColumnType_STRING, Description: "Name of the asset."}, 27 | {Name: "account_id", Type: proto.ColumnType_STRING, Description: "ID of the Account associated with this asset."}, 28 | {Name: "asset_level", Type: proto.ColumnType_INT, Description: "The asset's position in an asset hierarchy. If the asset has no parent or child assets, its level is 1."}, 29 | {Name: "contact_id", Type: proto.ColumnType_STRING, Description: "ID of the Contact associated with this asset."}, 30 | 31 | // Other columns 32 | {Name: "asset_provided_by_id", Type: proto.ColumnType_STRING, Description: "The account that provided the asset, typically a manufacturer."}, 33 | {Name: "asset_serviced_by_id", Type: proto.ColumnType_STRING, Description: "The account in charge of servicing the asset."}, 34 | {Name: "created_by_id", Type: proto.ColumnType_STRING, Description: "The id of the user who created the asset."}, 35 | {Name: "created_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date and time of the creation of the price book record."}, 36 | {Name: "description", Type: proto.ColumnType_STRING, Description: "Description of the asset."}, 37 | {Name: "install_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date when the asset was installed."}, 38 | {Name: "is_competitor_product", Type: proto.ColumnType_BOOL, Description: "Indicates whether this Asset represents a product sold by a competitor (true) or not (false)."}, 39 | {Name: "is_deleted", Type: proto.ColumnType_BOOL, Description: "The Deleted."}, 40 | {Name: "is_internal", Type: proto.ColumnType_BOOL, Description: "Indicates that the asset is produced or used internally (true) or not (false). Default value is false."}, 41 | {Name: "last_modified_by_id", Type: proto.ColumnType_STRING, Description: "The Last Modified By ID."}, 42 | {Name: "last_modified_date", Type: proto.ColumnType_TIMESTAMP, Description: "The Last Modified Date."}, 43 | {Name: "last_referenced_date", Type: proto.ColumnType_TIMESTAMP, Description: "The date and time that the asset was last modified."}, 44 | {Name: "last_viewed_date", Type: proto.ColumnType_TIMESTAMP, Description: "The date and time that the asset was last viewed."}, 45 | {Name: "owner_id", Type: proto.ColumnType_STRING, Description: "The asset's owner. By default, the asset owner is the user who created the asset record."}, 46 | {Name: "parent_id", Type: proto.ColumnType_STRING, Description: "The asset's parent asset."}, 47 | {Name: "price", Type: proto.ColumnType_DOUBLE, Description: "Price paid for this asset."}, 48 | {Name: "product_2_id", Type: proto.ColumnType_STRING, Description: "ID of the Product2 associated with this asset. Must be a valid Product2 ID."}, 49 | {Name: "product_code", Type: proto.ColumnType_STRING, Description: "The product code of the related product."}, 50 | {Name: "purchase_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date on which this asset was purchased."}, 51 | {Name: "quantity", Type: proto.ColumnType_DOUBLE, Description: "Quantity purchased or installed."}, 52 | {Name: "root_asset_id", Type: proto.ColumnType_STRING, Description: " The top-level asset in an asset hierarchy. Depending on where an asset lies in the hierarchy, its root could be the same as its parent."}, 53 | {Name: "serial_number", Type: proto.ColumnType_STRING, Description: "Serial number for this asset."}, 54 | {Name: "status", Type: proto.ColumnType_STRING, Description: "Customizable picklist of values. The default picklist includes the following values: Purchased, Shipped, Installed, Registered, Obsolete."}, 55 | {Name: "stock_keeping_unit", Type: proto.ColumnType_STRING, Description: "The SKU assigned to the related product."}, 56 | {Name: "system_modstamp", Type: proto.ColumnType_TIMESTAMP, Description: "The System Modstamp."}, 57 | {Name: "usage_end_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date when usage for this asset ends or expires."}, 58 | }), 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /docs/tables/salesforce_order.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Steampipe Table: salesforce_order - Query Salesforce Orders using SQL" 3 | description: "Allows users to query Salesforce Orders, specifically the details of all orders, providing insights into order data and related patterns." 4 | --- 5 | 6 | # Table: salesforce_order - Query Salesforce Orders using SQL 7 | 8 | Salesforce Orders is a feature within Salesforce that allows businesses to manage and track customer orders. It provides a comprehensive view of all orders, including their details, status, and associated accounts. Salesforce Orders helps businesses streamline their order management process, ensuring efficient and effective customer service. 9 | 10 | ## Table Usage Guide 11 | 12 | The `salesforce_order` table provides insights into Order data within Salesforce. As a Sales or Customer Service representative, explore order-specific details through this table, including order number, status, account details, and associated metadata. Utilize it to uncover information about orders, such as those pending, completed, or associated with specific accounts, aiding in efficient order management and customer service. 13 | 14 | **Important Notes** 15 | - If the `naming_convention` configuration argument is set to `api_native`, please see [API Native Examples](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account#api_native_examples). 16 | 17 | ## Examples 18 | 19 | ### Basic info 20 | Explore the sales orders in Salesforce to analyze their status and total amount. This can be useful for assessing the overall sales performance and identifying any unusual order patterns. 21 | 22 | ```sql+postgres 23 | select 24 | id, 25 | name, 26 | account_id, 27 | order_number, 28 | status, 29 | total_amount, 30 | type 31 | from 32 | salesforce_order; 33 | ``` 34 | 35 | ```sql+sqlite 36 | select 37 | id, 38 | name, 39 | account_id, 40 | order_number, 41 | status, 42 | total_amount, 43 | type 44 | from 45 | salesforce_order; 46 | ``` 47 | 48 | ### List number of orders by status 49 | Determine the distribution of order statuses to gain insights into business performance. This can help identify areas that require attention, such as unfulfilled orders or returns. 50 | 51 | ```sql+postgres 52 | select 53 | count(*), 54 | status 55 | from 56 | salesforce_order 57 | group by 58 | status; 59 | ``` 60 | 61 | ```sql+sqlite 62 | select 63 | count(*), 64 | status 65 | from 66 | salesforce_order 67 | group by 68 | status; 69 | ``` 70 | 71 | ## API Native Examples 72 | 73 | If the `naming_convention` config argument is set to `api_native`, the table and column names will match Salesforce naming conventions. 74 | 75 | ### Basic info (with API Native naming convention) 76 | Explore which orders have a specific status or type to gain insights into overall sales performance and identify potential areas for improvement. 77 | 78 | ```sql+postgres 79 | select 80 | "ID", 81 | "Name", 82 | "AccountID", 83 | "OrderNumber", 84 | "Status", 85 | "TotalAmount", 86 | "Type" 87 | from 88 | "Order"; 89 | ``` 90 | 91 | ```sql+sqlite 92 | select 93 | "ID", 94 | "Name", 95 | "AccountID", 96 | "OrderNumber", 97 | "Status", 98 | "TotalAmount", 99 | "Type" 100 | from 101 | "Order"; 102 | ``` 103 | 104 | ### List number of orders by status (with API Native naming convention) 105 | Analyze the distribution of order statuses to better understand your business operations and customer behavior patterns. 106 | 107 | ```sql+postgres 108 | select 109 | count(*), 110 | "Status" 111 | from 112 | "Order" 113 | group by 114 | "Status"; 115 | ``` 116 | 117 | ```sql+sqlite 118 | select 119 | count(*), 120 | "Status" 121 | from 122 | "Order" 123 | group by 124 | "Status"; 125 | ``` 126 | 127 | ### List draft orders 128 | Explore which orders are still in the draft stage to understand their status and manage them effectively. This is useful for tracking uncompleted transactions and identifying potential areas for follow-up or cancellation. 129 | 130 | ```sql+postgres 131 | select 132 | "ID", 133 | "Name", 134 | "AccountID", 135 | "OrderNumber", 136 | "Status", 137 | "TotalAmount", 138 | "Type" 139 | from 140 | "Order" 141 | where 142 | "Status" = 'Draft'; 143 | ``` 144 | 145 | ```sql+sqlite 146 | select 147 | "ID", 148 | "Name", 149 | "AccountID", 150 | "OrderNumber", 151 | "Status", 152 | "TotalAmount", 153 | "Type" 154 | from 155 | "Order" 156 | where 157 | "Status" = 'Draft'; 158 | ``` 159 | 160 | ### List deleted orders 161 | Explore which orders have been deleted to maintain accurate records and ensure proper account management. This aids in tracking potential errors or fraudulent activities. 162 | 163 | ```sql+postgres 164 | select 165 | "ID", 166 | "Name", 167 | "AccountID", 168 | "OrderNumber", 169 | "Status", 170 | "TotalAmount", 171 | "Type" 172 | from 173 | "Order" 174 | where 175 | "IsDeleted"; 176 | ``` 177 | 178 | ```sql+sqlite 179 | select 180 | "ID", 181 | "Name", 182 | "AccountID", 183 | "OrderNumber", 184 | "Status", 185 | "TotalAmount", 186 | "Type" 187 | from 188 | "Order" 189 | where 190 | "IsDeleted"; 191 | ``` -------------------------------------------------------------------------------- /salesforce/table_salesforce_contract.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" 7 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 8 | ) 9 | 10 | func SalesforceContract(ctx context.Context, dm dynamicMap, config salesforceConfig) *plugin.Table { 11 | tableName := "Contract" 12 | return &plugin.Table{ 13 | Name: "salesforce_contract", 14 | Description: "Represents a contract (a business agreement) associated with an Account.", 15 | List: &plugin.ListConfig{ 16 | Hydrate: listSalesforceObjectsByTable(tableName, dm.salesforceColumns), 17 | KeyColumns: dm.keyColumns, 18 | }, 19 | Get: &plugin.GetConfig{ 20 | Hydrate: getSalesforceObjectbyID(tableName), 21 | KeyColumns: plugin.SingleColumn(checkNameScheme(config, dm.cols)), 22 | }, 23 | Columns: mergeTableColumns(ctx, config, dm.cols, []*plugin.Column{ 24 | // Top columns 25 | {Name: "id", Type: proto.ColumnType_STRING, Description: "Unique identifier of the contract in Salesforce."}, 26 | {Name: "account_id", Type: proto.ColumnType_STRING, Description: "ID of the Account associated with this contract."}, 27 | {Name: "contract_number", Type: proto.ColumnType_STRING, Description: "Number of the contract."}, 28 | {Name: "contract_term", Type: proto.ColumnType_INT, Description: "Number of months that the contract is valid."}, 29 | {Name: "end_date", Type: proto.ColumnType_TIMESTAMP, Description: "Calculated end date of the contract. This value is calculated by adding the ContractTerm to the start_date."}, 30 | {Name: "owner_id", Type: proto.ColumnType_STRING, Description: "ID of the user who owns the contract."}, 31 | {Name: "start_date", Type: proto.ColumnType_TIMESTAMP, Description: "Start date for this contract."}, 32 | {Name: "status", Type: proto.ColumnType_STRING, Description: "The picklist of values that indicate order status. A contract can be Draft, InApproval, or Activated."}, 33 | 34 | // Other columns 35 | {Name: "activated_by_id", Type: proto.ColumnType_STRING, Description: "ID of the User who activated this contract."}, 36 | {Name: "activated_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date and time when this contract was activated."}, 37 | {Name: "billing_address", Type: proto.ColumnType_JSON, Description: "Billing address of the account."}, 38 | {Name: "company_signed_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date on which the contract was signed by organization."}, 39 | {Name: "company_signed_id", Type: proto.ColumnType_STRING, Description: "ID of the User who signed the contract."}, 40 | {Name: "created_by_id", Type: proto.ColumnType_STRING, Description: "Id of the user who created the contract record."}, 41 | {Name: "created_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date and time when contract record was created."}, 42 | {Name: "customer_signed_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date on which the customer signed the contract."}, 43 | {Name: "customer_signed_id", Type: proto.ColumnType_STRING, Description: "ID of the Contact who signed this contract."}, 44 | {Name: "customer_signed_title", Type: proto.ColumnType_STRING, Description: "Title of the contact who signed the contract."}, 45 | {Name: "description", Type: proto.ColumnType_STRING, Description: "Statement describing the contract."}, 46 | {Name: "is_deleted", Type: proto.ColumnType_BOOL, Description: "Indicates whether the object has been moved to the Recycle Bin (true) or not (false)."}, 47 | {Name: "last_activity_date", Type: proto.ColumnType_TIMESTAMP, Description: "Value is one of the following, whichever is the most recent. a) Due date of the most recent event logged against the record. b) Due date of the most recently closed task associated with the record."}, 48 | {Name: "last_approved_date", Type: proto.ColumnType_TIMESTAMP, Description: "Last date the contract was approved."}, 49 | {Name: "last_modified_by_id", Type: proto.ColumnType_STRING, Description: "The id of user who most recently changed the contract record."}, 50 | {Name: "last_modified_date", Type: proto.ColumnType_TIMESTAMP, Description: "The date and time of the last change to contract record."}, 51 | {Name: "last_referenced_date", Type: proto.ColumnType_TIMESTAMP, Description: "The timestamp when the current user last accessed this record, a record related to this record, or a list view."}, 52 | {Name: "last_viewed_date", Type: proto.ColumnType_TIMESTAMP, Description: "The timestamp when the current user last viewed this record or list view. If this value is null, the user might have only accessed this record or list view (last_referenced_date) but not viewed it."}, 53 | {Name: "owner_expiration_notice", Type: proto.ColumnType_STRING, Description: "Number of days ahead of the contract end date (15, 30, 45, 60, 90, and 120). Used to notify the owner in advance that the contract is ending."}, 54 | {Name: "pricebook_2_id", Type: proto.ColumnType_STRING, Description: "ID of the pricebook, if any, associated with this contract."}, 55 | {Name: "special_terms", Type: proto.ColumnType_STRING, Description: "Special terms that apply to the contract."}, 56 | {Name: "system_modstamp", Type: proto.ColumnType_TIMESTAMP, Description: "The date and time when contract was last modified by a user or by an automated process."}, 57 | }), 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /docs/tables/salesforce_account_contact_role.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Steampipe Table: salesforce_account_contact_role - Query Salesforce Account Contact Roles using SQL" 3 | description: "Allows users to query Salesforce Account Contact Roles, providing specific details about the role of a contact within an account." 4 | --- 5 | 6 | # Table: salesforce_account_contact_role - Query Salesforce Account Contact Roles using SQL 7 | 8 | Salesforce Account Contact Role is a feature within Salesforce that allows users to specify the role that a contact plays within an account. It provides a way to define and manage the relationships between contacts and accounts, offering insights into the hierarchy and responsibilities within an organization. Salesforce Account Contact Role is crucial for managing customer relationships and understanding the dynamics within an account. 9 | 10 | ## Table Usage Guide 11 | 12 | The `salesforce_account_contact_role` table offers insights into the roles of contacts within Salesforce accounts. As a Salesforce administrator or sales representative, you can use this table to understand the responsibilities and hierarchy of contacts within an account. This can help you manage customer relationships more effectively, identify key contacts, and understand the dynamics within an account. 13 | 14 | **Important Notes** 15 | - If the `naming_convention` configuration argument is set to `api_native`, please see [API Native Examples](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account#api_native_examples). 16 | 17 | ## Examples 18 | 19 | ### Basic info 20 | Explore the roles assigned to different contacts within various accounts. This can assist in identifying key contacts and their roles in each account, which is crucial for effective account management and communication strategies. 21 | 22 | ```sql+postgres 23 | select 24 | id, 25 | account_id, 26 | contact_id, 27 | is_primary, 28 | role 29 | from 30 | salesforce_account_contact_role; 31 | ``` 32 | 33 | ```sql+sqlite 34 | select 35 | id, 36 | account_id, 37 | contact_id, 38 | is_primary, 39 | role 40 | from 41 | salesforce_account_contact_role; 42 | ``` 43 | 44 | ### List primary account contact role 45 | Explore which contact roles are primarily associated with specific accounts. This is useful for understanding the main points of contact for each account. 46 | 47 | ```sql+postgres 48 | select 49 | id, 50 | account_id, 51 | contact_id, 52 | is_primary 53 | from 54 | salesforce_account_contact_role 55 | where 56 | is_primary; 57 | ``` 58 | 59 | ```sql+sqlite 60 | select 61 | id, 62 | account_id, 63 | contact_id, 64 | is_primary 65 | from 66 | salesforce_account_contact_role 67 | where 68 | is_primary; 69 | ``` 70 | 71 | ## API Native Examples 72 | 73 | If the `naming_convention` config argument is set to `api_native`, the table and column names will match Salesforce naming conventions. 74 | 75 | ### Basic info (with API Native naming convention) 76 | Gain insights into the primary contacts associated with each account, which can be useful in understanding the account's key relationships and interactions. 77 | 78 | ```sql+postgres 79 | select 80 | "ID", 81 | "AccountID", 82 | "ContactID", 83 | "IsPrimary" 84 | from 85 | "AccountContactRole"; 86 | ``` 87 | 88 | ```sql+sqlite 89 | select 90 | "ID", 91 | "AccountID", 92 | "ContactID", 93 | "IsPrimary" 94 | from 95 | "AccountContactRole"; 96 | ``` 97 | 98 | ### List primary account contact role (with API Native naming convention) 99 | Explore which contacts are designated as the primary point of contact for their respective accounts. This is particularly useful for focusing communication efforts and understanding the main contact for each account. 100 | 101 | ```sql+postgres 102 | select 103 | "ID", 104 | "AccountID", 105 | "ContactID", 106 | "IsPrimary" 107 | from 108 | "AccountContactRole" 109 | where 110 | "IsPrimary"; 111 | ``` 112 | 113 | ```sql+sqlite 114 | select 115 | "ID", 116 | "AccountID", 117 | "ContactID", 118 | "IsPrimary" 119 | from 120 | "AccountContactRole" 121 | where 122 | "IsPrimary"; 123 | ``` 124 | 125 | ### Show approver account contact roles 126 | Identify the primary contacts who hold the 'Approver' role within an organization. This can be useful to understand who has the authority to approve actions or changes within the system. 127 | 128 | ```sql+postgres 129 | select 130 | "ID", 131 | "AccountID", 132 | "ContactID", 133 | "IsPrimary", 134 | "Role" 135 | from 136 | "AccountContactRole" 137 | where 138 | "Role" = 'Approver'; 139 | ``` 140 | 141 | ```sql+sqlite 142 | select 143 | "ID", 144 | "AccountID", 145 | "ContactID", 146 | "IsPrimary", 147 | "Role" 148 | from 149 | "AccountContactRole" 150 | where 151 | "Role" = 'Approver'; 152 | ``` 153 | 154 | ### Show account contact roles created in last 30 days 155 | Identify recent changes in your account's contact roles to understand any alterations made within the past month. 156 | 157 | ```sql+postgres 158 | select 159 | "ID", 160 | "AccountID", 161 | "ContactID", 162 | "IsPrimary", 163 | "Role" 164 | from 165 | "AccountContactRole" 166 | where 167 | "CreatedDate" <= now() - interval '30' day; 168 | ``` 169 | 170 | ```sql+sqlite 171 | select 172 | "ID", 173 | "AccountID", 174 | "ContactID", 175 | "IsPrimary", 176 | "Role" 177 | from 178 | "AccountContactRole" 179 | where 180 | "CreatedDate" <= datetime('now', '-30 day'); 181 | ``` -------------------------------------------------------------------------------- /docs/tables/salesforce_product.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Steampipe Table: salesforce_product - Query Salesforce Products using SQL" 3 | description: "Allows users to query Products in Salesforce, providing detailed information about each product, including its standard and custom fields." 4 | --- 5 | 6 | # Table: salesforce_product - Query Salesforce Products using SQL 7 | 8 | Salesforce Products are used to represent the items you sell. They can be goods, services, or digital content that are part of your business model. Products are typically associated with Opportunities or Quotes in Salesforce. 9 | 10 | ## Table Usage Guide 11 | 12 | The `salesforce_product` table provides insights into Products within Salesforce. As a Sales or Business Analyst, explore product-specific details through this table, including standard and custom fields. Utilize it to uncover information about products, such as their associated Opportunities or Quotes, and the verification of custom fields. 13 | 14 | **Important Notes** 15 | - If the `naming_convention` configuration argument is set to `api_native`, please see [API Native Examples](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account#api_native_examples). 16 | - If the naming_convention parameter is set to api_native in the config file, then the table and column names will match what’s in Salesforce. For instance, the query `select id, name from salesforce_product` would become `select "ID", "Name" from "Product2"`. 17 | 18 | ## Examples 19 | 20 | ### Basic info 21 | Explore which products in your Salesforce inventory are active and who created them. This information can be useful for auditing purposes and to understand the distribution of product responsibilities within your team. 22 | 23 | ```sql+postgres 24 | select 25 | id, 26 | name, 27 | family, 28 | is_active, 29 | created_by_id, 30 | quantity_unit_of_measure, 31 | stock_keeping_unit 32 | from 33 | salesforce_product; 34 | ``` 35 | 36 | ```sql+sqlite 37 | select 38 | id, 39 | name, 40 | family, 41 | is_active, 42 | created_by_id, 43 | quantity_unit_of_measure, 44 | stock_keeping_unit 45 | from 46 | salesforce_product; 47 | ``` 48 | 49 | ### List inactive products 50 | Discover the segments that consist of inactive products in your Salesforce database. This can help you identify which products are not currently in use, allowing you to make informed decisions about inventory management and product offerings. 51 | 52 | ```sql+postgres 53 | select 54 | id, 55 | name, 56 | family, 57 | is_active, 58 | created_by_id, 59 | quantity_unit_of_measure, 60 | stock_keeping_unit 61 | from 62 | salesforce_product 63 | where 64 | not is_active; 65 | ``` 66 | 67 | ```sql+sqlite 68 | select 69 | id, 70 | name, 71 | family, 72 | is_active, 73 | created_by_id, 74 | quantity_unit_of_measure, 75 | stock_keeping_unit 76 | from 77 | salesforce_product 78 | where 79 | is_active = 0; 80 | ``` 81 | 82 | ## API Native Examples 83 | 84 | If the `naming_convention` config argument is set to `api_native`, the table and column names will match Salesforce naming conventions. 85 | 86 | ### Basic info (with API Native naming convention) 87 | Explore which products are active and in stock by assessing key attributes such as product ID, name, and family. This can help in managing inventory and understanding product performance. 88 | 89 | ```sql+postgres 90 | select 91 | "ID", 92 | "Name", 93 | "Family", 94 | "IsActive", 95 | "StockKeepingUnit" 96 | from 97 | "Product2"; 98 | ``` 99 | 100 | ```sql+sqlite 101 | select 102 | "ID", 103 | "Name", 104 | "Family", 105 | "IsActive", 106 | "StockKeepingUnit" 107 | from 108 | "Product2"; 109 | ``` 110 | 111 | ### List inactive products (with API Native naming convention) 112 | Discover the segments that contain inactive products in the inventory to better manage stock and potentially discontinue or replenish certain items. 113 | 114 | ```sql+postgres 115 | select 116 | "ID", 117 | "Name", 118 | "Family", 119 | "IsActive", 120 | "StockKeepingUnit" 121 | from 122 | "Product2" 123 | where 124 | not "IsActive"; 125 | ``` 126 | 127 | ```sql+sqlite 128 | select 129 | "ID", 130 | "Name", 131 | "Family", 132 | "IsActive", 133 | "StockKeepingUnit" 134 | from 135 | "Product2" 136 | where 137 | "IsActive" = 0; 138 | ``` 139 | 140 | ### Show archived products 141 | Explore which products have been archived in your inventory, allowing you to keep track of items no longer actively sold or in circulation. 142 | 143 | ```sql+postgres 144 | select 145 | "ID", 146 | "Name", 147 | "Family", 148 | "IsActive", 149 | "StockKeepingUnit" 150 | from 151 | "Product2" 152 | where 153 | "IsArchived"; 154 | ``` 155 | 156 | ```sql+sqlite 157 | select 158 | "ID", 159 | "Name", 160 | "Family", 161 | "IsActive", 162 | "StockKeepingUnit" 163 | from 164 | "Product2" 165 | where 166 | "IsArchived"; 167 | ``` 168 | 169 | ### Show deleted products 170 | Uncover the details of products that have been removed from your inventory. This is useful for tracking product lifecycle and managing stock levels effectively. 171 | 172 | ```sql+postgres 173 | select 174 | "ID", 175 | "Name", 176 | "Family", 177 | "IsActive", 178 | "StockKeepingUnit" 179 | from 180 | "Product2" 181 | where 182 | "IsDeleted"; 183 | ``` 184 | 185 | ```sql+sqlite 186 | select 187 | "ID", 188 | "Name", 189 | "Family", 190 | "IsActive", 191 | "StockKeepingUnit" 192 | from 193 | "Product2" 194 | where 195 | "IsDeleted"; 196 | ``` -------------------------------------------------------------------------------- /docs/tables/salesforce_permission_set_assignment.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Steampipe Table: salesforce_permission_set_assignment - Query Salesforce Permission Set Assignments using SQL" 3 | description: "Allows users to query Permission Set Assignments in Salesforce, particularly user permissions and access settings, providing insights into user access and security configurations." 4 | --- 5 | 6 | # Table: salesforce_permission_set_assignment - Query Salesforce Permission Set Assignments using SQL 7 | 8 | A Salesforce Permission Set Assignment is a functionality within Salesforce that allows administrators to assign specific permissions to users. It is a flexible and granular way to provide access beyond what is defined in the user's profile. Permission Set Assignments help organizations to manage user access and security settings effectively, ensuring that users have only the access they need. 9 | 10 | ## Table Usage Guide 11 | 12 | The `salesforce_permission_set_assignment` table provides insights into Permission Set Assignments within Salesforce. As a Salesforce administrator, explore assignment-specific details through this table, including user permissions and access settings. Utilize it to uncover information about assignments, such as those with specific permissions, the relationships between users and their assigned permissions, and the verification of access policies. 13 | 14 | **Important Notes** 15 | - If the `naming_convention` configuration argument is set to `api_native`, please see [API Native Examples](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account#api_native_examples). 16 | 17 | ## Examples 18 | 19 | ### Basic info 20 | Discover the segments that detail the assignment of permission sets in Salesforce. This can help identify instances where specific permissions are assigned, aiding in understanding user access control and ensuring necessary security measures are in place. 21 | 22 | ```sql+postgres 23 | select 24 | id, 25 | assignee_id, 26 | permission_set_group_id, 27 | permission_set_id 28 | from 29 | salesforce_permission_set_assignment; 30 | ``` 31 | 32 | ```sql+sqlite 33 | select 34 | id, 35 | assignee_id, 36 | permission_set_group_id, 37 | permission_set_id 38 | from 39 | salesforce_permission_set_assignment; 40 | ``` 41 | 42 | ### List users with permission to "Modify All Data" 43 | Explore which users have the authority to modify all data in your Salesforce environment. This is particularly useful for maintaining security and control over data integrity. 44 | 45 | ```sql+postgres 46 | with sps as ( 47 | select 48 | id, 49 | name, 50 | description, 51 | label 52 | from 53 | salesforce_permission_set 54 | where 55 | permissions_modify_all_data 56 | ), 57 | spsa as ( 58 | select 59 | * 60 | from 61 | salesforce_permission_set_assignment 62 | ) 63 | select 64 | su.name as user_name, 65 | su.email as user_email, 66 | su.username as user_username, 67 | spsa.assignee_id as user_id, 68 | sps.id as permission_set_id, 69 | sps.name as permission_set_name, 70 | sps.description as permission_set_description, 71 | sps.label as permission_set_label 72 | from 73 | sps, 74 | spsa, 75 | salesforce_user as su 76 | where 77 | sps.id = spsa.permission_set_id 78 | and spsa.assignee_id = su.id; 79 | ``` 80 | 81 | ```sql+sqlite 82 | with sps as ( 83 | select 84 | id, 85 | name, 86 | description, 87 | label 88 | from 89 | salesforce_permission_set 90 | where 91 | permissions_modify_all_data 92 | ), 93 | spsa as ( 94 | select 95 | * 96 | from 97 | salesforce_permission_set_assignment 98 | ) 99 | select 100 | su.name as user_name, 101 | su.email as user_email, 102 | su.username as user_username, 103 | spsa.assignee_id as user_id, 104 | sps.id as permission_set_id, 105 | sps.name as permission_set_name, 106 | sps.description as permission_set_description, 107 | sps.label as permission_set_label 108 | from 109 | sps, 110 | spsa, 111 | salesforce_user as su 112 | where 113 | sps.id = spsa.permission_set_id 114 | and spsa.assignee_id = su.id; 115 | ``` 116 | 117 | ## API Native Examples 118 | 119 | If the `naming_convention` config argument is set to `api_native`, the table and column names will match Salesforce naming conventions. 120 | 121 | ### Basic info (with API Native naming convention) 122 | Explore which permission sets are assigned to various users. This helps in understanding user access and permissions within your system, thereby aiding in effective access management. 123 | 124 | ```sql+postgres 125 | select 126 | "ID", 127 | "AssigneeID", 128 | "PermissionSetGroupID", 129 | "PermissionSetID" 130 | from 131 | "PermissionSetAssignment"; 132 | ``` 133 | 134 | ```sql+sqlite 135 | select 136 | "ID", 137 | "AssigneeID", 138 | "PermissionSetGroupID", 139 | "PermissionSetID" 140 | from 141 | "PermissionSetAssignment"; 142 | ``` 143 | 144 | ### List assignments which are not associated with any permission set groups 145 | Discover the segments that consist of assignments not linked to any permission set groups. This can be useful to identify potential issues in access control and rectify them for enhanced security management. 146 | 147 | ```sql+postgres 148 | select 149 | "ID", 150 | "AssigneeID", 151 | "PermissionSetGroupID", 152 | "PermissionSetID" 153 | from 154 | "PermissionSetAssignment" 155 | where 156 | "PermissionSetGroupID" is null; 157 | ``` 158 | 159 | ```sql+sqlite 160 | select 161 | "ID", 162 | "AssigneeID", 163 | "PermissionSetGroupID", 164 | "PermissionSetID" 165 | from 166 | "PermissionSetAssignment" 167 | where 168 | "PermissionSetGroupID" is null; 169 | ``` -------------------------------------------------------------------------------- /salesforce/table_salesforce_opportunity.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" 7 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 8 | ) 9 | 10 | func SalesforceOpportunity(ctx context.Context, dm dynamicMap, config salesforceConfig) *plugin.Table { 11 | tableName := "Opportunity" 12 | return &plugin.Table{ 13 | Name: "salesforce_opportunity", 14 | Description: "Represents an opportunity, which is a sale or pending deal.", 15 | List: &plugin.ListConfig{ 16 | Hydrate: listSalesforceObjectsByTable(tableName, dm.salesforceColumns), 17 | KeyColumns: dm.keyColumns, 18 | }, 19 | Get: &plugin.GetConfig{ 20 | Hydrate: getSalesforceObjectbyID(tableName), 21 | KeyColumns: plugin.SingleColumn(checkNameScheme(config, dm.cols)), 22 | }, 23 | Columns: mergeTableColumns(ctx, config, dm.cols, []*plugin.Column{ 24 | // Top columns 25 | {Name: "id", Type: proto.ColumnType_STRING, Description: "Unique identifier of the opportunity in Salesforce."}, 26 | {Name: "account_id", Type: proto.ColumnType_STRING, Description: "ID of the account associated with this opportunity."}, 27 | {Name: "amount", Type: proto.ColumnType_DOUBLE, Description: "Estimated total sale amount. For opportunities with products, the amount is the sum of the related products."}, 28 | {Name: "name", Type: proto.ColumnType_STRING, Description: "A name for this opportunity."}, 29 | {Name: "owner_id", Type: proto.ColumnType_STRING, Description: "ID of the User who has been assigned to work this opportunity."}, 30 | 31 | // Other columns 32 | {Name: "campaign_id", Type: proto.ColumnType_STRING, Description: "ID of a related Campaign. This field is defined only for those organizations that have the campaign feature Campaigns enabled."}, 33 | {Name: "close_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date when the opportunity is expected to close."}, 34 | {Name: "created_by_id", Type: proto.ColumnType_STRING, Description: "Id of the user who created the opportunity."}, 35 | {Name: "created_date", Type: proto.ColumnType_TIMESTAMP, Description: "The creation date and time of the opportunity."}, 36 | {Name: "description", Type: proto.ColumnType_STRING, Description: "Description of the opportunity."}, 37 | {Name: "expected_revenue", Type: proto.ColumnType_DOUBLE, Description: "Calculated revenue based on the Amount and Probability fields."}, 38 | {Name: "fiscal_quarter", Type: proto.ColumnType_INT, Description: "Represents the fiscal quarter. Valid values are 1, 2, 3, or 4."}, 39 | {Name: "fiscal_year", Type: proto.ColumnType_INT, Description: "Represents the fiscal year, for example, 2006."}, 40 | {Name: "forecast_category", Type: proto.ColumnType_STRING, Description: "Forecast category name displayed in reports, opportunity detail and edit pages, opportunity searches, and opportunity list views."}, 41 | {Name: "forecast_category_name", Type: proto.ColumnType_STRING, Description: "Name of the forecast category."}, 42 | {Name: "has_open_activity", Type: proto.ColumnType_BOOL, Description: "Indicates whether an opportunity has an open event or task (true) or not (false)."}, 43 | {Name: "has_opportunity_line_item", Type: proto.ColumnType_BOOL, Description: "Indicates whether the opportunity has associated line items. A value of true means that Opportunity line items have been created for the opportunity."}, 44 | {Name: "has_overdue_task", Type: proto.ColumnType_BOOL, Description: "Indicates whether an opportunity has an overdue task (true) or not (false)."}, 45 | {Name: "is_closed", Type: proto.ColumnType_BOOL, Description: "Indicates that the opportunity is closed."}, 46 | {Name: "is_deleted", Type: proto.ColumnType_BOOL, Description: "Indicates that the opportunity is deleted."}, 47 | {Name: "is_private", Type: proto.ColumnType_BOOL, Description: "Indicates that the opportunity is private."}, 48 | {Name: "is_won", Type: proto.ColumnType_BOOL, Description: "Indicates that the quote or proposal has been signed or electronically accepted."}, 49 | {Name: "last_activity_date", Type: proto.ColumnType_TIMESTAMP, Description: "Value is one of the following, whichever is the most recent of a) Due date of the most recent event logged against the record or b) Due date of the most recently closed task associated with the record."}, 50 | {Name: "last_modified_by_id", Type: proto.ColumnType_STRING, Description: "The id of the user who last modified the oppurtinity record."}, 51 | {Name: "last_modified_date", Type: proto.ColumnType_TIMESTAMP, Description: "The data and time of the last modification of the oppurtinity record."}, 52 | {Name: "lead_source", Type: proto.ColumnType_STRING, Description: "Source of this opportunity, such as Advertisement or Trade Show."}, 53 | {Name: "next_step", Type: proto.ColumnType_STRING, Description: "Description of next task in closing opportunity."}, 54 | {Name: "pricebook_2_id", Type: proto.ColumnType_STRING, Description: "ID of a related Pricebook2 object. The Pricebook2Id field indicates which Pricebook2 applies to this opportunity. The Pricebook2Id field is defined only for those organizations that have products enabled as a feature."}, 55 | {Name: "probability", Type: proto.ColumnType_DOUBLE, Description: "Percentage of estimated confidence in closing the opportunity."}, 56 | {Name: "stage_name", Type: proto.ColumnType_STRING, Description: "Current stage of opportunity."}, 57 | {Name: "system_modstamp", Type: proto.ColumnType_STRING, Description: "The date and time when opportunity was last modified by a user or by an automated process."}, 58 | {Name: "total_opportunity_quantity", Type: proto.ColumnType_STRING, Description: "Number of items included in this opportunity. Used in quantity-based forecasting."}, 59 | {Name: "type", Type: proto.ColumnType_STRING, Description: "Type of opportunity, such as Existing Business or New Business."}, 60 | }), 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/turbot/steampipe-plugin-salesforce 2 | 3 | go 1.24 4 | 5 | toolchain go1.24.1 6 | 7 | require ( 8 | github.com/iancoleman/strcase v0.3.0 9 | github.com/simpleforce/simpleforce v0.0.0-20211207104336-af9d9a281fea 10 | github.com/turbot/steampipe-plugin-sdk/v5 v5.13.1 11 | ) 12 | 13 | require ( 14 | cloud.google.com/go v0.112.1 // indirect 15 | cloud.google.com/go/compute/metadata v0.3.0 // indirect 16 | cloud.google.com/go/iam v1.1.6 // indirect 17 | cloud.google.com/go/storage v1.38.0 // indirect 18 | github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect 19 | github.com/agext/levenshtein v1.2.3 // indirect 20 | github.com/allegro/bigcache/v3 v3.1.0 // indirect 21 | github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect 22 | github.com/aws/aws-sdk-go v1.44.183 // indirect 23 | github.com/beorn7/perks v1.0.1 // indirect 24 | github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect 25 | github.com/btubbs/datetime v0.1.1 // indirect 26 | github.com/cenkalti/backoff/v4 v4.3.0 // indirect 27 | github.com/cespare/xxhash/v2 v2.3.0 // indirect 28 | github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect 29 | github.com/dgraph-io/ristretto v0.2.0 // indirect 30 | github.com/dustin/go-humanize v1.0.1 // indirect 31 | github.com/eko/gocache/lib/v4 v4.1.6 // indirect 32 | github.com/eko/gocache/store/bigcache/v4 v4.2.1 // indirect 33 | github.com/eko/gocache/store/ristretto/v4 v4.2.1 // indirect 34 | github.com/fatih/color v1.17.0 // indirect 35 | github.com/felixge/httpsnoop v1.0.4 // indirect 36 | github.com/fsnotify/fsnotify v1.7.0 // indirect 37 | github.com/gertd/go-pluralize v0.2.1 // indirect 38 | github.com/ghodss/yaml v1.0.0 // indirect 39 | github.com/go-logr/logr v1.4.1 // indirect 40 | github.com/go-logr/stdr v1.2.2 // indirect 41 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect 42 | github.com/golang/mock v1.6.0 // indirect 43 | github.com/golang/protobuf v1.5.4 // indirect 44 | github.com/google/go-cmp v0.6.0 // indirect 45 | github.com/google/s2a-go v0.1.7 // indirect 46 | github.com/google/uuid v1.6.0 // indirect 47 | github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect 48 | github.com/googleapis/gax-go/v2 v2.12.3 // indirect 49 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect 50 | github.com/hashicorp/go-cleanhttp v0.5.2 // indirect 51 | github.com/hashicorp/go-getter v1.7.9 // indirect 52 | github.com/hashicorp/go-hclog v1.6.3 // indirect 53 | github.com/hashicorp/go-plugin v1.6.1 // indirect 54 | github.com/hashicorp/go-safetemp v1.0.0 // indirect 55 | github.com/hashicorp/go-version v1.7.0 // indirect 56 | github.com/hashicorp/hcl/v2 v2.20.1 // indirect 57 | github.com/hashicorp/yamux v0.1.1 // indirect 58 | github.com/jmespath/go-jmespath v0.4.0 // indirect 59 | github.com/klauspost/compress v1.17.2 // indirect 60 | github.com/mattn/go-colorable v0.1.13 // indirect 61 | github.com/mattn/go-isatty v0.0.20 // indirect 62 | github.com/mattn/go-runewidth v0.0.15 // indirect 63 | github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect 64 | github.com/mitchellh/go-homedir v1.1.0 // indirect 65 | github.com/mitchellh/go-testing-interface v1.14.1 // indirect 66 | github.com/mitchellh/go-wordwrap v1.0.0 // indirect 67 | github.com/mitchellh/mapstructure v1.5.0 // indirect 68 | github.com/oklog/run v1.0.0 // indirect 69 | github.com/olekukonko/tablewriter v0.0.5 // indirect 70 | github.com/pkg/errors v0.9.1 // indirect 71 | github.com/prometheus/client_golang v1.14.0 // indirect 72 | github.com/prometheus/client_model v0.3.0 // indirect 73 | github.com/prometheus/common v0.37.0 // indirect 74 | github.com/prometheus/procfs v0.8.0 // indirect 75 | github.com/rivo/uniseg v0.2.0 // indirect 76 | github.com/sethvargo/go-retry v0.2.4 // indirect 77 | github.com/stevenle/topsort v0.2.0 // indirect 78 | github.com/tkrajina/go-reflector v0.5.6 // indirect 79 | github.com/turbot/go-kit v1.1.0 // indirect 80 | github.com/ulikunitz/xz v0.5.15 // indirect 81 | github.com/zclconf/go-cty v1.14.4 // indirect 82 | go.opencensus.io v0.24.0 // indirect 83 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect 84 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect 85 | go.opentelemetry.io/otel v1.26.0 // indirect 86 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.26.0 // indirect 87 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect 88 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 // indirect 89 | go.opentelemetry.io/otel/metric v1.26.0 // indirect 90 | go.opentelemetry.io/otel/sdk v1.26.0 // indirect 91 | go.opentelemetry.io/otel/sdk/metric v1.26.0 // indirect 92 | go.opentelemetry.io/otel/trace v1.26.0 // indirect 93 | go.opentelemetry.io/proto/otlp v1.2.0 // indirect 94 | golang.org/x/crypto v0.36.0 // indirect 95 | golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect 96 | golang.org/x/mod v0.19.0 // indirect 97 | golang.org/x/net v0.38.0 // indirect 98 | golang.org/x/oauth2 v0.27.0 // indirect 99 | golang.org/x/sync v0.12.0 // indirect 100 | golang.org/x/sys v0.31.0 // indirect 101 | golang.org/x/text v0.23.0 // indirect 102 | golang.org/x/time v0.5.0 // indirect 103 | golang.org/x/tools v0.23.0 // indirect 104 | google.golang.org/api v0.171.0 // indirect 105 | google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect 106 | google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect 107 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect 108 | google.golang.org/grpc v1.66.0 // indirect 109 | google.golang.org/protobuf v1.34.2 // indirect 110 | gopkg.in/yaml.v2 v2.4.0 // indirect 111 | ) 112 | -------------------------------------------------------------------------------- /docs/tables/salesforce_lead.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Steampipe Table: salesforce_lead - Query Salesforce Leads using SQL" 3 | description: "Allows users to query Leads in Salesforce, providing detailed information about potential sales opportunities and customer data." 4 | --- 5 | 6 | # Table: salesforce_lead - Query Salesforce Leads using SQL 7 | 8 | Salesforce Leads are a key resource in Salesforce, a customer relationship management solution. They represent potential sales opportunities and contain information about individuals or representatives of organizations who are interested in the product or service that the company offers. Leads can be converted into accounts, contacts, or opportunities when they are qualified. 9 | 10 | ## Table Usage Guide 11 | 12 | The `salesforce_lead` table provides insights into Leads within Salesforce. As a sales manager or marketing professional, explore Lead-specific details through this table, including personal information, source, status, and associated company details. Utilize it to track and analyze potential sales opportunities, understand customer behavior, and plan targeted marketing strategies. 13 | 14 | **Important Notes** 15 | - If the `naming_convention` configuration argument is set to `api_native`, please see [API Native Examples](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account#api_native_examples). 16 | 17 | ## Examples 18 | 19 | ### Basic info 20 | Explore the various leads in your Salesforce system to understand their status and gain insights into their associated industries. This can assist in identifying potential conversion opportunities and assessing lead quality. 21 | 22 | ```sql+postgres 23 | select 24 | id, 25 | name, 26 | company, 27 | email, 28 | industry, 29 | is_converted, 30 | rating, 31 | status, 32 | website 33 | from 34 | salesforce_lead; 35 | ``` 36 | 37 | ```sql+sqlite 38 | select 39 | id, 40 | name, 41 | company, 42 | email, 43 | industry, 44 | is_converted, 45 | rating, 46 | status, 47 | website 48 | from 49 | salesforce_lead; 50 | ``` 51 | 52 | ### List number of leads by industry type 53 | Analyze the distribution of leads across different industry sectors. This is beneficial for understanding which industries are more engaged with your business, aiding in strategic decision-making. 54 | 55 | ```sql+postgres 56 | select 57 | count(*), 58 | industry 59 | from 60 | salesforce_lead 61 | group by 62 | industry; 63 | ``` 64 | 65 | ```sql+sqlite 66 | select 67 | count(*), 68 | industry 69 | from 70 | salesforce_lead 71 | group by 72 | industry; 73 | ``` 74 | 75 | ### List number of leads by status 76 | Determine the distribution of leads based on their status. This can provide insights into your sales pipeline and help pinpoint areas for improvement. 77 | 78 | ```sql+postgres 79 | select 80 | count(*), 81 | status 82 | from 83 | salesforce_lead 84 | group by 85 | status; 86 | ``` 87 | 88 | ```sql+sqlite 89 | select 90 | count(*), 91 | status 92 | from 93 | salesforce_lead 94 | group by 95 | status; 96 | ``` 97 | 98 | ## API Native Examples 99 | 100 | If the `naming_convention` config argument is set to `api_native`, the table and column names will match Salesforce naming conventions. 101 | 102 | ### Basic info (with API Native naming convention) 103 | Discover the segments that are converted and their respective ratings in a particular industry. This can be used to pinpoint specific areas for potential business growth and improvement. 104 | 105 | ```sql+postgres 106 | select 107 | "ID", 108 | "Name", 109 | "Industry", 110 | "IsConverted", 111 | "Rating", 112 | "Status", 113 | "Website" 114 | from 115 | "Lead"; 116 | ``` 117 | 118 | ```sql+sqlite 119 | select 120 | "ID", 121 | "Name", 122 | "Industry", 123 | "IsConverted", 124 | "Rating", 125 | "Status", 126 | "Website" 127 | from 128 | "Lead"; 129 | ``` 130 | 131 | ### List number of leads by industry type (with API Native naming convention) 132 | Determine the distribution of leads across various industry types. This can help in identifying which industries are more engaged with your services, enabling targeted marketing efforts. 133 | 134 | ```sql+postgres 135 | select 136 | count(*), 137 | "Industry" 138 | from 139 | "Lead" 140 | group by 141 | "Industry"; 142 | ``` 143 | 144 | ```sql+sqlite 145 | select 146 | count(*), 147 | "Industry" 148 | from 149 | "Lead" 150 | group by 151 | "Industry"; 152 | ``` 153 | 154 | ### List cold rated leads 155 | Discover the segments that are identified as 'cold' leads in your business. This is useful to target specific marketing strategies to improve conversion rates. 156 | 157 | ```sql+postgres 158 | select 159 | "ID", 160 | "Name", 161 | "Industry", 162 | "IsConverted", 163 | "Rating", 164 | "Status", 165 | "Website" 166 | from 167 | "Lead" 168 | where 169 | "Rating" = 'Cold'; 170 | ``` 171 | 172 | ```sql+sqlite 173 | select 174 | "ID", 175 | "Name", 176 | "Industry", 177 | "IsConverted", 178 | "Rating", 179 | "Status", 180 | "Website" 181 | from 182 | "Lead" 183 | where 184 | "Rating" = 'Cold'; 185 | ``` 186 | 187 | ### List qualified leads 188 | Explore which leads are qualified, allowing you to focus your efforts on potential customers who have been pre-identified as likely to convert. This can help streamline your sales process and improve efficiency. 189 | 190 | ```sql+postgres 191 | select 192 | "ID", 193 | "Name", 194 | "Industry", 195 | "IsConverted", 196 | "Rating", 197 | "Status", 198 | "Website" 199 | from 200 | "Lead" 201 | where 202 | "Status" = 'Qualified'; 203 | ``` 204 | 205 | ```sql+sqlite 206 | select 207 | "ID", 208 | "Name", 209 | "Industry", 210 | "IsConverted", 211 | "Rating", 212 | "Status", 213 | "Website" 214 | from 215 | "Lead" 216 | where 217 | "Status" = 'Qualified'; 218 | ``` -------------------------------------------------------------------------------- /salesforce/table_salesforce_order.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" 7 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 8 | ) 9 | 10 | func SalesforceOrder(ctx context.Context, dm dynamicMap, config salesforceConfig) *plugin.Table { 11 | tableName := "Order" 12 | return &plugin.Table{ 13 | Name: "salesforce_order", 14 | Description: "Represents an order associated with a contract or an account.", 15 | List: &plugin.ListConfig{ 16 | Hydrate: listSalesforceObjectsByTable(tableName, dm.salesforceColumns), 17 | KeyColumns: dm.keyColumns, 18 | }, 19 | Get: &plugin.GetConfig{ 20 | Hydrate: getSalesforceObjectbyID(tableName), 21 | KeyColumns: plugin.SingleColumn(checkNameScheme(config, dm.cols)), 22 | }, 23 | Columns: mergeTableColumns(ctx, config, dm.cols, []*plugin.Column{ 24 | // Top columns 25 | {Name: "id", Type: proto.ColumnType_STRING, Description: "Unique identifier of the order in Salesforce."}, 26 | {Name: "name", Type: proto.ColumnType_STRING, Description: "Title for the order that distinguishes it from other orders."}, 27 | {Name: "account_id", Type: proto.ColumnType_STRING, Description: "ID of the Account associated with this order."}, 28 | {Name: "order_number", Type: proto.ColumnType_STRING, Description: "Order number assigned to this order."}, 29 | {Name: "owner_id", Type: proto.ColumnType_STRING, Description: " ID of the User or queue that owns this order."}, 30 | {Name: "status", Type: proto.ColumnType_STRING, Description: "The Status field specifies the current state of an order. Status strings represent its current state (Draft or Activated)."}, 31 | {Name: "total_amount", Type: proto.ColumnType_DOUBLE, Description: "Total amount of the order."}, 32 | {Name: "type", Type: proto.ColumnType_STRING, Description: "Type of order."}, 33 | 34 | // Other columns 35 | {Name: "activated_by_id", Type: proto.ColumnType_STRING, Description: "ID of the User who activated this order."}, 36 | {Name: "activated_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date and time when the order was activated."}, 37 | {Name: "bill_to_contact_id", Type: proto.ColumnType_STRING, Description: "ID of the contact that the order is billed to."}, 38 | {Name: "billing_address", Type: proto.ColumnType_JSON, Description: "The billing adress for the order."}, 39 | {Name: "company_authorized_by_id", Type: proto.ColumnType_STRING, Description: "ID of the user who authorized the account associated with the order."}, 40 | {Name: "company_authorized_date", Type: proto.ColumnType_TIMESTAMP, Description: "The date on which your organization authorized the order."}, 41 | {Name: "contract_id", Type: proto.ColumnType_STRING, Description: "ID of the contract associated with this order. Can only be updated when the order's StatusCode value is Draft."}, 42 | {Name: "created_by_id", Type: proto.ColumnType_STRING, Description: "Id of the user who created the order record."}, 43 | {Name: "created_date", Type: proto.ColumnType_TIMESTAMP, Description: "Creation date and time of the order record."}, 44 | {Name: "customer_authorized_by_id", Type: proto.ColumnType_STRING, Description: "ID of the contact who authorized the order."}, 45 | {Name: "customer_authorized_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date on which the contact authorized the order."}, 46 | {Name: "description", Type: proto.ColumnType_STRING, Description: "Description of the order."}, 47 | {Name: "effective_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date at which the order becomes effective."}, 48 | {Name: "end_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date at which the order ends."}, 49 | {Name: "is_deleted", Type: proto.ColumnType_BOOL, Description: "Indicates that the order is deleted."}, 50 | {Name: "is_reduction_order", Type: proto.ColumnType_BOOL, Description: "Determines whether an order is a reduction order."}, 51 | {Name: "last_modified_by_id", Type: proto.ColumnType_STRING, Description: "Id of the user who most recently changed the order record."}, 52 | {Name: "last_modified_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date of most recent change in the order record."}, 53 | {Name: "last_referenced_date", Type: proto.ColumnType_TIMESTAMP, Description: "The timestamp when the current user last accessed this record, a record related to this record, or a list view."}, 54 | {Name: "last_viewed_date", Type: proto.ColumnType_TIMESTAMP, Description: "The timestamp when the current user last viewed this record or list view. If this value is null, the user might have only accessed this record or list view (LastReferencedDate) but not viewed it."}, 55 | {Name: "order_reference_number", Type: proto.ColumnType_STRING, Description: "Reference number assigned to the order."}, 56 | {Name: "original_order_id", Type: proto.ColumnType_STRING, Description: "Optional. ID of the original order that a reduction order is reducing, if the reduction order is reducing a single order."}, 57 | {Name: "po_date", Type: proto.ColumnType_TIMESTAMP, Description: "Date of the purchase order."}, 58 | {Name: "po_number", Type: proto.ColumnType_STRING, Description: "Number identifying the purchase order."}, 59 | {Name: "pricebook_2_id", Type: proto.ColumnType_STRING, Description: "ID of the price book associated with this order."}, 60 | {Name: "ship_to_contact_id", Type: proto.ColumnType_STRING, Description: "ID of the contact that the order is shipped to."}, 61 | {Name: "status_code", Type: proto.ColumnType_STRING, Description: "Status code of the stage that the order has reached in the order business process."}, 62 | {Name: "system_modstamp", Type: proto.ColumnType_TIMESTAMP, Description: "The date and time when order record was last modified by a user or by an automated process."}, 63 | {Name: "shipping_address", Type: proto.ColumnType_JSON, Description: "The shipping adress for the order."}, 64 | }), 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /docs/tables/salesforce_object_permission.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Steampipe Table: salesforce_object_permission - Query Salesforce Object Permissions using SQL" 3 | description: "Allows users to query Salesforce Object Permissions, specifically the permissions that users have on Salesforce objects." 4 | --- 5 | 6 | # Table: salesforce_object_permission - Query Salesforce Object Permissions using SQL 7 | 8 | Salesforce Object Permissions is a feature within Salesforce that allows you to control the level of access that users have to Salesforce objects. It provides a way to set up and manage permissions for various Salesforce objects, including accounts, contacts, leads, and opportunities. Salesforce Object Permissions helps you maintain the security and integrity of your Salesforce data by ensuring that users only have the appropriate level of access to Salesforce objects. 9 | 10 | ## Table Usage Guide 11 | 12 | The `salesforce_object_permission` table provides insights into the permissions that users have on Salesforce objects. As a Salesforce administrator, explore permission-specific details through this table, including the Salesforce object that the permission applies to, the type of permission, and the user or profile that the permission is associated with. Utilize it to uncover information about permissions, such as those that allow users to view, create, edit, or delete Salesforce objects. 13 | 14 | **Important Notes** 15 | - If the `naming_convention` configuration argument is set to `api_native`, please see [API Native Examples](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account#api_native_examples). 16 | 17 | ## Examples 18 | 19 | ### Basic info 20 | Explore which Salesforce object permissions allow for modification or viewing of all records. This is beneficial for assessing user access rights and ensuring appropriate security measures are in place. 21 | 22 | ```sql+postgres 23 | select 24 | id, 25 | parent_id, 26 | sobject_type, 27 | permissions_modify_all_records, 28 | permissions_view_all_records 29 | from 30 | salesforce_object_permission 31 | order by 32 | sobject_type; 33 | ``` 34 | 35 | ```sql+sqlite 36 | select 37 | id, 38 | parent_id, 39 | sobject_type, 40 | permissions_modify_all_records, 41 | permissions_view_all_records 42 | from 43 | salesforce_object_permission 44 | order by 45 | sobject_type; 46 | ``` 47 | 48 | ### List permission sets with "Transfer Leads" permission on "Lead" object 49 | Determine the areas in which specific permissions are granted for transferring leads. This query is useful for assessing user permissions and ensuring appropriate access control within your Salesforce environment. 50 | 51 | ```sql+postgres 52 | select 53 | sop.id, 54 | sop.parent_id, 55 | sps.name, 56 | sps.permissions_transfer_any_lead, 57 | sop.sobject_type, 58 | sop.permissions_read, 59 | sop.permissions_create 60 | from 61 | salesforce_object_permission sop, 62 | salesforce_permission_set sps 63 | where 64 | sobject_type = 'Lead' and 65 | sps.id = sop.parent_id; 66 | ``` 67 | 68 | ```sql+sqlite 69 | select 70 | sop.id, 71 | sop.parent_id, 72 | sps.name, 73 | sps.permissions_transfer_any_lead, 74 | sop.sobject_type, 75 | sop.permissions_read, 76 | sop.permissions_create 77 | from 78 | salesforce_object_permission sop, 79 | salesforce_permission_set sps 80 | where 81 | sobject_type = 'Lead' and 82 | sps.id = sop.parent_id; 83 | ``` 84 | 85 | ## API Native Examples 86 | 87 | If the `naming_convention` config argument is set to `api_native`, the table and column names will match Salesforce naming conventions. 88 | 89 | ### Basic info (with API Native naming convention) 90 | Determine areas in which users have comprehensive permissions, such as the ability to view or modify all records, to understand potential security risks and compliance issues in your system. 91 | 92 | ```sql+postgres 93 | select 94 | "ID", 95 | "ParentID", 96 | "SobjectType", 97 | "PermissionsModifyAllRecords", 98 | "PermissionsViewAllRecords" 99 | from 100 | "ObjectPermission" 101 | order by 102 | "SobjectType"; 103 | ``` 104 | 105 | ```sql+sqlite 106 | select 107 | "ID", 108 | "ParentID", 109 | "SobjectType", 110 | "PermissionsModifyAllRecords", 111 | "PermissionsViewAllRecords" 112 | from 113 | "ObjectPermission" 114 | order by 115 | "SobjectType"; 116 | ``` 117 | 118 | ### Show delete permissions 119 | Determine the areas in which users have delete permissions to understand potential security risks or areas for access management improvements. This query is useful for administrators looking to optimize user roles and permissions. 120 | 121 | ```sql+postgres 122 | select 123 | "ID", 124 | "ParentID", 125 | "SobjectType", 126 | "PermissionsModifyAllRecords", 127 | "PermissionsViewAllRecords" 128 | from 129 | "ObjectPermission" 130 | where 131 | "PermissionsDelete"; 132 | ``` 133 | 134 | ```sql+sqlite 135 | select 136 | "ID", 137 | "ParentID", 138 | "SobjectType", 139 | "PermissionsModifyAllRecords", 140 | "PermissionsViewAllRecords" 141 | from 142 | "ObjectPermission" 143 | where 144 | "PermissionsDelete"; 145 | ``` 146 | 147 | ### Show read permissions 148 | Explore which Salesforce objects a user has read permissions for, allowing you to understand and manage access rights effectively. This can be particularly useful for auditing user permissions or troubleshooting access issues. 149 | 150 | ```sql+postgres 151 | select 152 | "ID", 153 | "ParentID", 154 | "SobjectType", 155 | "PermissionsModifyAllRecords", 156 | "PermissionsViewAllRecords" 157 | from 158 | "ObjectPermission" 159 | where 160 | "PermissionsRead"; 161 | ``` 162 | 163 | ```sql+sqlite 164 | select 165 | "ID", 166 | "ParentID", 167 | "SobjectType", 168 | "PermissionsModifyAllRecords", 169 | "PermissionsViewAllRecords" 170 | from 171 | "ObjectPermission" 172 | where 173 | "PermissionsRead"; 174 | ``` -------------------------------------------------------------------------------- /docs/tables/salesforce_opportunity_contact_role.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Steampipe Table: salesforce_opportunity_contact_role - Query Salesforce Opportunity Contact Roles using SQL" 3 | description: "Allows users to query Opportunity Contact Roles in Salesforce, providing insights into the role that a contact plays in a specific opportunity." 4 | --- 5 | 6 | # Table: salesforce_opportunity_contact_role - Query Salesforce Opportunity Contact Roles using SQL 7 | 8 | Opportunity Contact Role in Salesforce is a junction object that links Contacts to Opportunities, showing the role that the contact plays in the specific opportunity. This role could be a decision maker, influencer, etc. It provides a way to specify the individuals who are involved in the business deal. 9 | 10 | ## Table Usage Guide 11 | 12 | The `salesforce_opportunity_contact_role` table provides insights into the roles that contacts play in specific opportunities within Salesforce. As a sales manager or business analyst, you can explore details about these roles through this table, including the contact's involvement in the opportunity, their influence level, and other associated metadata. Utilize it to uncover information about the relationships between contacts and opportunities, such as who are the main decision makers or influencers in a particular deal. 13 | 14 | **Important Notes** 15 | - If the `naming_convention` configuration argument is set to `api_native`, please see [API Native Examples](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account#api_native_examples). 16 | 17 | ## Examples 18 | 19 | ### Basic info 20 | Explore which roles are associated with different opportunities in Salesforce to better understand the distribution of responsibilities within your organization. This can help to identify any gaps or overlaps in roles assigned to specific opportunities. 21 | 22 | ```sql+postgres 23 | select 24 | id, 25 | contact_id, 26 | is_primary, 27 | opportunity_id, 28 | stage_name, 29 | role 30 | from 31 | salesforce_opportunity_contact_role; 32 | ``` 33 | 34 | ```sql+sqlite 35 | select 36 | id, 37 | contact_id, 38 | is_primary, 39 | opportunity_id, 40 | stage_name, 41 | role 42 | from 43 | salesforce_opportunity_contact_role; 44 | ``` 45 | 46 | ### List primary opportunity contact roles 47 | Determine the primary roles within your opportunities to better understand your salesforce interactions. This can help identify key contacts and their respective roles, helping to streamline communication and improve sales strategies. 48 | 49 | ```sql+postgres 50 | select 51 | id, 52 | opportunity_id, 53 | contact_id, 54 | is_primary 55 | from 56 | salesforce_opportunity_contact_role 57 | where 58 | is_primary; 59 | ``` 60 | 61 | ```sql+sqlite 62 | select 63 | id, 64 | opportunity_id, 65 | contact_id, 66 | is_primary 67 | from 68 | salesforce_opportunity_contact_role 69 | where 70 | is_primary; 71 | ``` 72 | 73 | ## API Native Examples 74 | 75 | If the `naming_convention` config argument is set to `api_native`, the table and column names will match Salesforce naming conventions. 76 | 77 | ### Basic info (with API Native naming convention) 78 | Explore the primary contacts associated with specific business opportunities. This can help you understand the key individuals involved in each opportunity and their respective roles. 79 | 80 | ```sql+postgres 81 | select 82 | "ID", 83 | "ContactID", 84 | "IsPrimary", 85 | "OpportunityID", 86 | "StageName" 87 | from 88 | "OpportunityContactRole"; 89 | ``` 90 | 91 | ```sql+sqlite 92 | select 93 | "ID", 94 | "ContactID", 95 | "IsPrimary", 96 | "OpportunityID", 97 | "StageName" 98 | from 99 | "OpportunityContactRole"; 100 | ``` 101 | 102 | ### List primary opportunity contact roles (with API Native naming convention) 103 | Identify the primary roles within opportunities to understand their significance and influence within your organization's operations. 104 | 105 | ```sql+postgres 106 | select 107 | "ID", 108 | "ContactID", 109 | "IsPrimary", 110 | "OpportunityID", 111 | "StageName" 112 | from 113 | "OpportunityContactRole" 114 | where 115 | "IsPrimary"; 116 | ``` 117 | 118 | ```sql+sqlite 119 | select 120 | "ID", 121 | "ContactID", 122 | "IsPrimary", 123 | "OpportunityID", 124 | "StageName" 125 | from 126 | "OpportunityContactRole" 127 | where 128 | "IsPrimary"; 129 | ``` 130 | 131 | ### Show opportunity contact roles created in last 30 days 132 | Discover the roles of contacts associated with opportunities that were created in the past month. This could be useful for assessing recent changes in contact roles and understanding their involvement in new opportunities. 133 | 134 | ```sql+postgres 135 | select 136 | "ID", 137 | "ContactID", 138 | "IsPrimary", 139 | "OpportunityID", 140 | "StageName", 141 | "Role" 142 | from 143 | "OpportunityContactRole" 144 | where 145 | "CreatedDate" <= now() - interval '30' day; 146 | ``` 147 | 148 | ```sql+sqlite 149 | select 150 | "ID", 151 | "ContactID", 152 | "IsPrimary", 153 | "OpportunityID", 154 | "StageName", 155 | "Role" 156 | from 157 | "OpportunityContactRole" 158 | where 159 | "CreatedDate" <= datetime('now', '-30 day'); 160 | ``` 161 | 162 | ### Show decision maker opportunity contact roles 163 | Explore which roles in an opportunity are designated as 'Decision Makers'. This can be useful in identifying key individuals within a business opportunity. 164 | 165 | ```sql+postgres 166 | select 167 | "ID", 168 | "ContactID", 169 | "IsPrimary", 170 | "OpportunityID", 171 | "StageName", 172 | "Role" 173 | from 174 | "OpportunityContactRole" 175 | where 176 | "Role" = 'Decision Maker'; 177 | ``` 178 | 179 | ```sql+sqlite 180 | select 181 | "ID", 182 | "ContactID", 183 | "IsPrimary", 184 | "OpportunityID", 185 | "StageName", 186 | "Role" 187 | from 188 | "OpportunityContactRole" 189 | where 190 | "Role" = 'Decision Maker'; 191 | ``` -------------------------------------------------------------------------------- /salesforce/table_salesforce_contact.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" 7 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 8 | ) 9 | 10 | func SalesforceContact(ctx context.Context, dm dynamicMap, config salesforceConfig) *plugin.Table { 11 | tableName := "Contact" 12 | return &plugin.Table{ 13 | Name: "salesforce_contact", 14 | Description: "Represents a contact, which is a person associated with an account.", 15 | List: &plugin.ListConfig{ 16 | Hydrate: listSalesforceObjectsByTable(tableName, dm.salesforceColumns), 17 | KeyColumns: dm.keyColumns, 18 | }, 19 | Get: &plugin.GetConfig{ 20 | Hydrate: getSalesforceObjectbyID(tableName), 21 | KeyColumns: plugin.SingleColumn(checkNameScheme(config, dm.cols)), 22 | }, 23 | Columns: mergeTableColumns(ctx, config, dm.cols, []*plugin.Column{ 24 | // Top columns 25 | {Name: "id", Type: proto.ColumnType_STRING, Description: "ID of the account that's the parent of this contact."}, 26 | {Name: "name", Type: proto.ColumnType_STRING, Description: "The full name of the contact."}, 27 | {Name: "account_id", Type: proto.ColumnType_STRING, Description: "ID of the account that's the parent of this contact."}, 28 | {Name: "email", Type: proto.ColumnType_STRING, Description: "The contact's email address."}, 29 | {Name: "lead_source", Type: proto.ColumnType_STRING, Description: "The lead's source."}, 30 | {Name: "owner_id", Type: proto.ColumnType_STRING, Description: "The ID of the owner of the account associated with this contact."}, 31 | {Name: "title", Type: proto.ColumnType_STRING, Description: "Title of the contact, such as CEO or Vice President."}, 32 | 33 | // Other columns 34 | {Name: "assistant_name", Type: proto.ColumnType_STRING, Description: "The Assistant's Name."}, 35 | {Name: "assistant_phone", Type: proto.ColumnType_STRING, Description: "The Assistant's Phone."}, 36 | {Name: "birthdate", Type: proto.ColumnType_TIMESTAMP, Description: "The contact's birthdate."}, 37 | {Name: "clean_status", Type: proto.ColumnType_STRING, Description: "Indicates the record's clean status."}, 38 | {Name: "created_by_id", Type: proto.ColumnType_STRING, Description: "The Created By ID."}, 39 | {Name: "created_date", Type: proto.ColumnType_TIMESTAMP, Description: "The Created Date."}, 40 | {Name: "department", Type: proto.ColumnType_STRING, Description: "The contact's department."}, 41 | {Name: "description", Type: proto.ColumnType_STRING, Description: "The description of the contact"}, 42 | {Name: "email_bounced_date", Type: proto.ColumnType_TIMESTAMP, Description: "If bounce management is activated and an email sent to the contact bounces, the date and time of the bounce."}, 43 | {Name: "email_bounced_reason", Type: proto.ColumnType_STRING, Description: "If bounce management is activated and an email sent to the contact bounces, the reason for the bounce."}, 44 | {Name: "fax", Type: proto.ColumnType_STRING, Description: "The contact's fax number."}, 45 | {Name: "home_phone", Type: proto.ColumnType_STRING, Description: "The contact's home telephone number."}, 46 | {Name: "individual_id", Type: proto.ColumnType_STRING, Description: "ID of the data privacy record associated with this contact. This field is available if Data Protection and Privacy is enabled."}, 47 | {Name: "is_deleted", Type: proto.ColumnType_BOOL, Description: "Indicates whether the object has been moved to the Recycle Bin (true) or not (false)."}, 48 | {Name: "is_email_bounced", Type: proto.ColumnType_BOOL, Description: "If bounce management is activated and an email is sent to a contact, indicates whether the email bounced (true) or not (false)."}, 49 | {Name: "jigsaw", Type: proto.ColumnType_STRING, Description: "The Data.com Key."}, 50 | {Name: "jigsaw_contact_id", Type: proto.ColumnType_STRING, Description: "References the company's ID in Data.com. If an account has a value in this field, it means that the account was imported from Data.com."}, 51 | {Name: "last_activity_date", Type: proto.ColumnType_TIMESTAMP, Description: "Value is the most recent of either: Due date of the most recent event logged against the record. Due date of the most recently close task associated with the record."}, 52 | {Name: "last_cu_request_date", Type: proto.ColumnType_TIMESTAMP, Description: "The Last Stay-in-Touch Request Date."}, 53 | {Name: "last_cu_update_date", Type: proto.ColumnType_TIMESTAMP, Description: "The Last Stay-in-Touch Save Date."}, 54 | {Name: "last_modified_by_id", Type: proto.ColumnType_STRING, Description: "The Last Modified By ID."}, 55 | {Name: "last_modified_date", Type: proto.ColumnType_TIMESTAMP, Description: "The Last Modified Date."}, 56 | {Name: "last_referenced_date", Type: proto.ColumnType_TIMESTAMP, Description: "The timestamp when the current user last accessed this record, a record related to this record, or a list view."}, 57 | {Name: "last_viewed_date", Type: proto.ColumnType_TIMESTAMP, Description: "The timestamp when the current user last viewed this record or list view. If this value is null, the user might have only accessed this record or list view (LastReferencedDate) but not viewed it."}, 58 | {Name: "master_record_id", Type: proto.ColumnType_STRING, Description: "If this record was deleted as the result of a merge, this field contains the ID of the record that remains."}, 59 | {Name: "mobile_phone", Type: proto.ColumnType_STRING, Description: "Contact's mobile phone number."}, 60 | {Name: "other_phone", Type: proto.ColumnType_STRING, Description: "The other phone of the contact."}, 61 | {Name: "phone", Type: proto.ColumnType_STRING, Description: "Buisness telephone number for the contact."}, 62 | {Name: "photo_url", Type: proto.ColumnType_STRING, Description: "The Photo URL."}, 63 | {Name: "reports_to_id", Type: proto.ColumnType_STRING, Description: "The Reports To ID."}, 64 | {Name: "system_modstamp", Type: proto.ColumnType_TIMESTAMP, Description: "The System Modstamp."}, 65 | 66 | // JSON columns 67 | {Name: "other_address", Type: proto.ColumnType_JSON, Description: "The Other Address."}, 68 | {Name: "mailing_address", Type: proto.ColumnType_JSON, Description: "The Mailing Address."}, 69 | }), 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /docs/tables/salesforce_contract.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Steampipe Table: salesforce_contract - Query Salesforce Contracts using SQL" 3 | description: "Allows users to query Salesforce Contracts, providing details about contracts, including their status, start and end dates, associated accounts, and other related information." 4 | --- 5 | 6 | # Table: salesforce_contract - Query Salesforce Contracts using SQL 7 | 8 | Salesforce Contracts are a record of the agreements between your company and the customers. They contain details such as the contract term (start and end date), contract status, associated account, and other related information. Contracts in Salesforce help to maintain the details of the service or support agreed upon during a sale. 9 | 10 | ## Table Usage Guide 11 | 12 | The `salesforce_contract` table provides insights into contracts within Salesforce. As a Salesforce administrator, you can explore contract-specific details through this table, including the contract's status, its start and end dates, and the associated account. Use it to uncover information about contracts, such as those that are nearing their end dates, or to verify the details of a specific contract. 13 | 14 | **Important Notes** 15 | - If the `naming_convention` configuration argument is set to `api_native`, please see [API Native Examples](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account#api_native_examples). 16 | 17 | ## Examples 18 | 19 | ### Basic info 20 | Gain insights into your company's contractual agreements, including the duration and status, to better manage your business relationships and plan for future engagements. This will assist in understanding the overall contract lifecycle within your organization. 21 | 22 | ```sql+postgres 23 | select 24 | id, 25 | account_id, 26 | contract_number, 27 | contract_term, 28 | end_date, 29 | start_date, 30 | company_signed_date, 31 | status 32 | from 33 | salesforce_contract; 34 | ``` 35 | 36 | ```sql+sqlite 37 | select 38 | id, 39 | account_id, 40 | contract_number, 41 | contract_term, 42 | end_date, 43 | start_date, 44 | company_signed_date, 45 | status 46 | from 47 | salesforce_contract; 48 | ``` 49 | 50 | ### List contracts signed in the last six months 51 | Discover the contracts that have been signed in the past six months to understand the recent business dealings and their status. This can be useful in assessing the volume and nature of recent contractual agreements. 52 | 53 | ```sql+postgres 54 | select 55 | id, 56 | account_id, 57 | contract_number, 58 | contract_term, 59 | end_date, 60 | start_date, 61 | company_signed_date, 62 | status 63 | from 64 | salesforce_contract 65 | where 66 | company_signed_date >= (current_date - interval '6' month); 67 | ``` 68 | 69 | ```sql+sqlite 70 | select 71 | id, 72 | account_id, 73 | contract_number, 74 | contract_term, 75 | end_date, 76 | start_date, 77 | company_signed_date, 78 | status 79 | from 80 | salesforce_contract 81 | where 82 | company_signed_date >= date('now','-6 month'); 83 | ``` 84 | 85 | ### List number of contracts by status 86 | This query allows you to analyze the distribution of contracts within your Salesforce data according to their status. It aids in assessing the overall contract management efficiency and identifying areas that might need attention or improvement. 87 | 88 | ```sql+postgres 89 | select 90 | count(*), 91 | status 92 | from 93 | salesforce_contract 94 | group by 95 | status; 96 | ``` 97 | 98 | ```sql+sqlite 99 | select 100 | count(*), 101 | status 102 | from 103 | salesforce_contract 104 | group by 105 | status; 106 | ``` 107 | 108 | ## API Native Examples 109 | 110 | If the `naming_convention` config argument is set to `api_native`, the table and column names will match Salesforce naming conventions. 111 | 112 | ### Basic info (with API Native naming convention) 113 | Discover the segments that pertain to specific contract details such as term length and status. This can help in understanding the distribution and status of different contracts within an account. 114 | 115 | ```sql+postgres 116 | select 117 | "ID", 118 | "AccountID", 119 | "ContractNumber", 120 | "ContractTerm", 121 | "EndDate", 122 | "StartDate", 123 | "Status" 124 | from 125 | "Contract"; 126 | ``` 127 | 128 | ```sql+sqlite 129 | select 130 | "ID", 131 | "AccountID", 132 | "ContractNumber", 133 | "ContractTerm", 134 | "EndDate", 135 | "StartDate", 136 | "Status" 137 | from 138 | "Contract"; 139 | ``` 140 | 141 | ### List number of contracts by status (with API Native naming convention) 142 | Determine the distribution of contracts based on their status to understand the operational dynamics of your business. This can help you identify areas that may require attention or improvement. 143 | 144 | ```sql+postgres 145 | select 146 | count(*), 147 | "Status" 148 | from 149 | "Contract" 150 | group by 151 | "Status"; 152 | ``` 153 | 154 | ```sql+sqlite 155 | select 156 | count(*), 157 | "Status" 158 | from 159 | "Contract" 160 | group by 161 | "Status"; 162 | ``` 163 | 164 | ### Show draft contracts 165 | Explore which contracts are still in draft status to understand potential upcoming agreements and their terms. This could help in planning resources or assessing future commitments. 166 | 167 | ```sql+postgres 168 | select 169 | "ID", 170 | "AccountID", 171 | "ContractNumber", 172 | "ContractTerm", 173 | "EndDate", 174 | "StartDate", 175 | "Status" 176 | from 177 | "Contract" 178 | where 179 | "Status" = 'Draft'; 180 | ``` 181 | 182 | ```sql+sqlite 183 | select 184 | "ID", 185 | "AccountID", 186 | "ContractNumber", 187 | "ContractTerm", 188 | "EndDate", 189 | "StartDate", 190 | "Status" 191 | from 192 | "Contract" 193 | where 194 | "Status" = 'Draft'; 195 | ``` 196 | 197 | ### Show deleted contracts 198 | Discover the contracts that have been deleted to understand any potential impact on business operations or account management. This can be useful in identifying gaps in service or potential revenue loss. 199 | 200 | ```sql+postgres 201 | select 202 | "ID", 203 | "AccountID", 204 | "ContractNumber", 205 | "ContractTerm", 206 | "EndDate", 207 | "StartDate", 208 | "Status" 209 | from 210 | "Contract" 211 | where 212 | "IsDeleted"; 213 | ``` 214 | 215 | ```sql+sqlite 216 | select 217 | "ID", 218 | "AccountID", 219 | "ContractNumber", 220 | "ContractTerm", 221 | "EndDate", 222 | "StartDate", 223 | "Status" 224 | from 225 | "Contract" 226 | where 227 | "IsDeleted"; 228 | ``` -------------------------------------------------------------------------------- /docs/tables/salesforce_opportunity.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Steampipe Table: salesforce_opportunity - Query Salesforce Opportunities using SQL" 3 | description: "Allows users to query Opportunities in Salesforce, specifically to retrieve details about business deals and their current sales stage, providing insights into sales performance and potential revenue." 4 | --- 5 | 6 | # Table: salesforce_opportunity - Query Salesforce Opportunities using SQL 7 | 8 | Salesforce Opportunity is a component of Salesforce Sales Cloud that allows businesses to manage their sales cycles and deals. It provides a way to track and measure potential revenue, and monitor sales stages, from prospecting to closing. Salesforce Opportunity is instrumental in understanding a company's sales pipeline and forecasting sales. 9 | 10 | ## Table Usage Guide 11 | 12 | The `salesforce_opportunity` table provides insights into Opportunities within Salesforce Sales Cloud. As a sales manager or data analyst, explore opportunity-specific details through this table, including deal value, expected close date, and associated account details. Utilize it to uncover information about sales performance, such as deals in the pipeline, the value of potential revenue, and the progress of deals through sales stages. 13 | 14 | **Important Notes** 15 | - If the `naming_convention` configuration argument is set to `api_native`, please see [API Native Examples](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account#api_native_examples). 16 | 17 | ## Examples 18 | 19 | ### Basic info 20 | Gain insights into your sales opportunities by sorting them based on their stage in the sales process. This helps prioritize opportunities that are closer to closing, improving sales efficiency and forecasting. 21 | 22 | ```sql+postgres 23 | select 24 | id, 25 | name, 26 | amount, 27 | type, 28 | stage_name, 29 | forecast_category, 30 | is_won 31 | from 32 | salesforce_opportunity 33 | order by 34 | stage_name; 35 | ``` 36 | 37 | ```sql+sqlite 38 | select 39 | id, 40 | name, 41 | amount, 42 | type, 43 | stage_name, 44 | forecast_category, 45 | is_won 46 | from 47 | salesforce_opportunity 48 | order by 49 | stage_name; 50 | ``` 51 | 52 | ### List only won opportunities 53 | Explore which sales opportunities have been successful to understand the areas of high revenue generation. This can help in strategizing future sales approaches. 54 | 55 | ```sql+postgres 56 | select 57 | id, 58 | name, 59 | amount, 60 | type, 61 | is_won 62 | from 63 | salesforce_opportunity 64 | where 65 | is_won 66 | order by 67 | amount; 68 | ``` 69 | 70 | ```sql+sqlite 71 | select 72 | id, 73 | name, 74 | amount, 75 | type, 76 | is_won 77 | from 78 | salesforce_opportunity 79 | where 80 | is_won 81 | order by 82 | amount; 83 | ``` 84 | 85 | ### List number of opportunities with respective stage 86 | Determine the distribution of sales opportunities across different stages. This can help you understand where most of your opportunities are concentrated, allowing you to strategize and allocate resources effectively. 87 | 88 | ```sql+postgres 89 | select 90 | count(*), 91 | stage_name 92 | from 93 | salesforce_opportunity 94 | group by 95 | stage_name; 96 | ``` 97 | 98 | ```sql+sqlite 99 | select 100 | count(*), 101 | stage_name 102 | from 103 | salesforce_opportunity 104 | group by 105 | stage_name; 106 | ``` 107 | 108 | ## API Native Examples 109 | 110 | If the `naming_convention` config argument is set to `api_native`, the table and column names will match Salesforce naming conventions. 111 | 112 | ### Basic info (with API Native naming convention) 113 | Explore the opportunities in your pipeline, focusing on their names, amounts, types, and forecast categories, to gain insights into their stages. This is useful for understanding the distribution and potential value of your opportunities, which can inform your sales strategy and prioritization. 114 | 115 | ```sql+postgres 116 | select 117 | "ID", 118 | "Name", 119 | "Amount", 120 | "Type", 121 | "StageName", 122 | "ForecastCategory" 123 | from 124 | "Opportunity" 125 | order by 126 | "StageName"; 127 | ``` 128 | 129 | ```sql+sqlite 130 | select 131 | "ID", 132 | "Name", 133 | "Amount", 134 | "Type", 135 | "StageName", 136 | "ForecastCategory" 137 | from 138 | "Opportunity" 139 | order by 140 | "StageName"; 141 | ``` 142 | 143 | ### List only won opportunities (with API Native naming convention) 144 | Discover the segments that have been successful by identifying instances where opportunities have been won. This can help assess the elements within these successful opportunities to strategize for future prospects. 145 | 146 | ```sql+postgres 147 | select 148 | "ID", 149 | "Name", 150 | "Amount", 151 | "Type", 152 | "StageName", 153 | "ForecastCategory", 154 | "IsWon" 155 | from 156 | "Opportunity" 157 | where 158 | "IsWon" 159 | order by 160 | "Amount"; 161 | ``` 162 | 163 | ```sql+sqlite 164 | select 165 | "ID", 166 | "Name", 167 | "Amount", 168 | "Type", 169 | "StageName", 170 | "ForecastCategory", 171 | "IsWon" 172 | from 173 | "Opportunity" 174 | where 175 | "IsWon" 176 | order by 177 | "Amount"; 178 | ``` 179 | 180 | ### List closed opportunities 181 | Explore which business opportunities have already reached their close date. This can help in assessing past performance and strategizing for future opportunities. 182 | 183 | ```sql+postgres 184 | select 185 | "ID", 186 | "Name", 187 | "Amount", 188 | "Type", 189 | "StageName", 190 | "ForecastCategory" 191 | from 192 | "Opportunity" 193 | where 194 | "CloseDate" <= now(); 195 | ``` 196 | 197 | ```sql+sqlite 198 | select 199 | "ID", 200 | "Name", 201 | "Amount", 202 | "Type", 203 | "StageName", 204 | "ForecastCategory" 205 | from 206 | "Opportunity" 207 | where 208 | "CloseDate" <= datetime('now'); 209 | ``` 210 | 211 | ### List opportunities with open activity 212 | Explore which opportunities have an open activity to determine areas for potential business growth. This can help in identifying instances where immediate action is required, aiding in effective decision making. 213 | 214 | ```sql+postgres 215 | select 216 | "ID", 217 | "Name", 218 | "Amount", 219 | "Type", 220 | "StageName", 221 | "ForecastCategory" 222 | from 223 | "Opportunity" 224 | where 225 | "HasOpenActivity"; 226 | ``` 227 | 228 | ```sql+sqlite 229 | select 230 | "ID", 231 | "Name", 232 | "Amount", 233 | "Type", 234 | "StageName", 235 | "ForecastCategory" 236 | from 237 | "Opportunity" 238 | where 239 | "HasOpenActivity"; 240 | ``` -------------------------------------------------------------------------------- /docs/tables/salesforce_pricebook.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Steampipe Table: salesforce_pricebook - Query Salesforce Pricebooks using SQL" 3 | description: "Allows users to query Pricebooks in Salesforce, specifically the list of all available pricebooks and their associated details." 4 | --- 5 | 6 | # Table: salesforce_pricebook - Query Salesforce Pricebooks using SQL 7 | 8 | A Salesforce Pricebook is a list of products and their prices available in Salesforce. It is a key component of Salesforce's product and price management, allowing businesses to manage different prices for the same product. Pricebooks can be specific to an organization, a business unit, or even a specific customer, providing flexibility in pricing strategies. 9 | 10 | ## Table Usage Guide 11 | 12 | The `salesforce_pricebook` table provides insights into Pricebooks within Salesforce. As a sales manager or a business analyst, explore pricebook-specific details through this table, including related products, standard prices, and associated metadata. Utilize it to uncover information about pricing strategies, such as those specific to different business units or customers, and the verification of pricing policies. 13 | 14 | **Important Notes** 15 | - If the `naming_convention` configuration argument is set to `api_native`, please see [API Native Examples](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account#api_native_examples). 16 | - If the naming_convention parameter is set to api_native in the config file, then the table and column names will match what’s in Salesforce. For instance, the query `select name, is_active from salesforce_pricebook` would become `select "Name", "IsActive" from "Pricebook2"`. 17 | 18 | ## Examples 19 | 20 | ### Basic info 21 | Analyze the settings to understand the status and creation details of price books in Salesforce. This is useful in assessing the active price books and their creators, which can help in sales strategy planning and management. 22 | 23 | ```sql+postgres 24 | select 25 | name, 26 | is_active, 27 | is_standard, 28 | created_by_id, 29 | created_date, 30 | description 31 | from 32 | salesforce_pricebook; 33 | ``` 34 | 35 | ```sql+sqlite 36 | select 37 | name, 38 | is_active, 39 | is_standard, 40 | created_by_id, 41 | created_date, 42 | description 43 | from 44 | salesforce_pricebook; 45 | ``` 46 | 47 | ### List standard price books 48 | Explore the active standard price books in your Salesforce account. This can help you understand which price books have been created and are currently in use, offering insights into your pricing strategies and structures. 49 | 50 | ```sql+postgres 51 | select 52 | name, 53 | is_active, 54 | is_standard, 55 | created_by_id, 56 | created_date, 57 | description 58 | from 59 | salesforce_pricebook 60 | where 61 | is_standard; 62 | ``` 63 | 64 | ```sql+sqlite 65 | select 66 | name, 67 | is_active, 68 | is_standard, 69 | created_by_id, 70 | created_date, 71 | description 72 | from 73 | salesforce_pricebook 74 | where 75 | is_standard; 76 | ``` 77 | 78 | ### List active price books 79 | Determine the active price books in your Salesforce data. This can help you understand which pricing structures are currently in use, aiding in revenue management and strategic planning. 80 | 81 | ```sql+postgres 82 | select 83 | name, 84 | is_active, 85 | is_standard, 86 | created_by_id, 87 | created_date, 88 | description 89 | from 90 | salesforce_pricebook 91 | where 92 | is_active; 93 | ``` 94 | 95 | ```sql+sqlite 96 | select 97 | name, 98 | is_active, 99 | is_standard, 100 | created_by_id, 101 | created_date, 102 | description 103 | from 104 | salesforce_pricebook 105 | where 106 | is_active; 107 | ``` 108 | 109 | ## API Native Examples 110 | 111 | If the `naming_convention` config argument is set to `api_native`, the table and column names will match Salesforce naming conventions. 112 | 113 | ### Basic info (with API Native naming convention) 114 | Explore the active and standard status of different price books in your database, along with their creation details and descriptions. This can help understand the variety and usage of different price books in your system. 115 | 116 | ```sql+postgres 117 | select 118 | "Name", 119 | "IsActive", 120 | "IsStandard", 121 | "CreatedById", 122 | "CreatedDate", 123 | "Description" 124 | from 125 | "Pricebook2"; 126 | ``` 127 | 128 | ```sql+sqlite 129 | select 130 | "Name", 131 | "IsActive", 132 | "IsStandard", 133 | "CreatedById", 134 | "CreatedDate", 135 | "Description" 136 | from 137 | "Pricebook2"; 138 | ``` 139 | 140 | ### List standard price books (with API Native naming convention) 141 | Explore which standard price books are currently active and when they were created to understand their usage and relevance. Similarly, review the archived price books to determine which ones are no longer in use and when they were archived, providing insights into the company's pricing history and potential strategies. 142 | 143 | ```sql+postgres 144 | select 145 | "Name", 146 | "IsActive", 147 | "IsStandard", 148 | "CreatedById", 149 | "CreatedDate", 150 | "Description" 151 | from 152 | "Pricebook2" 153 | where 154 | "IsStandard"; 155 | ``` 156 | 157 | ```sql+sqlite 158 | select 159 | "Name", 160 | "IsActive", 161 | "IsStandard", 162 | "CreatedById", 163 | "CreatedDate", 164 | "Description" 165 | from 166 | "Pricebook2" 167 | where 168 | "IsStandard" = 1; 169 | ``` 170 | 171 | ## Show archived price books 172 | 173 | ```sql+postgres 174 | select 175 | "Name", 176 | "IsActive", 177 | "IsStandard", 178 | "CreatedById", 179 | "CreatedDate", 180 | "Description" 181 | from 182 | "Pricebook2" 183 | where 184 | "IsArchived"; 185 | ``` 186 | 187 | ```sql+sqlite 188 | select 189 | "Name", 190 | "IsActive", 191 | "IsStandard", 192 | "CreatedById", 193 | "CreatedDate", 194 | "Description" 195 | from 196 | "Pricebook2" 197 | where 198 | "IsArchived"; 199 | ``` 200 | 201 | ### Show deleted price books 202 | Discover the segments that have been marked as deleted in your pricing system. This information can be used to track changes, assess the impact of deletions, and potentially recover lost data. 203 | 204 | ```sql+postgres 205 | select 206 | "Name", 207 | "IsActive", 208 | "IsStandard", 209 | "CreatedById", 210 | "CreatedDate", 211 | "Description" 212 | from 213 | "Pricebook2" 214 | where 215 | "IsDeleted"; 216 | ``` 217 | 218 | ```sql+sqlite 219 | select 220 | "Name", 221 | "IsActive", 222 | "IsStandard", 223 | "CreatedById", 224 | "CreatedDate", 225 | "Description" 226 | from 227 | "Pricebook2" 228 | where 229 | "IsDeleted"; 230 | ``` -------------------------------------------------------------------------------- /docs/tables/salesforce_user.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Steampipe Table: salesforce_user - Query Salesforce Users using SQL" 3 | description: "Allows users to query Users in Salesforce, providing detailed information about each user's profile, role, and status." 4 | --- 5 | 6 | # Table: salesforce_user - Query Salesforce Users using SQL 7 | 8 | Salesforce Users are the individuals who have log in access to the Salesforce organization. They are associated with a unique username and profile that determines the level of access they have within the organization. User information includes details about the user's name, email, profile, role, and status among other attributes. 9 | 10 | ## Table Usage Guide 11 | 12 | The `salesforce_user` table provides insights into individual users within Salesforce. As a Salesforce administrator or auditor, explore user-specific details through this table, including their profile, role, and status. Utilize it to uncover information about users, such as their level of access, the roles they are assigned, and their activity status. 13 | 14 | **Important Notes** 15 | - If the `naming_convention` configuration argument is set to `api_native`, please see [API Native Examples](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account#api_native_examples). 16 | - If the naming_convention parameter is set to api_native in the config file, then the table and column names will match what’s in Salesforce. For instance, the query `select username, alias from salesforce_user` would become `select "Username", "Alias" from "User"`. 17 | 18 | ## Examples 19 | 20 | ### Basic info 21 | Discover the segments of users in your Salesforce platform, gaining insights into their activity status and last login date. This can be beneficial for assessing user engagement and identifying inactive users. 22 | 23 | ```sql+postgres 24 | select 25 | username, 26 | alias, 27 | user_type, 28 | is_active, 29 | last_login_date 30 | from 31 | salesforce_user; 32 | ``` 33 | 34 | ```sql+sqlite 35 | select 36 | username, 37 | alias, 38 | user_type, 39 | is_active, 40 | last_login_date 41 | from 42 | salesforce_user; 43 | ``` 44 | 45 | ### List active users 46 | Explore which users are currently active in your Salesforce environment. This is useful for understanding user engagement and identifying any potential inactive accounts. 47 | 48 | ```sql+postgres 49 | select 50 | username, 51 | alias, 52 | user_type, 53 | is_active, 54 | last_login_date 55 | from 56 | salesforce_user 57 | where 58 | is_active; 59 | ``` 60 | 61 | ```sql+sqlite 62 | select 63 | username, 64 | alias, 65 | user_type, 66 | is_active, 67 | last_login_date 68 | from 69 | salesforce_user 70 | where 71 | is_active; 72 | ``` 73 | 74 | ### List standard users 75 | Explore which standard users are active within your Salesforce platform. This query is particularly useful in understanding user activity and identifying any inactive accounts that may need attention. 76 | 77 | ```sql+postgres 78 | select 79 | username, 80 | alias, 81 | user_type, 82 | is_active, 83 | last_login_date 84 | from 85 | salesforce_user 86 | where 87 | user_type = 'Standard'; 88 | ``` 89 | 90 | ```sql+sqlite 91 | select 92 | username, 93 | alias, 94 | user_type, 95 | is_active, 96 | last_login_date 97 | from 98 | salesforce_user 99 | where 100 | user_type = 'Standard'; 101 | ``` 102 | 103 | ### List user designated as forecast managers 104 | Gain insights into your Salesforce users who have been enabled to manage forecasts. This allows you to better understand who in your team has the authority to manipulate and oversee forecasting data. 105 | 106 | ```sql+postgres 107 | select 108 | id, 109 | username, 110 | user_type, 111 | forecast_enabled 112 | from 113 | salesforce_user 114 | where 115 | forecast_enabled; 116 | ``` 117 | 118 | ```sql+sqlite 119 | select 120 | id, 121 | username, 122 | user_type, 123 | forecast_enabled 124 | from 125 | salesforce_user 126 | where 127 | forecast_enabled = 1; 128 | ``` 129 | 130 | ## API Native Examples 131 | 132 | If the `naming_convention` config argument is set to `api_native`, the table and column names will match Salesforce naming conventions. 133 | 134 | ### Basic info (with API Native naming convention) 135 | Explore which users are active and when they last logged in to effectively manage user access and understand usage patterns. This is useful for maintaining security, optimizing user experience, and making data-driven decisions. 136 | 137 | ```sql+postgres 138 | select 139 | "Username", 140 | "Alias", 141 | "UserType", 142 | "IsActive", 143 | "LastLoginDate" 144 | from 145 | "User"; 146 | ``` 147 | 148 | ```sql+sqlite 149 | select 150 | "Username", 151 | "Alias", 152 | "UserType", 153 | "IsActive", 154 | "LastLoginDate" 155 | from 156 | "User"; 157 | ``` 158 | 159 | ### List active users (with API Native naming convention) 160 | Explore which users are currently active and when they last logged in, helping to monitor user activity and understand usage patterns. 161 | 162 | ```sql+postgres 163 | select 164 | "Username", 165 | "Alias", 166 | "UserType", 167 | "IsActive", 168 | "LastLoginDate" 169 | from 170 | "User" 171 | where 172 | "IsActive"; 173 | ``` 174 | 175 | ```sql+sqlite 176 | select 177 | "Username", 178 | "Alias", 179 | "UserType", 180 | "IsActive", 181 | "LastLoginDate" 182 | from 183 | "User" 184 | where 185 | "IsActive" = 1; 186 | ``` 187 | 188 | ### List guest users 189 | Explore which users in your system are classified as 'Guests'. This is useful for identifying potential security risks or for auditing user access privileges. 190 | 191 | ```sql+postgres 192 | select 193 | "Username", 194 | "Alias", 195 | "UserType", 196 | "IsActive", 197 | "LastLoginDate" 198 | from 199 | "User" 200 | where 201 | "UserType" = 'Guest'; 202 | ``` 203 | 204 | ```sql+sqlite 205 | select 206 | "Username", 207 | "Alias", 208 | "UserType", 209 | "IsActive", 210 | "LastLoginDate" 211 | from 212 | "User" 213 | where 214 | "UserType" = 'Guest'; 215 | ``` 216 | 217 | ### List users who logged-in in last 30 days 218 | Discover the segments of users who have been active within the past month. This is useful for understanding user engagement and activity patterns over time. 219 | 220 | ```sql+postgres 221 | select 222 | "Username", 223 | "Alias", 224 | "UserType", 225 | "IsActive", 226 | "LastLoginDate" 227 | from 228 | "User" 229 | where 230 | "LastLoginDate" <= now() - interval '30' day; 231 | ``` 232 | 233 | ```sql+sqlite 234 | select 235 | "Username", 236 | "Alias", 237 | "UserType", 238 | "IsActive", 239 | "LastLoginDate" 240 | from 241 | "User" 242 | where 243 | "LastLoginDate" <= datetime('now', '-30 day'); 244 | ``` -------------------------------------------------------------------------------- /docs/tables/salesforce_permission_set.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Steampipe Table: salesforce_permission_set - Query Salesforce Permission Sets using SQL" 3 | description: "Allows users to query Salesforce Permission Sets, providing insights into the permissions and access settings within a Salesforce organization." 4 | --- 5 | 6 | # Table: salesforce_permission_set - Query Salesforce Permission Sets using SQL 7 | 8 | Salesforce Permission Sets are a flexible and granular means of assigning permissions and access settings within a Salesforce organization. They allow you to extend user's functional access without changing their roles or profiles. Permission Sets can be used to grant additional permissions and access settings to users, on top of what their profile provides. 9 | 10 | ## Table Usage Guide 11 | 12 | The `salesforce_permission_set` table provides insights into Salesforce Permission Sets within a Salesforce organization. As a Salesforce administrator, explore permission set-specific details through this table, including assigned permissions, access settings, and associated metadata. Utilize it to uncover information about permission sets, such as those with specific user access, the permissions associated with each set, and the verification of access settings. 13 | 14 | **Important Notes** 15 | - If the `naming_convention` configuration argument is set to `api_native`, please see [API Native Examples](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account#api_native_examples). 16 | - This table has one field for each permission with the pattern `permissions_permission_name`, e.g., `permissions_edit_task`. If true, users assigned to this permission set have the named permission. The number of fields varies depending on the permissions for the organization and license type. 17 | 18 | ## Examples 19 | 20 | ### Basic info 21 | Explore which permissions are custom-made within your Salesforce environment. This can help you better manage user access and understand the creation timeline of these permissions. 22 | 23 | ```sql+postgres 24 | select 25 | id, 26 | name, 27 | label, 28 | description, 29 | is_custom, 30 | created_date, 31 | from 32 | salesforce_permission_set 33 | ``` 34 | 35 | ```sql+sqlite 36 | select 37 | id, 38 | name, 39 | label, 40 | description, 41 | is_custom, 42 | created_date 43 | from 44 | salesforce_permission_set 45 | ``` 46 | 47 | ### List non-custom permission sets 48 | Explore which permission sets in your Salesforce environment are not custom-made. This helps to understand the default permissions given and aids in maintaining security standards. 49 | 50 | ```sql+postgres 51 | select 52 | id, 53 | name, 54 | label, 55 | description, 56 | is_custom, 57 | created_date, 58 | from 59 | salesforce_permission_set 60 | where 61 | not is_custom; 62 | ``` 63 | 64 | ```sql+sqlite 65 | select 66 | id, 67 | name, 68 | label, 69 | description, 70 | is_custom, 71 | created_date 72 | from 73 | salesforce_permission_set 74 | where 75 | not is_custom; 76 | ``` 77 | 78 | ### List permission sets that contain the "Modify All Data" permission 79 | Explore which permission sets in Salesforce have been granted the capability to modify all data. This is useful to identify potential security risks and ensure only appropriate roles have such extensive permissions. 80 | 81 | ```sql+postgres 82 | select 83 | id, 84 | name, 85 | label, 86 | description, 87 | is_custom, 88 | created_date, 89 | permissions_modify_all_data 90 | from 91 | salesforce_permission_set 92 | where 93 | permissions_modify_all_data; 94 | ``` 95 | 96 | ```sql+sqlite 97 | select 98 | id, 99 | name, 100 | label, 101 | description, 102 | is_custom, 103 | created_date, 104 | permissions_modify_all_data 105 | from 106 | salesforce_permission_set 107 | where 108 | permissions_modify_all_data; 109 | ``` 110 | 111 | ## API Native Examples 112 | 113 | If the `naming_convention` config argument is set to `api_native`, the table and column names will match Salesforce naming conventions. 114 | 115 | ### Basic info (with API Native naming convention) 116 | Explore the basic details of your permission sets to understand their custom status and creation date. This can help you manage and organize your permission sets effectively. 117 | 118 | ```sql+postgres 119 | select 120 | "ID", 121 | "Name", 122 | "Label", 123 | "Description", 124 | "IsCustom", 125 | "CreatedDate" 126 | from 127 | "PermissionSet"; 128 | ``` 129 | 130 | ```sql+sqlite 131 | select 132 | "ID", 133 | "Name", 134 | "Label", 135 | "Description", 136 | "IsCustom", 137 | "CreatedDate" 138 | from 139 | "PermissionSet"; 140 | ``` 141 | 142 | ### List non-custom permission sets (with API Native naming convention) 143 | Discover the segments that consist of non-custom permission sets. This can be useful in understanding the default sets provided by the platform and to ensure they align with your organization's security guidelines. 144 | 145 | ```sql+postgres 146 | select 147 | "ID", 148 | "Name", 149 | "Label", 150 | "Description", 151 | "IsCustom", 152 | "CreatedDate" 153 | from 154 | "PermissionSet" 155 | where 156 | not "IsCustom"; 157 | ``` 158 | 159 | ```sql+sqlite 160 | select 161 | "ID", 162 | "Name", 163 | "Label", 164 | "Description", 165 | "IsCustom", 166 | "CreatedDate" 167 | from 168 | "PermissionSet" 169 | where 170 | "IsCustom" = 0; 171 | ``` 172 | 173 | ### Show permission sets created in last 30 days 174 | Discover the segments that have recently updated their access rights by focusing on those that have made changes within the past month. This is useful for maintaining security and ensuring that permissions are up-to-date. 175 | 176 | ```sql+postgres 177 | select 178 | "ID", 179 | "Name", 180 | "Label", 181 | "Description", 182 | "IsCustom", 183 | "CreatedDate" 184 | from 185 | "PermissionSet" 186 | where 187 | "CreatedDate" <= now() - interval '30' day; 188 | ``` 189 | 190 | ```sql+sqlite 191 | select 192 | "ID", 193 | "Name", 194 | "Label", 195 | "Description", 196 | "IsCustom", 197 | "CreatedDate" 198 | from 199 | "PermissionSet" 200 | where 201 | "CreatedDate" <= datetime('now', '-30 day'); 202 | ``` 203 | 204 | ### List permission sets where activation required 205 | Discover the segments that require activation within your permission sets. This can help you identify areas where additional steps may be needed before the permission set can be used, improving your system's security and compliance. 206 | 207 | ```sql+postgres 208 | select 209 | "ID", 210 | "Name", 211 | "Label", 212 | "Description", 213 | "IsCustom", 214 | "CreatedDate" 215 | from 216 | "PermissionSet" 217 | where 218 | "HasActivationRequired"; 219 | ``` 220 | 221 | ```sql+sqlite 222 | select 223 | "ID", 224 | "Name", 225 | "Label", 226 | "Description", 227 | "IsCustom", 228 | "CreatedDate" 229 | from 230 | "PermissionSet" 231 | where 232 | "HasActivationRequired" = 1; 233 | ``` -------------------------------------------------------------------------------- /docs/tables/salesforce_account.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Steampipe Table: salesforce_account - Query Salesforce Accounts using SQL" 3 | description: "Allows users to query Salesforce Accounts, providing insights into customer account details and related information." 4 | --- 5 | 6 | # Table: salesforce_account - Query Salesforce Accounts using SQL 7 | 8 | Salesforce Accounts are companies or individuals that are involved in a business relationship. These can include customers, competitors, and partners. Accounts are used to store information such as name, address, and phone numbers, for easy reference. 9 | 10 | ## Table Usage Guide 11 | 12 | The `salesforce_account` table provides insights into Salesforce Accounts. As a Sales or CRM Manager, explore account-specific details through this table, including name, address, and phone numbers. Utilize it to uncover information about accounts, such as those with recent activities, the relationships between accounts, and the verification of account details. 13 | 14 | **Important Notes** 15 | - If the `naming_convention` configuration argument is set to `api_native`, please see [API Native Examples](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account#api_native_examples). 16 | 17 | ## Examples 18 | 19 | ### Basic info 20 | Explore the general information about your Salesforce accounts, such as their names, descriptions, annual revenues, ownership types, industries, creation dates, ratings, and websites. This can help you gain insights into your accounts' performance, their industries, and how they have been rated over time. 21 | 22 | ```sql+postgres 23 | select 24 | id, 25 | name, 26 | description, 27 | annual_revenue, 28 | ownership, 29 | industry, 30 | created_date, 31 | rating, 32 | website 33 | from 34 | salesforce_account; 35 | ``` 36 | 37 | ```sql+sqlite 38 | select 39 | id, 40 | name, 41 | description, 42 | annual_revenue, 43 | ownership, 44 | industry, 45 | created_date, 46 | rating, 47 | website 48 | from 49 | salesforce_account; 50 | ``` 51 | 52 | ### List number of accounts by industry type 53 | Discover the segments that each industry occupies in your Salesforce accounts. This can help you understand the distribution of your accounts across different industries, providing valuable insights for business strategy planning and decision making. 54 | 55 | ```sql+postgres 56 | select 57 | count(*), 58 | industry 59 | from 60 | salesforce_account 61 | group by 62 | industry; 63 | ``` 64 | 65 | ```sql+sqlite 66 | select 67 | count(*), 68 | industry 69 | from 70 | salesforce_account 71 | group by 72 | industry; 73 | ``` 74 | 75 | ### List number of accounts by ownership 76 | Explore the distribution of accounts based on ownership to better understand the structure of your Salesforce accounts. This can help in assessing the balance of account ownership and strategizing future sales and marketing efforts. 77 | 78 | ```sql+postgres 79 | select 80 | count(*), 81 | ownership 82 | from 83 | salesforce_account 84 | group by 85 | ownership; 86 | ``` 87 | 88 | ```sql+sqlite 89 | select 90 | count(*), 91 | ownership 92 | from 93 | salesforce_account 94 | group by 95 | ownership; 96 | ``` 97 | 98 | ### List accounts with hot rating 99 | This query can be used to identify high-priority accounts in your Salesforce database by finding those labeled with a 'Hot' rating. This can help sales teams focus their efforts on the most promising leads, improving efficiency and potentially increasing sales. 100 | 101 | ```sql+postgres 102 | select 103 | id, 104 | name, 105 | description, 106 | annual_revenue, 107 | ownership, 108 | industry, 109 | created_date, 110 | rating, 111 | website 112 | from 113 | salesforce_account 114 | where 115 | rating = 'Hot' 116 | ``` 117 | 118 | ```sql+sqlite 119 | select 120 | id, 121 | name, 122 | description, 123 | annual_revenue, 124 | ownership, 125 | industry, 126 | created_date, 127 | rating, 128 | website 129 | from 130 | salesforce_account 131 | where 132 | rating = 'Hot' 133 | ``` 134 | 135 | ## API Native Examples 136 | 137 | If the `naming_convention` config argument is set to `api_native`, the table and column names will match Salesforce naming conventions. 138 | 139 | ### Basic info (with API Native naming convention) 140 | Gain insights into various aspects of your business accounts such as revenue, ownership, industry type, and rating. This query is useful for a comprehensive overview, helping in strategic decision-making and performance evaluation. 141 | 142 | ```sql+postgres 143 | select 144 | "ID", 145 | "Name", 146 | "Description", 147 | "AnnualRevenue", 148 | "Ownership", 149 | "Industry", 150 | "Rating" 151 | from 152 | "Account"; 153 | ``` 154 | 155 | ```sql+sqlite 156 | select 157 | "ID", 158 | "Name", 159 | "Description", 160 | "AnnualRevenue", 161 | "Ownership", 162 | "Industry", 163 | "Rating" 164 | from 165 | "Account"; 166 | ``` 167 | 168 | ### List number of accounts by industry type (with API Native naming convention) 169 | Determine the distribution of accounts across different industry types. This can be useful for understanding the diversity of your client base and tailoring your services accordingly. 170 | 171 | ```sql+postgres 172 | select 173 | count(*), 174 | "Industry" 175 | from 176 | "Account" 177 | group by 178 | "Industry"; 179 | ``` 180 | 181 | ```sql+sqlite 182 | select 183 | count(*), 184 | "Industry" 185 | from 186 | "Account" 187 | group by 188 | "Industry"; 189 | ``` 190 | 191 | ### Show details about the turbot account 192 | Gain insights into the Turbot account's details such as annual revenue, ownership, industry, and rating to better understand its financial and industrial standing. 193 | 194 | ```sql+postgres 195 | select 196 | "ID", 197 | "Name", 198 | "Description", 199 | "AnnualRevenue", 200 | "Ownership", 201 | "Industry", 202 | "Rating" 203 | from 204 | "Account" 205 | where 206 | "Name" = 'turbot'; 207 | ``` 208 | 209 | ```sql+sqlite 210 | select 211 | "ID", 212 | "Name", 213 | "Description", 214 | "AnnualRevenue", 215 | "Ownership", 216 | "Industry", 217 | "Rating" 218 | from 219 | "Account" 220 | where 221 | "Name" = 'turbot'; 222 | ``` 223 | 224 | ### Show customer accounts 225 | Explore which customer accounts exist in your database to gain insights into their annual revenue, industry, and rating. This can help in understanding the financial health and industry distribution of your customer base. 226 | 227 | ```sql+postgres 228 | select 229 | "ID", 230 | "Name", 231 | "Description", 232 | "AnnualRevenue", 233 | "Ownership", 234 | "Industry", 235 | "Rating" 236 | from 237 | "Account" 238 | where 239 | "Type" = 'Customer'; 240 | ``` 241 | 242 | ```sql+sqlite 243 | select 244 | "ID", 245 | "Name", 246 | "Description", 247 | "AnnualRevenue", 248 | "Ownership", 249 | "Industry", 250 | "Rating" 251 | from 252 | "Account" 253 | where 254 | "Type" = 'Customer'; 255 | ``` -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## v1.2.0 [2025-10-13] 2 | 3 | _Dependencies_ 4 | 5 | - Recompiled plugin with Go version `1.24`. ([#81](https://github.com/turbot/steampipe-plugin-salesforce/pull/81)) 6 | - Recompiled plugin with [steampipe-plugin-sdk v5.13.1](https://github.com/turbot/steampipe-plugin-sdk/blob/develop/CHANGELOG.md#v5131-2025-09-25) that addresses critical and high vulnerabilities in dependent packages. ([#85](https://github.com/turbot/steampipe-plugin-salesforce/pull/85)) 7 | 8 | ## v1.1.1 [2025-04-18] 9 | 10 | _Bug fixes_ 11 | 12 | - Fixed Linux AMD64 plugin build failures for `Postgres 14 FDW`, `Postgres 15 FDW`, and `SQLite Extension` by upgrading GitHub Actions runners from `ubuntu-20.04` to `ubuntu-22.04`. 13 | 14 | ## v1.1.0 [2025-04-17] 15 | 16 | _Dependencies_ 17 | 18 | - Recompiled plugin with Go version `1.23.1`. ([#72](https://github.com/turbot/steampipe-plugin-salesforce/pull/72)) 19 | - Recompiled plugin with [steampipe-plugin-sdk v5.11.5](https://github.com/turbot/steampipe-plugin-sdk/blob/v5.11.5/CHANGELOG.md#v5115-2025-03-31) that addresses critical and high vulnerabilities in dependent packages. ([#72](https://github.com/turbot/steampipe-plugin-salesforce/pull/72)) 20 | 21 | ## v1.0.0 [2024-10-22] 22 | 23 | There are no significant changes in this plugin version; it has been released to align with [Steampipe's v1.0.0](https://steampipe.io/changelog/steampipe-cli-v1-0-0) release. This plugin adheres to [semantic versioning](https://semver.org/#semantic-versioning-specification-semver), ensuring backward compatibility within each major version. 24 | 25 | _Dependencies_ 26 | 27 | - Recompiled plugin with Go version `1.22`. ([#61](https://github.com/turbot/steampipe-plugin-salesforce/pull/61)) 28 | - Recompiled plugin with [steampipe-plugin-sdk v5.10.4](https://github.com/turbot/steampipe-plugin-sdk/blob/develop/CHANGELOG.md#v5104-2024-08-29) that fixes logging in the plugin export tool. ([#61](https://github.com/turbot/steampipe-plugin-salesforce/pull/61)) 29 | 30 | ## v0.7.0 [2023-12-12] 31 | 32 | _What's new?_ 33 | 34 | - The plugin can now be downloaded and used with the [Steampipe CLI](https://steampipe.io/docs), as a [Postgres FDW](https://steampipe.io/docs/steampipe_postgres/overview), as a [SQLite extension](https://steampipe.io/docs//steampipe_sqlite/overview) and as a standalone [exporter](https://steampipe.io/docs/steampipe_export/overview). ([#43](https://github.com/turbot/steampipe-plugin-salesforce/pull/43)) 35 | - The table docs have been updated to provide corresponding example queries for Postgres FDW and SQLite extension. ([#43](https://github.com/turbot/steampipe-plugin-salesforce/pull/43)) 36 | - Docs license updated to match Steampipe [CC BY-NC-ND license](https://github.com/turbot/steampipe-plugin-salesforce/blob/main/docs/LICENSE). ([#43](https://github.com/turbot/steampipe-plugin-salesforce/pull/43)) 37 | 38 | _Dependencies_ 39 | 40 | - Recompiled plugin with [steampipe-plugin-sdk v5.8.0](https://github.com/turbot/steampipe-plugin-sdk/blob/main/CHANGELOG.md#v580-2023-12-11) that includes plugin server encapsulation for in-process and GRPC usage, adding Steampipe Plugin SDK version to `_ctx` column, and fixing connection and potential divide-by-zero bugs. ([#42](https://github.com/turbot/steampipe-plugin-salesforce/pull/42)) 41 | 42 | ## v0.6.1 [2023-10-04] 43 | 44 | _Dependencies_ 45 | 46 | - Recompiled plugin with [steampipe-plugin-sdk v5.6.2](https://github.com/turbot/steampipe-plugin-sdk/blob/main/CHANGELOG.md#v562-2023-10-03) which prevents nil pointer reference errors for implicit hydrate configs. ([#33](https://github.com/turbot/steampipe-plugin-salesforce/pull/33)) 47 | 48 | ## v0.6.0 [2023-10-02] 49 | 50 | _Dependencies_ 51 | 52 | - Upgraded to [steampipe-plugin-sdk v5.6.1](https://github.com/turbot/steampipe-plugin-sdk/blob/main/CHANGELOG.md#v561-2023-09-29) with support for rate limiters. ([#30](https://github.com/turbot/steampipe-plugin-salesforce/pull/30)) 53 | - Recompiled plugin with Go version `1.21`. ([#30](https://github.com/turbot/steampipe-plugin-salesforce/pull/30)) 54 | 55 | ## v0.5.0 [2023-08-24] 56 | 57 | _What's new?_ 58 | 59 | - Added a new config argument `naming_convention` to support `api_native` or `snake_case` table and column names. Please check the [Configuration](https://hub.steampipe.io/plugins/turbot/salesforce#configuration) section for more information on how to use the new config argument. ([#24](https://github.com/turbot/steampipe-plugin-salesforce/pull/24)) 60 | 61 | ## v0.4.0 [2023-06-20] 62 | 63 | _Dependencies_ 64 | 65 | - Recompiled plugin with [steampipe-plugin-sdk v5.5.0](https://github.com/turbot/steampipe-plugin-sdk/blob/v5.5.0/CHANGELOG.md#v550-2023-06-16) which significantly reduces API calls and boosts query performance, resulting in faster data retrieval. This update significantly lowers the plugin initialization time of dynamic plugins by avoiding recursing into child folders when not necessary. ([#20](https://github.com/turbot/steampipe-plugin-salesforce/pull/20)) 66 | 67 | ## v0.3.0 [2023-03-23] 68 | 69 | _Dependencies_ 70 | 71 | - Recompiled plugin with [steampipe-plugin-sdk v5.3.0](https://github.com/turbot/steampipe-plugin-sdk/blob/main/CHANGELOG.md#v530-2023-03-16) which includes fixes for query cache pending item mechanism and aggregator connections not working for dynamic tables. ([#12](https://github.com/turbot/steampipe-plugin-salesforce/pull/12)) 72 | - Recompiled plugin with Go version `1.19`. ([#12](https://github.com/turbot/steampipe-plugin-salesforce/pull/12)) 73 | 74 | ## v0.2.1 [2023-03-02] 75 | 76 | _Bug fixes_ 77 | 78 | - Fixed formatting for various examples in index and table docs. 79 | 80 | ## v0.2.0 [2022-06-24] 81 | 82 | _Enhancements_ 83 | 84 | - Recompiled plugin with [steampipe-plugin-sdk v3.3.0](https://github.com/turbot/steampipe-plugin-sdk/blob/main/CHANGELOG.md#v330--2022-6-22). ([#9](https://github.com/turbot/steampipe-plugin-salesforce/pull/9)) 85 | 86 | ## v0.1.0 [2022-04-28] 87 | 88 | _Enhancements_ 89 | 90 | - Added support for native Linux ARM and Mac M1 builds. ([#7](https://github.com/turbot/steampipe-plugin-salesforce/pull/7)) 91 | - Recompiled plugin with [steampipe-plugin-sdk v3.1.0](https://github.com/turbot/steampipe-plugin-sdk/blob/main/CHANGELOG.md#v310--2022-03-30) and Go version `1.18`. ([#6](https://github.com/turbot/steampipe-plugin-salesforce/pull/6)) 92 | 93 | ## v0.0.1 [2022-02-15] 94 | 95 | _What's new?_ 96 | 97 | - New tables added 98 | - [salesforce_account](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account) 99 | - [salesforce_account_contact_role](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_account_contact_role) 100 | - [salesforce_asset](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_asset) 101 | - [salesforce_contact](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_contact) 102 | - [salesforce_contract](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_contract) 103 | - [salesforce_lead](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_lead) 104 | - [salesforce_object_permission](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_object_permission) 105 | - [salesforce_opportunity](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_opportunity) 106 | - [salesforce_opportunity_contact_role](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_opportunity_contact_role) 107 | - [salesforce_order](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_order) 108 | - [salesforce_permission_set](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_permission_set) 109 | - [salesforce_permission_set_assignment](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_permission_set_assignment) 110 | - [salesforce_pricebook](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_pricebook) 111 | - [salesforce_product](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_product) 112 | - [salesforce_user](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_user) 113 | - [salesforce_{object_name}](https://hub.steampipe.io/plugins/turbot/salesforce/tables/salesforce_{object_name}) 114 | -------------------------------------------------------------------------------- /docs/tables/salesforce_{object_name}.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Steampipe Table: salesforce_{object_name} - Query Salesforce {object_name} using SQL" 3 | description: "Allows users to query {object_name} in Salesforce, providing insights into Salesforce objects and their related data." 4 | --- 5 | 6 | # Table: salesforce_{object_name} - Query Salesforce {object_name} using SQL 7 | 8 | Salesforce is a customer relationship management solution that offers applications for small, midsize, and enterprise organizations, with a focus on sales and support. The Salesforce platform allows users to manage all interactions with their customers and prospects, including marketing automation, sales and customer service, analytics, and application development. {object_name} in Salesforce represents a specific type of object that can be created, manipulated, and deleted. 9 | 10 | ## Table Usage Guide 11 | 12 | The `salesforce_{object_name}` table provides insights into {object_name} within Salesforce. As a Salesforce administrator or developer, you can explore specific details through this table, including object properties, relationships, and associated metadata. Use it to uncover information about {object_name}, such as their properties, relationships with other objects, and the manipulation of these objects. 13 | 14 | ## Examples 15 | 16 | ### Inspect the table structure 17 | 18 | Assuming your connection configuration is: 19 | 20 | ```hcl 21 | connection "salesforce" { 22 | plugin = "salesforce" 23 | url = "https://my-dev-env.my.salesforce.com" 24 | username = "user@example.com" 25 | password = "MyPassword" 26 | token = "MyToken" 27 | client_id = "MyClientID" 28 | objects = ["Case", "Campaign", "CustomApp__c"] 29 | } 30 | ``` 31 | 32 | List all tables with: 33 | 34 | ```sh 35 | .inspect salesforce 36 | +---------------------------------+---------------------------------------------------------+ 37 | | table | description | 38 | +---------------------------------+---------------------------------------------------------+ 39 | | salesforce_account_contact_role | Represents the role that a Contact plays on an Account. | 40 | | salesforce_campaign | Represents Saleforce object Campaign. | 41 | | salesforce_case | Represents Salesforce object Case. | 42 | | salesforce_custom_app__c | Represents Salesforce object CustomApp__c. | 43 | +---------------------------------+---------------------------------------------------------+ 44 | ``` 45 | 46 | To get details of a specific object table, inspect it by name: 47 | 48 | ```sh 49 | .inspect salesforce_custom_app__c 50 | +---------------------+--------------------------+-------------------------+ 51 | | column | type | description | 52 | +---------------------+--------------------------+-------------------------+ 53 | | created_by_id | text | ID of app creator. | 54 | | created_date | timestamp with time zone | Created date. | 55 | | id | text | App record ID. | 56 | | is_deleted | boolean | True if app is deleted. | 57 | | last_modified_by_id | text | ID of last modifier. | 58 | | last_modified_date | timestamp with time zone | Last modified date. | 59 | | name | text | App name. | 60 | | owner_id | text | Owner ID. | 61 | | system_modstamp | timestamp with time zone | System Modstamp. | 62 | +---------------------+--------------------------+-------------------------+ 63 | ``` 64 | 65 | ### Get all values from salesforce_custom_app\_\_c 66 | Explore all the custom applications in your Salesforce environment to gain insights into their configurations and usage. This can be particularly useful for auditing purposes or when planning system upgrades or changes. 67 | 68 | ```sql+postgres 69 | select 70 | * 71 | from 72 | salesforce_custom_app__c; 73 | ``` 74 | 75 | ```sql+sqlite 76 | select 77 | * 78 | from 79 | salesforce_custom_app__c; 80 | ``` 81 | 82 | ### List custom apps added in the last 24 hours 83 | Explore which custom apps have been added recently. This is useful for maintaining an up-to-date inventory and tracking the evolution of your application landscape. 84 | 85 | ```sql+postgres 86 | select 87 | id, 88 | name, 89 | owner_id 90 | from 91 | salesforce_custom_app__c 92 | where 93 | created_date = now() - interval '24 hrs'; 94 | ``` 95 | 96 | ```sql+sqlite 97 | select 98 | id, 99 | name, 100 | owner_id 101 | from 102 | salesforce_custom_app__c 103 | where 104 | created_date = datetime('now', '-24 hours'); 105 | ``` 106 | 107 | ### Get details for a custom app by ID 108 | Determine the details of a specific custom application in your Salesforce environment by using its unique identifier. This can be useful for obtaining a comprehensive view of an application's settings or status. 109 | 110 | ```sql+postgres 111 | select 112 | * 113 | from 114 | salesforce_custom_app__c 115 | where 116 | id = '7015j0000019GVgAAM'; 117 | ``` 118 | 119 | ```sql+sqlite 120 | select 121 | * 122 | from 123 | salesforce_custom_app__c 124 | where 125 | id = '7015j0000019GVgAAM'; 126 | ``` 127 | 128 | If `naming_convention` is set to `api_native`, the plugin will use the Salesforce naming conventions. Table and column names will have mixed case and table names will not start with `salesforce_`. 129 | 130 | For instance, if the connection configuration is: 131 | 132 | ```hcl 133 | connection "salesforce" { 134 | plugin = "salesforce" 135 | url = "https://my-dev-env.my.salesforce.com" 136 | username = "user@example.com" 137 | password = "MyPassword" 138 | token = "MyToken" 139 | client_id = "MyClientID" 140 | objects = ["Case", "Campaign", "CustomApp__c"] 141 | naming_convention = "api_native" 142 | } 143 | ``` 144 | 145 | This plugin will automatically create tables called `Case`, `Campaign` and `CustomApp__c`: 146 | 147 | ```sh 148 | select "ID", "OwnerID", "IsDeleted" from "CustomApp__c" 149 | +--------------------+--------------------+------------+ 150 | | ID | OwnerID | IsDeleted | 151 | +--------------------+--------------------+------------+ 152 | | a005j000006vluAAAQ | 0055j000003GU6IAAW | false | 153 | | a005j000006vluBAAQ | 0055j000003GU6IAAW | false | 154 | | a005j000006vluFAAQ | 0055j000003GU6IAAW | false | 155 | +--------------------+--------------------+------------+ 156 | ``` 157 | 158 | ## API Native Examples 159 | 160 | List all tables with: 161 | 162 | ```sh 163 | .inspect salesforce 164 | +---------------------------------+---------------------------------------------------------+ 165 | | table | description | 166 | +---------------------------------+---------------------------------------------------------+ 167 | | AccountContactRole | Represents the role that a Contact plays on an Account. | 168 | | Campaign | Represents Saleforce object Campaign. | 169 | | Case | Represents Salesforce object Case. | 170 | | CustomApp__c | Represents Salesforce object CustomApp__c. | 171 | +---------------------------------+---------------------------------------------------------+ 172 | ``` 173 | 174 | To get details of a specific object table, inspect it by name: 175 | 176 | ```sh 177 | .inspect CustomApp__c 178 | +---------------------+--------------------------+-------------------------+ 179 | | column | type | description | 180 | +---------------------+--------------------------+-------------------------+ 181 | | CreatedByID | text | ID of app creator. | 182 | | CreatedDate | timestamp with time zone | Created date. | 183 | | ID | text | App record ID. | 184 | | IsDeleted | boolean | True if app is deleted. | 185 | | LastModifiedByID | text | ID of last modifier. | 186 | | LastModifiedDate | timestamp with time zone | Last modified date. | 187 | | Name | text | App name. | 188 | | OwnerID | text | Owner ID. | 189 | | SystemModstamp | timestamp with time zone | System Modstamp. | 190 | +---------------------+--------------------------+-------------------------+ 191 | ``` 192 | 193 | ### List custom apps added in the last 24 hours (with API Native naming convention) 194 | Discover the custom applications added within the past day. This can be useful for monitoring recent additions and their owners for management or security purposes. 195 | 196 | ```sql+postgres 197 | select 198 | "ID", 199 | "Name", 200 | "OwnerID" 201 | from 202 | "CustomApp__c" 203 | where 204 | "CreatedDate" = now() - interval '24 hrs'; 205 | ``` 206 | 207 | ```sql+sqlite 208 | select 209 | "ID", 210 | "Name", 211 | "OwnerID" 212 | from 213 | "CustomApp__c" 214 | where 215 | "CreatedDate" = datetime('now', '-24 hours'); 216 | ``` -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | organization: Turbot 3 | category: ["saas"] 4 | icon_url: "/images/plugins/turbot/salesforce.svg" 5 | brand_color: "#00A1E0" 6 | display_name: "Salesforce" 7 | short_name: "salesforce" 8 | description: "Steampipe plugin to query accounts, opportunities, users and more from your Salesforce instance." 9 | og_description: "Query Salesforce with SQL! Open source CLI. No DB required." 10 | og_image: "/images/plugins/turbot/salesforce-social-graphic.png" 11 | engines: ["steampipe", "sqlite", "postgres", "export"] 12 | --- 13 | 14 | # Salesforce + Steampipe 15 | 16 | [Salesforce](https://www.salesforce.com/) is a customer relationship management (CRM) platform. 17 | 18 | [Steampipe](https://steampipe.io) is an open-source zero-ETL engine to instantly query cloud APIs using SQL. 19 | 20 | List won opportunities: 21 | 22 | ```sql 23 | select 24 | name, 25 | amount, 26 | close_date 27 | from 28 | salesforce_opportunity 29 | where 30 | is_won; 31 | ``` 32 | 33 | ``` 34 | +-------------------------------------+--------+---------------------------+ 35 | | name | amount | close_date | 36 | +-------------------------------------+--------+---------------------------+ 37 | | GenePoint Standby Generator | 85000 | 2021-10-23T05:30:00+05:30 | 38 | | GenePoint SLA | 30000 | 2021-12-16T05:30:00+05:30 | 39 | | Express Logistics Standby Generator | 220000 | 2021-09-15T05:30:00+05:30 | 40 | +-------------------------------------+------------------------------------+ 41 | ``` 42 | 43 | ## Documentation 44 | 45 | - **[Table definitions & examples →](/plugins/turbot/salesforce/tables)** 46 | 47 | ## Get started 48 | 49 | ### Install 50 | 51 | Download and install the latest salesforce plugin: 52 | 53 | ```bash 54 | steampipe plugin install salesforce 55 | ``` 56 | 57 | ### Configuration 58 | 59 | Installing the latest salesforce plugin will create a config file (`~/.steampipe/config/salesforce.spc`) with a single connection named `salesforce`: 60 | 61 | ```hcl 62 | connection "salesforce" { 63 | plugin = "salesforce" 64 | 65 | # Salesforce instance URL, e.g., "https://na01.salesforce.com/" 66 | # url = "https://na01.salesforce.com/" 67 | 68 | # Salesforce account name 69 | # username = "user@example.com" 70 | 71 | # Salesforce account password 72 | # password = "Dummy@~Password" 73 | 74 | # The Salesforce security token is only required If the client's IP address is not added to the organization's list of trusted IPs 75 | # https://help.salesforce.com/s/articleView?id=sf.security_networkaccess.htm&type=5 76 | # token = "ABO5C3PNqOP0BHsPFakeToken" 77 | 78 | # Salesforce client ID of the connected app 79 | # client_id = "3MVG99E3Ry5mh4z_FakeID" 80 | 81 | # List of Salesforce object names to generate additional tables for 82 | # This argument only accepts exact Salesforce standard and custom object names, e.g., AccountBrand, OpportunityStage, CustomApp__c 83 | # For a full list of standard object names, please see https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_list.htm 84 | # All custom object names should end in "__c", following Salesforce object naming standards 85 | # objects = ["AccountBrand", "OpportunityStage", "CustomApp__c"] 86 | 87 | # Salesforce API version to connect to 88 | # api_version = "43.0" 89 | 90 | # The naming_convention allows users to control the naming format for tables and columns in the plugin. Below are the supported values: 91 | # api_native - If set to this value, the plugin will use the native format for table names, meaning there will be no "salesforce_" prefix, and the table and column names will remain as they are in Salesforce. 92 | # snake_case (default) - If the user does not specify any value, the plugin will use snake case for table and column names and table names will have a "salesforce_" prefix. 93 | # naming_convention = "snake_case" 94 | } 95 | ``` 96 | 97 | ### Credentials 98 | 99 | - [Create your connected application](https://trailhead.salesforce.com/en/content/learn/projects/build-a-connected-app-for-api-integration/create-a-connected-app) 100 | - Configure basic [connected application settings](https://help.salesforce.com/s/articleView?id=sf.connected_app_create_basics.htm&type=5) 101 | - Reset your [security token](https://help.salesforce.com/articleView?id=user_security_token.htm&type=5), which is required if you are connecting from an IP address outside your company's trusted IP range 102 | 103 | ## Custom Fields 104 | 105 | Salesforce supports the addition of [custom fields](https://help.salesforce.com/s/articleView?id=sf.adding_fields.htm&type=5) to standard objects. 106 | 107 | If you have set up Salesforce credentials correctly in the Steampipe configuration, Steampipe will generate the tables schema with all the custom fields along with standard object fields dynamically. 108 | 109 | For instance, if the `Account` object in my Salesforce account has a custom field with the label `Priority` and the API name `Priority__c`, the table schema will be generated as: 110 | 111 | ```sh 112 | .inspect salesforce_account 113 | +-----------------------+--------------------------+-------------------------------------------------------------+ 114 | | column | type | description | 115 | +-----------------------+---------------------------+------------------------------------------------------------+ 116 | | account_number | text | The Account Number. | 117 | | account_source | text | The source of the account record. For example, Advertisement, Data.com, or Trade Show. | 118 | | priority__c | text | The account's priority. | 119 | +----------------+------+----------------------------------------------------------------------------------------+ 120 | ``` 121 | 122 | The custom field `priority__c` column can then be queried like other columns: 123 | 124 | ```sql 125 | select 126 | account_number, 127 | priority__c 128 | from 129 | salesforce_account; 130 | ``` 131 | 132 | **Note:** Salesforce custom field names are always suffixed with `__c`, which is reflected in the column names as well. 133 | 134 | ## Custom Objects 135 | 136 | Salesforce also supports creating [custom objects](https://help.salesforce.com/s/articleView?id=sf.dev_objectcreate_task_lex.htm&type=5) to track and store data that's unique to your organization. 137 | 138 | Steampipe will create table schemas for all custom objects set in the `objects` argument. 139 | 140 | For instance, if my connection configuration is: 141 | 142 | ```hcl 143 | connection "salesforce" { 144 | plugin = "salesforce" 145 | url = "https://my-dev-env.my.salesforce.com" 146 | username = "user@example.com" 147 | password = "MyPassword" 148 | token = "MyToken" 149 | client_id = "MyClientID" 150 | objects = ["CustomApp__c", "OtherCustomApp__c"] 151 | } 152 | ``` 153 | 154 | Steampile will automatically create two tables, `salesforce_custom_app__c` and `salesforce_other_custom_app__c`, which can then be inspected and queried like other tables: 155 | 156 | ```sh 157 | .inspect salesforce 158 | +---------------------------------+---------------------------------------------------------+ 159 | | table | description | 160 | +---------------------------------+---------------------------------------------------------+ 161 | | salesforce_account_contact_role | Represents the role that a Contact plays on an Account. | 162 | | salesforce_custom_app__c | Represents Salesforce object CustomApp__c. | 163 | | salesforce_other_custom_app__c | Represents Salesforce object OtherCustomApp__c. | 164 | +---------------------------------+---------------------------------------------------------+ 165 | ``` 166 | 167 | To get details of a specific custom object table, inspect it by name: 168 | 169 | ```sh 170 | .inspect salesforce_custom_app__c 171 | +---------------------+--------------------------+-------------------------+ 172 | | column | type | description | 173 | +---------------------+--------------------------+-------------------------+ 174 | | created_by_id | text | ID of app creator. | 175 | | created_date | timestamp with time zone | Created date. | 176 | | id | text | App record ID. | 177 | | is_deleted | boolean | True if app is deleted. | 178 | | last_modified_by_id | text | ID of last modifier. | 179 | | last_modified_date | timestamp with time zone | Last modified date. | 180 | | name | text | App name. | 181 | | owner_id | text | Owner ID. | 182 | | system_modstamp | timestamp with time zone | System Modstamp. | 183 | +---------------------+--------------------------+-------------------------+ 184 | ``` 185 | 186 | This table can also be queried like other tables: 187 | 188 | ```sql 189 | select 190 | * 191 | from 192 | salesforce_custom_app__c; 193 | ``` 194 | 195 | **Note:** Salesforce custom object names are always suffixed with `__c`, which is reflected in the table names as well. 196 | 197 | ## Naming Convention 198 | 199 | The `naming_convention` configuration argument allows you to control the naming format for tables and columns in the plugin. 200 | 201 | ### Snake Case 202 | 203 | If you do not specify a value for `naming_convention` or set it to `snake_case`, the plugin will use snake case for table and column names, and table names will have a `salesforce_` prefix. 204 | 205 | For example: 206 | 207 | ```sql 208 | select 209 | id, 210 | who_count, 211 | what_count, 212 | subject, 213 | is_all_day_event 214 | from 215 | salesforce_event; 216 | ``` 217 | 218 | ``` 219 | +---------------------+-----------+------------+---------+------------------+ 220 | | id | who_count | what_count | subject | is_all_day_event | 221 | +----------------------------------------------+----------------------------+ 222 | | 00U2t0000000Mw3dEAD | 0 | 0 | test | false | 223 | +---------------------+-----------+------------+---------+------------------+ 224 | ``` 225 | 226 | ### API Native 227 | 228 | If `naming_convention` is set to `api_native`, the plugin will use Salesforce naming conventions. Table and column names will have mixed case and table names will not start with `salesforce_`. 229 | 230 | For example: 231 | 232 | ```sql 233 | select 234 | "Id", 235 | "WhoCount", 236 | "WhatCount", 237 | "Subject", 238 | "IsAllDayEvent" 239 | from 240 | "Event"; 241 | ``` 242 | 243 | ``` 244 | +---------------------+----------+-------------+---------+---------------+ 245 | | ID | WhoCount | WhatCount | Subject | IsAllDayEvent | 246 | +----------------------------------------------+-------------------------+ 247 | | 00U2t0000000Mw3dEAD | 0 | 0 | test | false | 248 | +---------------------+----------+-----------------------+---------------+ 249 | ``` 250 | 251 | 252 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /salesforce/plugin.go: -------------------------------------------------------------------------------- 1 | package salesforce 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "fmt" 7 | "regexp" 8 | "strings" 9 | "sync" 10 | 11 | "github.com/iancoleman/strcase" 12 | "github.com/simpleforce/simpleforce" 13 | "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" 14 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin" 15 | "github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform" 16 | ) 17 | 18 | const pluginName = "steampipe-plugin-salesforce" 19 | 20 | type contextKey string 21 | 22 | func Plugin(ctx context.Context) *plugin.Plugin { 23 | p := &plugin.Plugin{ 24 | Name: pluginName, 25 | DefaultTransform: transform.From(getFieldFromSObjectMapByColumnName).NullIfZero(), 26 | ConnectionKeyColumns: []plugin.ConnectionKeyColumn{ 27 | { 28 | Name: "organization_id", 29 | Hydrate: getOrganizationId, 30 | }, 31 | }, 32 | ConnectionConfigSchema: &plugin.ConnectionConfigSchema{ 33 | NewInstance: ConfigInstance, 34 | }, 35 | SchemaMode: plugin.SchemaModeDynamic, 36 | TableMapFunc: pluginTableDefinitions, 37 | } 38 | 39 | return p 40 | } 41 | 42 | type dynamicMap struct { 43 | cols []*plugin.Column 44 | keyColumns plugin.KeyColumnSlice 45 | salesforceColumns map[string]string 46 | } 47 | 48 | func pluginTableDefinitions(ctx context.Context, td *plugin.TableMapData) (map[string]*plugin.Table, error) { 49 | // If unable to connect to salesforce instance, log warning and abort dynamic table creation 50 | 51 | client, err := connectRaw(ctx, td.ConnectionCache, td.Connection) 52 | if err != nil { 53 | // do not abort the plugin as static table needs to be generated 54 | plugin.Logger(ctx).Warn("salesforce.pluginTableDefinitions", "connection_error: unable to generate dynamic tables because of invalid steampipe salesforce configuration", err) 55 | } 56 | 57 | staticTables := []string{"Account", "AccountContactRole", "Asset", "Contact", "Contract", "Lead", "Opportunity", "OpportunityContactRole", "Order", "Pricebook2", "Product2", "User", "PermissionSet", "PermissionSetAssignment", "ObjectPermissions"} 58 | 59 | dynamicColumnsMap := map[string]dynamicMap{} 60 | var mapLock sync.Mutex 61 | config := GetConfig(td.Connection) 62 | 63 | // If Salesforce client was obtained, don't generate dynamic columns for 64 | // defined static tables 65 | if client != nil { 66 | var wgd sync.WaitGroup 67 | wgd.Add(len(staticTables)) 68 | for _, st := range staticTables { 69 | go func(staticTable string) { 70 | defer wgd.Done() 71 | dynamicCols, dynamicKeyColumns, salesforceCols := dynamicColumns(ctx, client, staticTable, config) 72 | mapLock.Lock() 73 | dynamicColumnsMap[staticTable] = dynamicMap{dynamicCols, dynamicKeyColumns, salesforceCols} 74 | defer mapLock.Unlock() 75 | }(st) 76 | } 77 | wgd.Wait() 78 | } 79 | 80 | // Initialize tables with static tables with static and dynamic columns(if credentials are set) 81 | var tables map[string]*plugin.Table 82 | 83 | // check the NamingConvention parameter value in config 84 | if config.NamingConvention != nil && *config.NamingConvention == "api_native" { 85 | tables = map[string]*plugin.Table{ 86 | "Account": SalesforceAccount(ctx, dynamicColumnsMap["Account"], config), 87 | "AccountContactRole": SalesforceAccountContactRole(ctx, dynamicColumnsMap["AccountContactRole"], config), 88 | "Asset": SalesforceAsset(ctx, dynamicColumnsMap["Asset"], config), 89 | "Contact": SalesforceContact(ctx, dynamicColumnsMap["Contact"], config), 90 | "Contract": SalesforceContract(ctx, dynamicColumnsMap["Contract"], config), 91 | "Lead": SalesforceLead(ctx, dynamicColumnsMap["Lead"], config), 92 | "ObjectPermissions": SalesforceObjectPermission(ctx, dynamicColumnsMap["ObjectPermissions"], config), 93 | "Opportunity": SalesforceOpportunity(ctx, dynamicColumnsMap["Opportunity"], config), 94 | "OpportunityContactRole": SalesforceOpportunityContactRole(ctx, dynamicColumnsMap["OpportunityContactRole"], config), 95 | "Order": SalesforceOrder(ctx, dynamicColumnsMap["Order"], config), 96 | "PermissionSet": SalesforcePermissionSet(ctx, dynamicColumnsMap["PermissionSet"], config), 97 | "PermissionSetAssignment": SalesforcePermissionSetAssignment(ctx, dynamicColumnsMap["PermissionSetAssignment"], config), 98 | "Pricebook2": SalesforcePricebook(ctx, dynamicColumnsMap["Pricebook2"], config), 99 | "Product2": SalesforceProduct(ctx, dynamicColumnsMap["Product2"], config), 100 | "User": SalesforceUser(ctx, dynamicColumnsMap["User"], config), 101 | } 102 | } else { 103 | tables = map[string]*plugin.Table{ 104 | "salesforce_account": SalesforceAccount(ctx, dynamicColumnsMap["Account"], config), 105 | "salesforce_account_contact_role": SalesforceAccountContactRole(ctx, dynamicColumnsMap["AccountContactRole"], config), 106 | "salesforce_asset": SalesforceAsset(ctx, dynamicColumnsMap["Asset"], config), 107 | "salesforce_contact": SalesforceContact(ctx, dynamicColumnsMap["Contact"], config), 108 | "salesforce_contract": SalesforceContract(ctx, dynamicColumnsMap["Contract"], config), 109 | "salesforce_lead": SalesforceLead(ctx, dynamicColumnsMap["Lead"], config), 110 | "salesforce_object_permission": SalesforceObjectPermission(ctx, dynamicColumnsMap["ObjectPermissions"], config), 111 | "salesforce_opportunity": SalesforceOpportunity(ctx, dynamicColumnsMap["Opportunity"], config), 112 | "salesforce_opportunity_contact_role": SalesforceOpportunityContactRole(ctx, dynamicColumnsMap["OpportunityContactRole"], config), 113 | "salesforce_order": SalesforceOrder(ctx, dynamicColumnsMap["Order"], config), 114 | "salesforce_permission_set": SalesforcePermissionSet(ctx, dynamicColumnsMap["PermissionSet"], config), 115 | "salesforce_permission_set_assignment": SalesforcePermissionSetAssignment(ctx, dynamicColumnsMap["PermissionSetAssignment"], config), 116 | "salesforce_pricebook": SalesforcePricebook(ctx, dynamicColumnsMap["Pricebook2"], config), 117 | "salesforce_product": SalesforceProduct(ctx, dynamicColumnsMap["Product2"], config), 118 | "salesforce_user": SalesforceUser(ctx, dynamicColumnsMap["User"], config), 119 | } 120 | } 121 | 122 | var re = regexp.MustCompile(`\d+`) 123 | var substitution = `` 124 | salesforceTables := []string{} 125 | if config.Objects != nil && len(*config.Objects) > 0 { 126 | for _, tableName := range *config.Objects { 127 | var pluginTableName string 128 | if config.NamingConvention != nil && *config.NamingConvention == "api_native" { 129 | pluginTableName = strcase.ToSnake(re.ReplaceAllString(tableName, substitution)) 130 | } else { 131 | pluginTableName = "salesforce_" + strcase.ToSnake(re.ReplaceAllString(tableName, substitution)) 132 | } 133 | if _, ok := tables[pluginTableName]; !ok { 134 | salesforceTables = append(salesforceTables, tableName) 135 | } 136 | } 137 | } 138 | 139 | if client == nil { 140 | plugin.Logger(ctx).Warn("salesforce.pluginTableDefinitions", "client_not_found: unable to generate dynamic tables because of invalid steampipe salesforce configuration", err) 141 | return tables, nil 142 | } 143 | 144 | var wg sync.WaitGroup 145 | wg.Add(len(salesforceTables)) 146 | for _, sfTable := range salesforceTables { 147 | var tableName string 148 | if config.NamingConvention != nil && *config.NamingConvention == "api_native" { 149 | tableName = sfTable 150 | } else { 151 | tableName = "salesforce_" + strcase.ToSnake(re.ReplaceAllString(sfTable, substitution)) 152 | } 153 | if tables[tableName] != nil { 154 | wg.Done() 155 | continue 156 | } 157 | go func(name string) { 158 | defer wg.Done() 159 | if config.NamingConvention != nil && *config.NamingConvention == "api_native" { 160 | tableName = name 161 | } else { 162 | tableName = "salesforce_" + strcase.ToSnake(re.ReplaceAllString(name, substitution)) 163 | } 164 | plugin.Logger(ctx).Debug("salesforce.pluginTableDefinitions", "object_name", name, "table_name", tableName) 165 | ctx = context.WithValue(ctx, contextKey("PluginTableName"), tableName) 166 | ctx = context.WithValue(ctx, contextKey("SalesforceTableName"), name) 167 | table := generateDynamicTables(ctx, client, config) 168 | // Ignore if the requested Salesforce object is not present. 169 | if table != nil { 170 | tables[tableName] = table 171 | } 172 | }(sfTable) 173 | } 174 | wg.Wait() 175 | return tables, nil 176 | } 177 | 178 | func generateDynamicTables(ctx context.Context, client *simpleforce.Client, config salesforceConfig) *plugin.Table { 179 | // Get the query for the metric (required) 180 | salesforceTableName := ctx.Value(contextKey("SalesforceTableName")).(string) 181 | tableName := ctx.Value(contextKey("PluginTableName")).(string) 182 | 183 | sObjectMeta := client.SObject(salesforceTableName).Describe() 184 | if sObjectMeta == nil { 185 | plugin.Logger(ctx).Error("salesforce.generateDynamicTables", fmt.Sprintf("Object %s not found in salesforce", salesforceTableName)) 186 | return nil 187 | } 188 | 189 | // Top columns 190 | cols := []*plugin.Column{} 191 | salesforceCols := map[string]string{} 192 | // Key columns 193 | keyColumns := plugin.KeyColumnSlice{} 194 | 195 | salesforceObjectMetadata := *sObjectMeta 196 | salesforceObjectMetadataAsByte, err := json.Marshal(salesforceObjectMetadata["fields"]) 197 | if err != nil { 198 | plugin.Logger(ctx).Error("salesforce.generateDynamicTables", "json marshal error", err) 199 | } 200 | 201 | salesforceObjectFields := []map[string]interface{}{} 202 | err = json.Unmarshal(salesforceObjectMetadataAsByte, &salesforceObjectFields) 203 | if err != nil { 204 | plugin.Logger(ctx).Error("salesforce.generateDynamicTables", "json unmarshal error", err) 205 | } 206 | 207 | for _, properties := range salesforceObjectFields { 208 | if properties["name"] == nil { 209 | continue 210 | } 211 | fieldName := properties["name"].(string) 212 | compoundFieldName := properties["compoundFieldName"] 213 | if compoundFieldName != nil && compoundFieldName.(string) != fieldName { 214 | continue 215 | } 216 | 217 | if properties["soapType"] == nil { 218 | continue 219 | } 220 | soapType := strings.Split((properties["soapType"]).(string), ":") 221 | fieldType := soapType[len(soapType)-1] 222 | 223 | // Column dynamic generation 224 | // Don't convert to snake case since field names can have underscores in 225 | // them, so it's impossible to convert from snake case back to camel case 226 | // to match the original field name. Also, if we convert to snake case, 227 | // custom fields like "TestField" and "Test_Field" will result in duplicates 228 | var columnFieldName string 229 | 230 | // keep the field name as it is if NamingConvention is set to api_native 231 | if config.NamingConvention != nil && *config.NamingConvention == "api_native" { 232 | columnFieldName = fieldName 233 | } else if strings.HasSuffix(fieldName, "__c") { 234 | columnFieldName = strings.ToLower(fieldName) 235 | } else { 236 | columnFieldName = strcase.ToSnake(fieldName) 237 | } 238 | 239 | column := plugin.Column{ 240 | Name: columnFieldName, 241 | Description: fmt.Sprintf("%s.", properties["label"].(string)), 242 | Transform: transform.FromP(getFieldFromSObjectMap, fieldName), 243 | } 244 | // Adding column type in the map to help in qual handling 245 | salesforceCols[columnFieldName] = fieldType 246 | 247 | // Set column type based on the `soapType` from salesforce schema 248 | switch fieldType { 249 | case "string", "ID", "time": 250 | column.Type = proto.ColumnType_STRING 251 | keyColumns = append(keyColumns, &plugin.KeyColumn{Name: columnFieldName, Require: plugin.Optional, Operators: []string{"=", "<>"}}) 252 | case "date", "dateTime": 253 | column.Type = proto.ColumnType_TIMESTAMP 254 | keyColumns = append(keyColumns, &plugin.KeyColumn{Name: columnFieldName, Require: plugin.Optional, Operators: []string{"=", ">", ">=", "<=", "<"}}) 255 | case "boolean": 256 | column.Type = proto.ColumnType_BOOL 257 | keyColumns = append(keyColumns, &plugin.KeyColumn{Name: columnFieldName, Require: plugin.Optional, Operators: []string{"=", "<>"}}) 258 | case "double": 259 | column.Type = proto.ColumnType_DOUBLE 260 | keyColumns = append(keyColumns, &plugin.KeyColumn{Name: columnFieldName, Require: plugin.Optional, Operators: []string{"=", ">", ">=", "<=", "<"}}) 261 | case "int": 262 | column.Type = proto.ColumnType_INT 263 | keyColumns = append(keyColumns, &plugin.KeyColumn{Name: columnFieldName, Require: plugin.Optional, Operators: []string{"=", ">", ">=", "<=", "<"}}) 264 | default: 265 | column.Type = proto.ColumnType_JSON 266 | } 267 | cols = append(cols, &column) 268 | } 269 | 270 | Table := plugin.Table{ 271 | Name: tableName, 272 | Description: fmt.Sprintf("Represents Salesforce object %s.", salesforceObjectMetadata["name"]), 273 | List: &plugin.ListConfig{ 274 | KeyColumns: keyColumns, 275 | Hydrate: listSalesforceObjectsByTable(salesforceTableName, salesforceCols), 276 | }, 277 | Get: &plugin.GetConfig{ 278 | KeyColumns: plugin.SingleColumn(checkNameScheme(config, cols)), 279 | Hydrate: getSalesforceObjectbyID(salesforceTableName), 280 | }, 281 | Columns: append([]*plugin.Column{ 282 | {Name: "organization_id", Type: proto.ColumnType_STRING, Description: "Unique identifier of the organization in Salesforce.", Hydrate: getOrganizationId, Transform: transform.FromValue()}, 283 | }, cols...), 284 | } 285 | return &Table 286 | } 287 | 288 | // set GetConfig parameter based on NamingConvention value 289 | // if the object is unavailable then there will be no dynamic columns, so GetConfig parameter should be id to avoid failure of static table creation 290 | func checkNameScheme(config salesforceConfig, dynamicColumns []*plugin.Column) string { 291 | if config.NamingConvention != nil && *config.NamingConvention == "api_native" && len(dynamicColumns) > 0 { 292 | return "Id" 293 | } 294 | return "id" 295 | } 296 | --------------------------------------------------------------------------------