

# Connecting to Freshsales
<a name="connecting-to-data-freshsales"></a>

Freshsales is an intuitive CRM that helps sales reps take the guesswork out of sales. With the built-in phone and email, tasks, appointments and notes, sales reps needn’t have to toggle between tabs to follow up on prospects. You can manage your deals better with the pipeline view and drive more deals to closure. If you are a Freshsales user, you can connect AWS Glue to your Freshsales account. You can use Freshsales as a data source in your ETL jobs. Run these jobs to transfer data from Freshsales to AWS services or other supported applications.

**Topics**
+ [AWS Glue support for Freshsales](freshsales-support.md)
+ [Policies containing the API operations for creating and using connections](freshsales-configuring-iam-permissions.md)
+ [Configuring Freshsales](freshsales-configuring.md)
+ [Configuring Freshsales connections](freshsales-configuring-connections.md)
+ [Reading from Freshsales entities](freshsales-reading-from-entities.md)
+ [Freshsales connection options](freshsales-connection-options.md)
+ [Freshsales limitations](freshsales-connection-limitations.md)

# AWS Glue support for Freshsales
<a name="freshsales-support"></a>

AWS Glue supports Freshsales as follows:

**Supported as a source?**  
Yes. You can use AWS Glue ETL jobs to query data from Freshsales.

**Supported as a target?**  
No.

**Supported Freshsales API versions**  
The following Freshsales API versions are supported:
+ v1.0

# Policies containing the API operations for creating and using connections
<a name="freshsales-configuring-iam-permissions"></a>

The following sample policy describes the required AWS IAM permissions for creating and using connections. If you are creating a new role, create a policy that contains the following:

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "glue:ListConnectionTypes",
        "glue:DescribeConnectionType",
        "glue:RefreshOAuth2Tokens",
        "glue:ListEntities",
        "glue:DescribeEntity"
      ],
      "Resource": "*"
    }
  ]
}
```

------

If you don't want to use the above method, alternatively use the following managed IAM policies:
+ [AWSGlueServiceRole](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole) – Grants access to resources that various AWS Glue processes require to run on your behalf. These resources include AWS Glue, Amazon S3, IAM, CloudWatch Logs, and Amazon EC2. If you follow the naming convention for resources specified in this policy, AWS Glue processes have the required permissions. This policy is typically attached to roles specified when defining crawlers, jobs, and development endpoints.
+ [AWSGlueConsoleFullAccess](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AWSGlueConsoleFullAccess) – Grants full access to AWS Glue resources when an identity that the policy is attached to uses the AWS Management Console. If you follow the naming convention for resources specified in this policy, users have full console capabilities. This policy is typically attached to users of the AWS Glue console.

# Configuring Freshsales
<a name="freshsales-configuring"></a>

Before you can use AWS Glue to transfer data from Freshsales, you must meet these requirements:

## Minimum requirements
<a name="freshsales-configuring-min-requirements"></a>

The following are minimum requirements:
+ You have a Freshsales account.
+ You have a user API key.

If you meet these requirements, you’re ready to connect AWS Glue to your Freshsales account. For typical connections, you don't need do anything else in Freshsales.

# Configuring Freshsales connections
<a name="freshsales-configuring-connections"></a>

Freshsales supports custom authentication.

For public Freshsales documentation on generating the required API keys for custom authentication, see [Authentication](https://developer.freshsales.io/api/#authentication).

To configure a Freshsales connection:

1. In AWS Secrets Manager, create a secret with the following details:

   1. For the customer managed connected app, the Secret should contain the connected app API key with `apiSecretKey` as key. The Secret also needs to contain another key-value pair with `apiKey` as key and `token` as value.

   1. Note: you must create a secret for your connections in AWS Glue.

1. In AWS Glue Glue Studio, create a connection under **Data Connections** by following the steps below:

   1. When selecting a **Data Source**, select Freshsales.

   1. Provide the `INSTANCE_URL` of the Freshsales account you want to connect to.

   1. Select the AWS IAM role which AWS Glue can assume and has permissions for following actions:

------
#### [ JSON ]

****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "secretsmanager:DescribeSecret",
              "secretsmanager:GetSecretValue",
              "secretsmanager:PutSecretValue",
              "ec2:CreateNetworkInterface",
              "ec2:DescribeNetworkInterfaces",
              "ec2:DeleteNetworkInterface"
            ],
            "Resource": "*"
          }
        ]
      }
      ```

