

# Connecting to Freshdesk
<a name="connecting-to-data-freshdesk"></a>

Freshdesk is a cloud-based customer support software that is both feature-rich and easy to use. With multiple support channels available, including live chat, email, phone, and social media, you can help customers through their preferred communication method. If you are a Freshdesk user, you can connect AWS Glue to your Freshdesk account. You can use Freshdesk as a data source in your ETL jobs. Run these jobs to transfer data from Freshdesk to AWS services or other supported applications.

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

# AWS Glue support for Freshdesk
<a name="freshdesk-support"></a>

AWS Glue supports Freshdesk as follows:

**Supported as a source?**  
Yes – Sync and Async. You can use AWS Glue ETL jobs to query data from Freshdesk.

**Supported as a target?**  
No.

**Supported Freshdesk API versions**  
The following Freshdesk API versions are supported:
+ v2

# Policies containing the API operations for creating and using connections
<a name="freshdesk-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 Freshdesk
<a name="freshdesk-configuring"></a>

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

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

The following are minimum requirements:
+ A Freshdesk account. You can choose from Free, Growth, Pro or Enterprise editions.
+ A Freshdesk user's API key.

# Configuring Freshdesk connections
<a name="freshdesk-configuring-connections"></a>

Freshdesk supports custom authentication.

