# Collecting Contact Information

In Part I, we established a Capture Customer Info Web Flow. Now, we're going to build out the UI associated with that flow so that users can submit their information, and then apply that information so that we can send users outgoing messages later on.

## Building the Capture Customer Info Form

1. The Capture Customer Info Web Flow comes with a Web Page already nested underneath. Rename this Web Page "Collect Info Capture Form":

![](https://3088276961-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC6qMwMGWBgxnN70QsDuH%2Fuploads%2Fgit-blob-9ea287dca8e1a9e6f006d8f14cce4c847db26baa%2Fcollecting-contact-information-v182-0.png?alt=media)

2. Add the following Web Controls to the Contact Info Capture Form, in this order:

* Label Control _(Variant: **headerMedium**)_
  * Change text to: "Please provide your contact information"
* Label Control _(Variant: **inputLabel**)_
  * Change text to: "First Name"
* Text Input Control
  * Change data binding to: `first_name_input`
* Label Control _(Variant: **inputLabel**)_
  * Change text to: "Last Name"
* Text Input Control
  * Change data binding to: `last_name_input`
* Label Control _(Variant: **inputLabel**)_
  * Change text to: "Email Address"
* Email Input Control
  * Keep data binding as `email_input`
* Label Control _(Variant: **inputLabel**)_
  * Change text to: "Phone Number"
* Phone Input Control
  * Keep data binding as `phone_input`

The end result should look as follows:

![](https://3088276961-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC6qMwMGWBgxnN70QsDuH%2Fuploads%2Fgit-blob-69116e43928ba23ef6943398d4f28428e4fe1ac3%2Fcollecting-contact-information-v182-1.png?alt=media)

\[block:callout] { "type": "info", "body": "If you want review the fundamentals of Web Controls or Variants, check out the [Appendix](../your-first-app-a-simple-form/building-your-first-app-appendix) or [FAQ](../your-first-app-a-simple-form/faq) associated with [Your First App (A Simple Form)](../your-first-app-a-simple-form)." } \[/block]

3. To enforce TCPA compliance when we send text messages to users later on, we're going to need to collect information on what state the user lives in. Add two more Web Controls:

* Label Control _(Variant: **inputLabel**)_
  * Change text to: "State"
* Dropdown List Control
  * Change data binding to `state_input`

![](https://3088276961-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC6qMwMGWBgxnN70QsDuH%2Fuploads%2Fgit-blob-8f2685a5fbd9411c17e276b2f04bd21cbcc22615%2Fcollecting-contact-information-v182-2.png?alt=media)

<details>

<summary>What is TCPA compliance and why does it require collecting a user's state?</summary>

\


TCPA (Telephone Consumer Protection Act) is a series of US legislation that dictates limitations on how automated systems can reach out to customers over phone and SMS. Some TCPA regulations are federal, but states can impose their own requirements, meaning that the rules dictating how phone and SMS messages can be automated vary from state to state. **You need to know what state a user lives in before you can send them TCPA-compliant messages.**

For more on TCPA regulations, see [TCPA](../../security-and-compliance/tcpa).

</details>

4. With the State Dropdown List still selected, go to the **General** tab. In **Type of List**, choose **Custom Expression**. Under **Data**, paste the following List to populate the dropdown options:

```javascript
["AK", "AL", "AR", "AZ", "CA", "CO", "CT", "DC", "DE", "FL", "GA", "HI", "IA", "ID", "IL", "IN", "KS", "KS", "KY", "LA", "MA", "MD", "ME", "MI", "MN", "MO", "MS", "MT", "NC", "ND", "NE", "NH", "NJ", "NM", "NV", "NV", "NY", "OH", "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "US", "UT", "VA", "VT", "WA", "WI", "WV", "WY"]
```

![](https://3088276961-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC6qMwMGWBgxnN70QsDuH%2Fuploads%2Fgit-blob-7f18aede837bb6697553f30997e564c2dd754c8f%2Fcollecting-contact-information-v182-3.png?alt=media)

Each item in the List represents a state in the US and will be available for selection in the associated dropdown menu.

<details>

<summary>Do the states need to be designated by their State Abbreviation Key, as they are in this List?</summary>

\


When designating a user's state (or **region**, as it is described in the [Identity Object](../../working-with-data/airdata/identity-app-object)), the designation will only be Airkit-parsable if it is described in the correct format. To this end, States/Regions must be described by their [State/Province Abbreviation Key](https://www.fs.fed.us/database/feis/format.html).

We'll see how this works in practice later in this tutorial, but if you want to read more about region designation now, you can find a deeper dive into the subject in [TCPA](../../security-and-compliance/tcpa).

</details>

5. Add one more Web Control to the bottom of your Contact Info Form Captured Web Page:

* Button Control _(Variant: **default**)_
  * Change text to: "Continue"

![](https://3088276961-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC6qMwMGWBgxnN70QsDuH%2Fuploads%2Fgit-blob-13180f9da5ed35644bbcf58a6e7e5d55356cca79%2Fcollecting-contact-information-v182-4.png?alt=media)

6. Save the app.

## Creating the App Object

Go to **AirData** Builder and create a User Info App Object with the following fields to store the captured information:

* `first_name` Variable of Type `Text`
* `last_name` Variable of Type `Text`
* `email` Variable of Type `Email`
* `phone` Variable of Type `Phone`
* `state` Variable of Type `Text`
* `timezone` Variable of Type `Text`

![](https://3088276961-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC6qMwMGWBgxnN70QsDuH%2Fuploads%2Fgit-blob-3e15c73b3873046f134862f6a5238f34b4236a2a%2Fcollecting-contact-information-v182-5.png?alt=media)

Then save the app and confirm all changes this will make to the Datastore.

## Creating the Data Flow

In order to save information into the AirData Object we just made, the next step is to create a Data Flow that can save information to AirData.

1. Go to **Connections** Builder and create a Data Flow from scratch. Rename it to “Save Contact Info”.
2. Then, in **Start**, add the following:

* `first_name` Variable of Type `Text`
* `last_name` Variable of Type `Text`
* `email` Variable of Type `Email`
* `phone` Variable of Type `Phone`
* `state` Variable of Type `Text`
* `timezone` Variable of Type `Text`

![](https://3088276961-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC6qMwMGWBgxnN70QsDuH%2Fuploads%2Fgit-blob-52063d41f49dd7a795467acea1147e3371f935ad%2Fcollecting-contact-information-v182-6.png?alt=media)

3. Click on the ‘+’ icon between the **Start** and **End** sections of the Stage and add an AirData Request Data Operation.
   * In **App Object**, select the **User Info** App Object we have just created
   * For **Type** select INSERT
   * In **Objects to Insert or Update**, enter the Keys one by one by clicking on the ‘+’ icon and match each Key with their corresponding Variable:

![](https://3088276961-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC6qMwMGWBgxnN70QsDuH%2Fuploads%2Fgit-blob-91766b31e88dde931fcf462bb3515b35f3da3850%2Fcollecting-contact-information-v182-7.png?alt=media)

4. In Run Results, click on the **Run** button to ensure that your Data Flow runs.
5. Save the app.

## Saving Input and Initializing the Actor

1. Return to the **Web Flows** Builder and Inspect the Continue Button in the **Contact Info Capture Form** Web Page. In the **Actions** tab of the Inspector, add a **Run Data Flow** Action and select the **Save Contact Info** Data Flow to run. Use the variables given to the **Contact Info Captured** Event as Web Flow input.

* `first_name` = `first_name_input`
* `last_name` = `last_name_input`
* `email` = `email_input`
* `phone` = `phone_input`
* `state` = `state_input`
* `timezone` = `session.Timezone`

![](https://3088276961-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC6qMwMGWBgxnN70QsDuH%2Fuploads%2Fgit-blob-c85bd0f559387e185a40989eadf040972d3299e2%2Fcollecting-contact-information-v182-8.png?alt=media)

<details>

<summary>Where did `session.Timezone` come from?</summary>

\


`session.timeZone` is an automatically collected and managed global variable. For more on what data is automatically collected and managed, see [Standard Journey Data](../../working-with-data/standard-journey-data).

Like all global variables, session.timeZone is referenced by referring to the Session namespace.

</details>

3. In order to send Notifications to users, we need to initialize the Actor.

<details>

<summary>What is the Actor and why does it need to be initialized?</summary>

\


An Actor represents someone who goes on an Airkit Journey. They can be identified by their phone numbers and their email addresses, because they serve as unique properties that are tied directly to the app user.

Out of the box, **Actors** are structured such that the Actor namespace has the following properties:

* **first\_name** (`string`) - the Actor's first name.
* **last\_name** (`string`) - the Actor's last name.
* **full\_name** (`string`) - the Actor's full name.
* **email** (`string`) - the Actor's email address. This cans serve as a unique identifier.
* **phone** (`string`) - the Actor's phone number. This can serve as a unique identifier.
* **timezone** (`string`) - the Actor's timezone. Timezones must be described by their [TZ database names](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones), or the Actor will not parse them as meaningful timezones.
* **region** (`string`) - the Actor's region. Regions must be described by their [State/Province Abbreviation Key](https://www.fs.fed.us/database/feis/format.html), or the Actor will not parse them as meaningful regions.
* **calendar\_restriction** (`string`, _Availability Schedule Key_) - defines when Notifications can and cannot be sent to the Actor from the [Journey Builder](../../studio/builder-bar/journey-builder). For the sake of TCPA compliance, this value is automatically generated out of **timezone** and **region** when applicable.
  * Availability Schedule Keys are made in the [Schedules Builder](../../studio/builder-bar/schedules-builder). For more on how to conceptualize calendar restrictions, see [Using Availability Schedules](../../building-apps/calendars/using-availability-schedules).

You can use dot notation when referencing a property within the Actor namespace. For instance, to reference the Actor's phone number, access `actor.phone` wherever Airscript is accepted.

Variables saved in the Actor namespace are just that: locally-stored variables. They do not automatically establish communication channels any more than other locally-stored variables do.

In order to automatically parse and establish communication channels, relevant **Actor** properties must be copied into Airkit's **actor\_internal** database. This is what is done in the process of Initializing the Actor. Once an Actor has been initialized with a value for `actor.phone`, it will send all outgoing calls and SMS messages to that phone number.

For more on Actors and the process of initializing them, see [Actors](../../concepts/actors).

</details>

To begin the process of Actor initialization, let’s set a few Variables with the data from the form into the `actor` namespace.

Staying in the **Actions** tab associated with the **Contact Info Captured** Event, add six **Set Variable** Actions:

* `actor.first_name` as Variable and `first_name_input` as Value
* `actor.last_name` as Variable and `last_name_input` as Value
* `actor.phone` as Variable and `phone_input` as Value
* `actor.email` as Variable and `email_input` as Value
* `actor.region` as Variable and `state_input` as Value
* `actor.time_zone` as Variable and `session.Timezone` as Value

![](https://3088276961-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC6qMwMGWBgxnN70QsDuH%2Fuploads%2Fgit-blob-a727713adb8f014bf151ee153e56ce8489c3298e%2Fcollecting-contact-information-v182-9.png?alt=media)

2. Add an **Initialize Actor** Action.

![](https://3088276961-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FC6qMwMGWBgxnN70QsDuH%2Fuploads%2Fgit-blob-7678d3ec44150b7132a1a48a8e17ba4bde726879%2Fcollecting-contact-information-v182-10.png?alt=media)

You've now finished building the first Web Flow of your Journey. Not only does it collect contact information from users and save it to AirData, this Web Flow also uses the collected information to initialize the Actor. This will have powerful implications later on, when we program our application to send automated messages.

Save your progress and get ready build out the appointment-scheduling portion of your application.
