

# Connecting to Facebook Ads
<a name="connecting-to-data-facebook-ads"></a>

Facebook Ads is a powerful digital advertising platform used by businesses of all sizes to reach their target audience and achieve various marketing objectives. The platform allows advertisers to create tailored ads that can be displayed across Facebook's family of apps and services, including Facebook and Messenger. With its advanced targeting capabilities, Facebook Ads enables businesses to reach specific demographics, interests, behaviors, and locations.

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

# AWS Glue support for Facebook Ads
<a name="facebook-ads-support"></a>

AWS Glue supports Facebook Ads as follows:

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

**Supported as a target?**  
No.

**Supported Facebook Ads API versions**  
The following Facebook Ads API versions are supported:
+ v17.0
+ v18.0
+ v19.0
+ v20.0

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

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

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

The following are minimum requirements:
+ Facebook Standard accounts are accessed directly through Facebook.
+ User authentication is needed to generate the access token.
+ The Facebook Ads SDK connector will be implementing the *User Access Token OAuth* flow.
+ We are using OAuth2.0 to authenticate our API requests to Facebook Ads. This web-based authentication falls under the Multi-Factor Authentication (MFA) architecture, which is a superset of 2FA.
+ The user needs to grant permissions to access the end points. For accessing the user's data, endpoint authorization is handled through [permissions](https://developers.facebook.com/docs/permissions) and [features](https://developers.facebook.com/docs/features-reference).

## Getting OAuth 2.0 credentials
<a name="facebook-ads-configuring-creating-facebook-ads-oauth2-credentials"></a>

To obtain API credentials so that you can make authenticated calls to your instance, see [REST API](https://developers.facebook-ads.com/rest-api/) in the Facebook Ads Developer Guide.

# Configuring Facebook Ads connections
<a name="facebook-ads-configuring-connections"></a>

Facebook Ads supports the AUTHORIZATION\$1CODE grant type for OAuth2.
+ This grant type is considered three-legged OAuth as it relies on redirecting users to the third-party authorization server to authenticate the user. It is used when creating connections via the AWS Glue console.
+ Users may still opt to create their own connected app in Facebook Ads and provide their own client ID and client secret when creating connections through the AWS Glue console. In this scenario, they will still be redirected to Facebook Ads to login and authorize AWS Glue to access their resources.
+ This grant type results in an access token. An expiring system user token is valid for 60 days from a generated or refreshed date. To create continuity, the developer should refresh the access token within 60 days. Failing to do so results in forfeiting the access token and requires the developer obtain a new one to regain API access. See [Refresh Access Token](https://developers.facebook.com/docs/marketing-api/system-users/install-apps-and-generate-tokens/).
+ For public Facebook Ads documentation on creating a connected app for Authorization Code OAuth flow, see [Using OAuth 2.0 to Access Google APIs](https://developers.google.com/identity/protocols/oauth2) in the Google for Developers guide.

To configure a Facebook Ads connection:

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

   1. When selecting a **Connection type**, select Facebook Ads.

   1. Provide the `INSTANCE_URL` of the Facebook Ads instance you want to connect to.

   1. Select the AWS IAM role which AWS Glue can assume and has permissions for the 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 Facebook Ads entities
<a name="facebook-ads-reading-from-entities"></a>

**Prerequisite**

A Facebook Ads object you would like to read from. You will need the object name. The following tables shows the supported entities.

**Supported entities for source**:


| Entity | Can be filtered | Supports limit | Supports Order by | Supports Select \$1 | Supports partitioning | 
| --- | --- | --- | --- | --- | --- | 
| Campaign | Yes | Yes | No | Yes | Yes | 
| Ad Set | Yes | Yes | No | Yes | Yes | 
| Ads | Yes | Yes | No | Yes | Yes | 
| Ad Creative | No | Yes | No | Yes | No | 
| Insights - Account | No | Yes | No | Yes | No | 
| Adaccounts | Yes | Yes | No | Yes | No | 
| Insights - Ad | Yes | Yes | No | Yes | Yes | 
| Insights - AdSet | Yes | Yes | No | Yes | Yes | 
| Insights - Campaign | Yes | Yes | No | Yes | Yes | 

**Example**:

```
FacebookAds_read = glueContext.create_dynamic_frame.from_options(
    connection_type="FacebookAds",
    connection_options={
        "connectionName": "connectionName",
        "ENTITY_NAME": "entityName",
        "API_VERSION": "v20.0"
    }
```

## Facebook Ads entity and field details
<a name="facebook-ads-reading-entity-and-field-details"></a>

For more information about the entities and field details see:
+ [Ad Account](https://developers.facebook.com/docs/marketing-api/reference/ad-account)
+ [Campaign](https://developers.facebook.com/docs/marketing-api/reference/ad-campaign-group)
+ [Ad Set](https://developers.facebook.com/docs/marketing-api/reference/ad-campaign)
+ [Ad](https://developers.facebook.com/docs/marketing-api/reference/adgroup)
+ [Ad Creative](https://developers.facebook.com/docs/marketing-api/reference/ad-creative)
+ [Insight Ad Account](https://developers.facebook.com/docs/marketing-api/reference/ad-account/insights)
+ [Insights Ads](https://developers.facebook.com/docs/marketing-api/reference/adgroup/insights/)
+ [Insights AdSets](https://developers.facebook.com/docs/marketing-api/reference/ad-campaign/insights)
+ [Insights Campaigns](https://developers.facebook.com/docs/marketing-api/reference/ad-campaign-group/insights)

For more information, see [Marketing API](https://developers.facebook.com/docs/marketing-api/reference/v21.0).

**Note**  
Struct and List data types are converted to String data type in the response of the connectors.

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

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.

  Example of valid value:

  ```
  "2022-01-01"
  ```
+ `UPPER_BOUND`: an **exclusive** upper bound value of the chosen partition field.
+ `NUM_PARTITIONS`: the number of partitions.

Example:

```
FacebookADs_read = glueContext.create_dynamic_frame.from_options(
    connection_type="FacebookAds",
    connection_options={
        "connectionName": "connectionName",
        "ENTITY_NAME": "entityName",
        "API_VERSION": "v20.0",
        "PARTITION_FIELD": "created_time"
        "LOWER_BOUND": "2022-01-01"
        "UPPER_BOUND": "2024-01-02"
        "NUM_PARTITIONS": "10"
    }
```

# Facebook Ads connection options
<a name="facebook-ads-connection-options"></a>

The following are connection options for Facebook Ads:
+ `ENTITY_NAME`(String) - (Required) Used for read. The name of your object in Facebook Ads.
+ `API_VERSION`(String) - (Required) Used for read. Facebook Ads Rest API version you want to use. For example: v1.
+ `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.
+ `TRANSFER_MODE`(String) - Default: SYNC. Used for asynchronous read.

# Limitations and notes for Facebook Ads connector
<a name="facebook-ads-connector-limitations"></a>

The following are limitations or notes for the Facebook Ads connector:
+ As Facebook Ads supports dynamic metadata, all fields can be queried. All the fields support filtration and records are fetched if the data is available, or else Facebook returns a Bad request (400) response with a proper error message.
+ An app's call count is the number of calls a user can make during a rolling one-hour window 200 multiplied by the number of users. For rate limit details, see [Rate Limits](https://developers.facebook.com/docs/graph-api/overview/rate-limiting/), and [Business Use Case Rate Limits](https://developers.facebook.com/docs/graph-api/overview/rate-limiting/#buc-rate-limits).