For public Freshdesk documentation on generating the required API keys for custom authorization, see [Freshdesk authentication](https://developer.freshdesk.com/api/#authentication).

The following are the steps to configure Freshdesk connection:
+ In AWS Secrets Manager, create a secret with the following details:
  + For customer managed connected app – the secret should contain the connected app API key with `apiKey` as key. Note that you must create a secret per connection in AWS Glue.
+ In the AWS Glue Studio, create a connection under **Data Connections** by following the steps below:
  + When selecting a **Data source**, select Freshdesk.
  + Provide the `INSTANCE_URL` of the Freshdesk instance you want to connect to.
  + 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": "*"
        }
      ]
    }
    ```

------
  + Select the `secretName` that you want to use for this connection in AWS Glue to put the tokens.
  + Select the network options if you want to use your network.
+ Grant the IAM role associated with your AWS Glue job permission to read `secretName`.
+ In your AWS Glue job configuration, provide `connectionName` as an **Additional network connection**.

# Reading from Freshdesk entities
<a name="freshdesk-reading-from-entities"></a>

**Prerequisite**

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

**Supported entities for Sync source**:


| Entity | Can be filtered | Supports limit | Supports Order by | Supports Select \$1 | Supports partitioning | 
| --- | --- | --- | --- | --- | --- | 
| Agents | Yes | Yes | No | Yes | Yes | 
| Business Hours | No | Yes | No | Yes | Yes | 
| Company | Yes | Yes | No | Yes | Yes | 
| Contacts | Yes | Yes | No | Yes | Yes | 
| Conversations | No | Yes | No | Yes | No | 
| Email Configs | No | Yes | No | Yes | No | 
| Email Inboxes | Yes | Yes | Yes | Yes | No | 
| Forum Categories | No | Yes | No | Yes | No | 
| Forums | No | Yes | No | Yes | No | 
| Groups | No | Yes | No | Yes | No | 
| Products | No | Yes | No | Yes | No | 
| Roles | No | Yes | No | Yes | No | 
| Satisfaction Ratings | Yes | Yes | No | Yes | No | 
| Skills | No | Yes | No | Yes | No | 
| Solutions | Yes | Yes | No | Yes | No | 
| Surveys | No | Yes | No | Yes | No | 
| Tickets | Yes | Yes | Yes | Yes | Yes | 
| Time Entries | Yes | Yes | No | Yes | No | 
| Topics | No | Yes | No | Yes | No | 
| Topic Comments | No | Yes | No | Yes | No | 

**Supported entities for Async source**:


| Entity | API version | Can be filtered | Supports limit | Supports Order by | Supports Select \$1 | Supports partitioning | 
| --- | --- | --- | --- | --- | --- | --- | 
| Companies | v2 | No | No | No | No | No | 
| Contacts | v2 | No | No | No | No | No | 

**Example**:

```
freshdesk_read = glueContext.create_dynamic_frame.from_options(
    connection_type="freshdesk",
    connection_options={
        "connectionName": "connectionName",
        "ENTITY_NAME": "entityName",
        "API_VERSION": "v2"
    }
```

**Freshdesk entity and field details**:


| Entity | Field | 
| --- | --- | 
| Agents | https://developers.freshdesk.com/api/\$1list\$1all\$1agents | 
| Business-hours | https://developers.freshdesk.com/api/\$1list\$1all\$1business\$1hours | 
| Comments | https://developers.freshdesk.com/api/\$1comment\$1attributess | 
| Company | https://developers.freshdesk.com/api/\$1companies | 
| Contacts | https://developers.freshdesk.com/api/\$1list\$1all\$1contacts | 
| Conversations | https://developers.freshdesk.com/api/\$1list\$1all\$1ticket\$1notes | 
| Email-configs | https://developers.freshdesk.com/api/\$1list\$1all\$1email\$1configs | 
| Email-inboxes | https://developers.freshdesk.com/api/\$1list\$1all\$1email\$1mailboxes | 
| Forum-categories | https://developers.freshdesk.com/api/\$1category\$1attributes | 
| Forums | https://developers.freshdesk.com/api/\$1forum\$1attributes | 
| Groups | https://developers.freshdesk.com/api/\$1list\$1all\$1groups | 
| Products | https://developers.freshdesk.com/api/\$1list\$1all\$1products | 
| Roles | https://developers.freshdesk.com/api/\$1list\$1all\$1roles | 
| Satisfaction-rating | https://developers.freshdesk.com/api/\$1view\$1all\$1satisfaction\$1ratingss | 
| Skills | https://developers.freshdesk.com/api/\$1list\$1all\$1skills | 
| Solutions | https://developers.freshdesk.com/api/\$1solution\$1content | 
| Surveys | https://developers.freshdesk.com/api/\$1list\$1all\$1survey | 
| Tickets | https://developers.freshdesk.com/api/\$1list\$1all\$1tickets | 
| Time-entries | https://developers.freshdesk.com/api/\$1list\$1all\$1time\$1entries | 
| Topics | https://developers.freshdesk.com/api/\$1topic\$1attributes | 

## Partitioning queries
<a name="freshdesk-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 Spark timestamp format used in Spark SQL queries.

  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:

```
freshDesk_read = glueContext.create_dynamic_frame.from_options(
     connection_type="freshdesk",
     connection_options={
         "connectionName": "connectionName",
         "ENTITY_NAME": "entityName",
         "API_VERSION": "v2",
         "PARTITION_FIELD": "Created_Time"
         "LOWER_BOUND": " 2024-10-27T23:16:08Z“
         "UPPER_BOUND": " 2024-10-27T23:16:08Z"
         "NUM_PARTITIONS": "10"
     }
```

# Freshdesk connection options
<a name="freshdesk-connection-options"></a>

The following are connection options for Freshdesk:
+ `ENTITY_NAME`(String) - (Required) Used for Read. The name of your object in Freshdesk.
+ `API_VERSION`(String) - (Required) Used for Read. Freshdesk 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) - (Required) Used for Read. A valid Freshdesk instance URL.
+ `TRANSFER_MODE`(String) - Used to indicate whether the type of processing like `SYNC` or `ASYNC` is set to `SYNC` by default. (Optional)

# Limitations and notes for Freshdesk connector
<a name="freshdesk-connector-limitations"></a>

The following are limitations or notes for the Freshdesk connector:
+ The `Company`, `Contacts`, and `Tickets` entities with filtration have pagination limitations. They return only 30 records per page and the page value can be set up to a maximum of 10 (fetching a maximum of 300 records).
+ The `Tickets` entity does not fetch records older than 30 days.
+ The `Company`, `Contacts`, and `Tickets` entities support the 'Date' datatype in filtration. You should select the 'Daily' onward trigger frequencies for these three entities. Selecting 'Minutes' or 'Hourly' can lead to duplicate data. Also, while selecting these fields for filtration, only the date value should be selected, since it will only consider the date portion of the selected timestamp.
+ The number of API calls per minute is based on your plan. This limit is applied on an account wide basis irrespective of factors such as the number of agents or IP addresses used to make the calls. For all trial users, there is a default API limit of 50 calls/minute. For more details, refer to [Freshdesk](https://developer.freshdesk.com/api/#ratelimit)
+ For any entity, only one Export/Async Job is processed at a time. A new job will only be processed once the existing job has completed successfully or failed. For more details, refer to [Freshdesk](https://developers.freshdesk.com/api/#export_contact)
+ The following fields are supported for Sync API calls, but are not supported/allowed to be passed in Async API request body.
  + id
  + created\$1at
  + updated\$1at
  + updated\$1since
  + active
  + company\$1id
  + other\$1companies
  + avatar
  + view\$1all\$1tickets
  + deleted
  + other\$1emails
  + state
  + tag
  + tags