# Creating New Functions

**Getting Started**

1. Use the following repo as a template for building your own Freshpaint Functions. <https://github.com/freshpaint-io/functions-template>.&#x20;
2. Create a new repository from this template, implement the methods in index.js, and configure your function settings in config.json. Additional configuration options are provided [below](#function-configuration).
3. Navigate to the [Functions](https://app.freshpaint.io/functions) page in Freshpaint, and provide the URL of your new repository to add your function to the Freshpaint UI:

![Adding a new function](/files/z6wkqA8KVSECiK7rR2aJ)

If you attempt to create a new function that uses a private GitHub repo, a request to set up GitHub OAuth and install the Freshpaint GitHub app will appear. Follow the provided steps to allow your function to be added:

<div align="left"><img src="/files/kxlt6wKFwhI4TF0eXU3e" alt=""></div>

4\. With your function now added, navigate to [Functions under Destinations](https://app.freshpaint.io/destinations/functions), to complete the configuration:

![Configuring an existing function](/files/gwsA6O5AoqNCezJcH8NH)

5\. Complete the configuration by adding your credentials:

![Completing function configuration.](/files/RYzMx97taex00c4WBb3T)

**Your function is now configured and available as a destination.** To send data to this Function, enable it in the same way that existing destinations are enabled on the [events](https://app.freshpaint.io/events/schema) page.

{% hint style="info" %}
**Note on Backfills:** There is no need for any additional backfill-specific configuration. You can rerun all events through the same functions code, as long as the endpoints you're already using can handle the added volume.
{% endhint %}

## Function configuration

You can provide an optional configuration file `config.json` in your function's GitHub repository.  The file should include a JSON object with the following fields:

<table><thead><tr><th width="184.9698146443518">Key</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code>configFields</code> (optional)</td><td>ConfigFields (see below)</td><td>Configurable settings</td></tr><tr><td><code>configName</code> (optional)</td><td>string</td><td>The name to show when a destination or source is configured from the function</td></tr><tr><td><code>configHelp</code> (optional)</td><td>string</td><td>A description of how to correctly configure the function, shown when a user is setting up a source or destination from the function</td></tr><tr><td><code>supportsTrack</code> (optional)</td><td>boolean</td><td>Whether this function supports event tracking (default: true)</td></tr><tr><td><code>supportsCohorts</code> (optional)</td><td>boolean</td><td>Whether this function supports cohorts as user properties sent to <code>onIdentity</code> (default: true)</td></tr><tr><td><code>supportsBackfill</code> (optional)</td><td>boolean</td><td>Whether this function supports backfills of historical events  (default: true)</td></tr></tbody></table>

### Config Fields

<table><thead><tr><th>Key</th><th width="150">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>key</code></td><td>string</td><td>The key on the <code>settings</code> object sent to the function</td></tr><tr><td><code>name</code></td><td>string</td><td>The human-readable name of the field shown in the UI</td></tr><tr><td><code>required</code></td><td>boolean</td><td>Whether this field is required for the config to be valid</td></tr><tr><td><code>description</code></td><td>string</td><td>Description of the field shown in the UI</td></tr><tr><td><code>sensitive</code></td><td>boolean</td><td>Whether the field should be treated as sensitive</td></tr><tr><td><code>type</code></td><td>string</td><td>The type of the field (see below)</td></tr><tr><td><code>options</code></td><td><code>{"value": string, "label": string}</code></td><td>For <code>select</code> and <code>radio</code>, the options available to the user. <code>value</code> is passed in the <code>settings</code> object, <code>label</code> is shown to the user configuring the function.</td></tr><tr><td><code>defaultValue</code></td><td><code>type</code></td><td>The default value</td></tr></tbody></table>

#### Types of config fields

There are several different types you can use for your config field

* `string`
* `boolean`
* `number`
* `list` - A list of strings
* `select` - A dropdown menu
* `radio` - A set of radio buttons

## Writing your function

Each handler (`onTrack`, `onIdentify`, `onGroup`, and `onPage`) accepts two parameters:

| Parameter  | Type   | Description                                                                                                                        |
| ---------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| `event`    | object | The event data. See [Event Format](#event-format) for details                                                                      |
| `settings` | object | The configuration fields as specified in your `config.json` file, with the configuration values you've configured per-environment. |

### Event Format

The format of the `event` argument passed to your event handlers differs slightly depending on which handler (`onTrack`, `onIdentify`, `onGroup`, and `onPage`) is being invoked. Details about the shape of the object can be found below:

* [#base-properties-present-on-all-event-objects](#base-properties-present-on-all-event-objects "mention")
* [#additional-event-object-properties-ongroup](#additional-event-object-properties-ongroup "mention")
* [#additional-event-object-properties-onidentify](#additional-event-object-properties-onidentify "mention")
* [#additional-event-object-properties-onpage](#additional-event-object-properties-onpage "mention")
* [#additional-event-object-properties-ontrack](#additional-event-object-properties-ontrack "mention")

### Base properties present on all event objects

The following base properties are available on every event object regardless of the handler.

<table><thead><tr><th width="246.66666666666666">Key</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code>type</code></td><td>string</td><td><p>The type of the event</p><p>Example: <code>"track"</code>, <code>"identify"</code>, <code>"page"</code>, or <code>"group"</code></p></td></tr><tr><td><code>messageId</code></td><td>string</td><td>Unique id identifying this event</td></tr><tr><td><code>anonymousId</code></td><td>string</td><td>The ID of the device the identify call was performed on.</td></tr><tr><td><code>userId</code></td><td>optional string</td><td>An identifier that uniquely identifies the user that performed the event (usually email address)</td></tr><tr><td><code>context</code></td><td>object</td><td>An object describing the context that created this event</td></tr><tr><td><code>timestamp</code></td><td>string</td><td>The time the event occurred, formatted via <a href="https://www.rfc-editor.org/rfc/rfc3339">RFC3339</a>.<br>Example: <code>"2022-08-08T17:15:45Z"</code></td></tr></tbody></table>

### Additional properties: onGroup&#x20;

<table><thead><tr><th width="246.66666666666666">Key</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code>groupId</code></td><td>string</td><td>The ID of the group the call was for</td></tr><tr><td><code>traits</code></td><td>object</td><td>An object representing the group's traits</td></tr></tbody></table>

### Additional properties: onIdentify

<table><thead><tr><th width="246.66666666666666">Key</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code>traits</code></td><td>object</td><td>An object representing the identified user's traits</td></tr></tbody></table>

### Additional properties: onPage

<table><thead><tr><th width="246.66666666666666">Key</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code>properties</code></td><td>object</td><td>Any additional event properties</td></tr></tbody></table>

### Additional properties: onTrack

<table><thead><tr><th width="246.66666666666666">Key</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code>event</code></td><td>string</td><td>The name of the event</td></tr><tr><td><code>properties</code></td><td>object</td><td>Any additional event properties</td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://documentation.freshpaint.io/integrations/destinations/functions/creating-new-functions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