------

   1. Select the `secretName` which you want to use for this connection in AWS Glue to put the tokens.

   1. Select the network options if you want to use your network.

1. Grant the IAM role associated with your AWS Glue job permission to read `secretName`.

# Reading from Freshsales entities
<a name="freshsales-reading-from-entities"></a>

**Prerequisite**

A Freshsales object you would like to read from. You will need the object name.

**Supported entities for source**:


| Entity | Can be filtered | Supports limit | Supports Order by | Supports Select \$1 | Supports partitioning | 
| --- | --- | --- | --- | --- | --- | 
| Accounts | Yes | Yes | Yes | Yes | Yes | 
| Contacts | Yes | Yes | Yes | Yes | Yes | 

**Example**:

```
freshSales_read = glueContext.create_dynamic_frame.from_options(
     connection_type="freshsales",
     connection_options={
         "connectionName": "connectionName",
         "ENTITY_NAME": "entityName",
         "API_VERSION": "v1.0"
     }
```

**Freshsales entity and field details**:

Freshsales provides endpoints to fetch metadata dynamically for supported entities. Accordingly, operator support is captured at the datatype level.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/glue/latest/dg/freshsales-reading-from-entities.html)

## Partitioning queries
<a name="freshsales-reading-partitioning-queries"></a>

**Filter-based partitioning**:

You can provide the additional Spark options `PARTITION_FIELD`, `LOWER_BOUND`, `UPPER_BOUND`, and `NUM_PARTITIONS` if you want to utilize concurrency in Spark. With these parameters, the original query would be split into `NUM_PARTITIONS` number of sub-queries that can be executed by Spark tasks concurrently.
+ `PARTITION_FIELD`: the name of the field to be used to partition the query.
+ `LOWER_BOUND`: an **inclusive** lower bound value of the chosen partition field.

  For the Datetime field, we accept the value in ISO format.

  Examples of valid value:

  ```
  "2024-09-30T01:01:01.000Z"
  ```
+ `UPPER_BOUND`: an **exclusive** upper bound value of the chosen partition field.
+ `NUM_PARTITIONS`: the number of partitions.

Example:

```
freshSales_read = glueContext.create_dynamic_frame.from_options(
     connection_type="freshsales",
     connection_options={
         "connectionName": "connectionName",
         "ENTITY_NAME": "entityName",
         "API_VERSION": "v1",
         "PARTITION_FIELD": "Created_Time"
         "LOWER_BOUND": " 2024-10-15T21:16:25Z"
         "UPPER_BOUND": " 2024-10-20T21:25:50Z"
         "NUM_PARTITIONS": "10"
     }
```

# Freshsales connection options
<a name="freshsales-connection-options"></a>

The following are connection options for Freshsales:
+ `ENTITY_NAME`(String) - (Required) Used for Read. The name of your object in Freshsales.
+ `API_VERSION`(String) - (Required) Used for Read. Freshsales Rest API version you want to use.
+ `SELECTED_FIELDS`(List<String>) - Default: empty(SELECT \$1). Used for Read. Columns you want to select for the object.
+ `FILTER_PREDICATE`(String) - Default: empty. Used for Read. It should be in the Spark SQL format.
+ `QUERY`(String) - Default: empty. Used for Read. Full Spark SQL query.
+ `PARTITION_FIELD`(String) - Used for Read. Field to be used to partition query.
+ `LOWER_BOUND`(String)- Used for Read. An inclusive lower bound value of the chosen partition field.
+ `UPPER_BOUND`(String) - Used for Read. An exclusive upper bound value of the chosen partition field.
+ `NUM_PARTITIONS`(Integer) - Default: 1. Used for Read. Number of partitions for read.
+ `INSTANCE_URL`(String) - Used for Read. A valid Freshsales instance URL.

# Freshsales limitations
<a name="freshsales-connection-limitations"></a>

The following are limitations or notes for Freshsales:
+ In Freshsales, the API Rate limit is 1000 API requests per hour per account (see [Errors](https://developer.freshsales.io/api/#error). But this limit is extendable with the Enterprise subscription plan (see the [plan comparison](https://www.freshworks.com/crm/pricing-compare/)).