Skip to content

Commit 248958d

Browse files
Merge branch 'master' into develop
2 parents 100ee70 + 95e2a33 commit 248958d

File tree

8 files changed

+414
-89
lines changed

8 files changed

+414
-89
lines changed

src/_data/sidenav/main.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ sections:
191191
title: Source Functions
192192
- path: /connections/functions/destination-functions
193193
title: Destination Functions
194+
- path: /connections/functions/insert-functions
195+
title: Destination Insert Functions
194196
- path: /connections/functions/environment
195197
title: Functions Environment
196198
- path: /connections/functions/usage
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Functions execute only in response to incoming data, but the environments that functions run in are generally long-running. Because of this, you can use global variables to cache small amounts of information between invocations. For example, you can reduce the number of access tokens you generate by caching a token, and regenerating it only after it expires. Segment cannot make any guarantees about the longevity of environments, but by using this strategy, you can improve the performance and reliability of your Functions by reducing the need for redundant API requests.
2+
3+
This example code fetches an access token from an external API and refreshes it every hour:
4+
5+
```js
6+
const TOKEN_EXPIRE_MS = 60 * 60 * 1000 // 1 hour
7+
let token = null
8+
async function getAccessToken () {
9+
const now = new Date().getTime()
10+
if (!token || now - token.ts > TOKEN_EXPIRE_MS) {
11+
const resp = await fetch('https://example.com/tokens', {
12+
method: 'POST'
13+
}).then(resp => resp.json())
14+
token = {
15+
ts: now,
16+
value: resp.token
17+
}
18+
}
19+
return token.value
20+
}
21+
```
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<!-- Use for destination and insert functions -->
2+
3+
Segment considers a function's execution successful if it finishes without error. You can also `throw` an error to create a failure on purpose. Use these errors to validate event data before processing it, to ensure the function works as expected.
4+
5+
You can `throw` the following pre-defined error types to indicate that the function ran as expected, but that data was not deliverable:
6+
7+
- `EventNotSupported`
8+
- `InvalidEventPayload`
9+
- `ValidationError`
10+
- `RetryError`
11+
12+
The examples show basic uses of these error types.
13+
14+
```js
15+
async function onGroup(event) {
16+
if (!event.traits.company) {
17+
throw new InvalidEventPayload('Company name is required')
18+
}
19+
}
20+
21+
async function onPage(event) {
22+
if (!event.properties.pageName) {
23+
throw new ValidationError('Page name is required')
24+
}
25+
}
26+
27+
async function onAlias(event) {
28+
throw new EventNotSupported('Alias event is not supported')
29+
}
30+
31+
async function onTrack(event) {
32+
let res
33+
try {
34+
res = await fetch('http://example-service.com/api', {
35+
method: 'POST',
36+
headers: {
37+
'Content-Type': 'application/json'
38+
},
39+
body: JSON.stringify({ event })
40+
})
41+
} catch (err) {
42+
// Retry on connection error
43+
throw new RetryError(err.message)
44+
}
45+
if (res.status >= 500 || res.status === 429) {
46+
// Retry on 5xx and 429s (ratelimits)
47+
throw new RetryError(`HTTP Status ${res.status}`)
48+
}
49+
}
50+
51+
```
52+
If you don't supply a function for an event type, Segment throws an `EventNotSupported` error by default.
53+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
If your function throws an error, execution halts immediately. Segment captures the event, any outgoing requests/responses, any logs the function might have printed, as well as the error itself.
2+
3+
Segment then displays the captured error information in the [Event Delivery](/docs/connections/event-delivery/) page for your function. You can use this information to find and fix unexpected errors.
4+
5+
You can throw [an error or a custom error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error){:target="_blank"} and you can also add helpful context in logs using the [`console` API](https://developer.mozilla.org/en-US/docs/Web/API/console){:target="_blank"}. For example:
6+
7+
```js
8+
async function onTrack(event, settings) {
9+
const userId = event.userId
10+
11+
console.log('User ID is', userId)
12+
13+
if (typeof userId !== 'string' || userId.length < 8) {
14+
throw new ValidationError('User ID is invalid')
15+
}
16+
17+
console.log('User ID is valid')
18+
}
19+
```
20+

src/connections/functions/destination-functions.md

Lines changed: 2 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -81,56 +81,7 @@ To change which event type the handler listens to, you can rename it to the name
8181
8282
### Errors and error handling
8383

84-
Segment considers a function's execution successful if it finishes without error. You can also `throw` an error to create a failure on purpose. Use these errors to validate event data before processing it, to ensure the function works as expected.
85-
86-
You can `throw` the following pre-defined error types to indicate that the function ran as expected, but that data was deliverable:
87-
88-
- `EventNotSupported`
89-
- `InvalidEventPayload`
90-
- `ValidationError`
91-
- `RetryError`
92-
93-
The examples show basic uses of these error types.
94-
95-
```js
96-
async function onGroup(event) {
97-
if (!event.traits.company) {
98-
throw new InvalidEventPayload('Company name is required')
99-
}
100-
}
101-
102-
async function onPage(event) {
103-
if (!event.properties.pageName) {
104-
throw new ValidationError('Page name is required')
105-
}
106-
}
107-
108-
async function onAlias(event) {
109-
throw new EventNotSupported('Alias event is not supported')
110-
}
111-
112-
async function onTrack(event) {
113-
let res
114-
try {
115-
res = await fetch('http://example-service.com/api', {
116-
method: 'POST',
117-
headers: {
118-
'Content-Type': 'application/json'
119-
},
120-
body: JSON.stringify({ event })
121-
})
122-
} catch (err) {
123-
// Retry on connection error
124-
throw new RetryError(err.message)
125-
}
126-
if (res.status >= 500 || res.status === 429) {
127-
// Retry on 5xx and 429s (ratelimits)
128-
throw new RetryError(`HTTP Status ${res.status}`)
129-
}
130-
}
131-
132-
```
133-
If you don't supply a function for an event type, Segment throws an `EventNotSupported` error by default.
84+
{% include content/functions/errors-and-error-handling.md %}
13485

13586
You can read more about [error handling](#destination-functions-logs-and-errors) below.
13687

@@ -379,43 +330,7 @@ You can also choose to **Save & Deploy** to save the changes, and then choose wh
379330

380331
## Destination functions logs and errors
381332

382-
A function can throw errors, or Segment might encounter errors while invoking your function. You can view these errors in the [Event Delivery](/docs/connections/event-delivery/) tab for your Destination as in the example below.
383-
384-
![A screenshot of the event delivery tab, showing 519 failed events broken into categories explaining why they failed](images/event-delivery.png)
385-
386-
### Destination functions error types
387-
388-
- **Bad Request** - Any error thrown by the function code that is not covered by the other errors.
389-
- **Invalid Settings** - A configuration error prevented Segment from executing your code. If this error persists for more than an hour, [contact Segment Support](https://segment.com/help/contact/){:target="_blank"}.
390-
- **Message Rejected** - Your code threw `InvalidEventPayload` or `ValidationError` due to invalid input.
391-
- **Unsupported Event Type** - Your code doesn't implement a specific event type (for example, `onTrack()`) or threw an `EventNotSupported` error.
392-
- **Retry** - Your code threw `RetryError` indicating that the function should be retried.
393-
394-
Segment only attempts to send the event to your destination function again if a **Retry** error occurs.
395-
396-
You can view Segment's list of [Integration Error Codes](/docs/connections/integration_error_codes/) for more information about what might cause an error.
397-
398-
### Destination functions logs
399-
400-
If your function throws an error, execution halts immediately. Segment captures the event, any outgoing requests/responses, any logs the function might have printed, as well as the error itself.
401-
402-
Segment then displays the captured error information in the [Event Delivery](/docs/connections/event-delivery/) page for your destination function. You can use this information to find and fix unexpected errors.
403-
404-
You can throw [an error or a custom error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error){:target="_blank"} and you can also add helpful context in logs using the [`console` API](https://developer.mozilla.org/en-US/docs/Web/API/console){:target="_blank"}. For example:
405-
406-
```js
407-
async function onTrack(event, settings) {
408-
const userId = event.userId
409-
410-
console.log('User ID is', userId)
411-
412-
if (typeof userId !== 'string' || userId.length < 8) {
413-
throw new ValidationError('User ID is invalid')
414-
}
415-
416-
console.log('User ID is valid')
417-
}
418-
```
333+
{% include content/functions/logs.md %}
419334

420335
> warning ""
421336
> **Warning:** Do not log sensitive data, such as personally-identifying information (PII), authentication tokens, or other secrets. Avoid logging entire request/response payloads. The **Function Logs** tab may be visible to other workspace members if they have the necessary permissions.

src/connections/functions/environment.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ When you create a function, write code for it, and save it, the function appears
1616
Only [Functions admins](#functions-permissions) can create or edit functions.
1717

1818
1. From your workspace, go to the Catalog and click the [Functions tab](https://app.segment.com/goto-my-workspace/functions/catalog){:target="_blank"}.
19-
2. Click **New Function**.
19+
2. Click **Create function**.
2020
3. Select the type of function you want to build, and click **Build**.
2121

2222
When you click **Build**, a code editor appears. Different template code is available depending on which type of function you created.

src/connections/functions/index.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Functions let you create your own sources and destinations directly within your
1010
![An image illustrating source functions and destination functions in a Segment workspace](images/functions_overview.png)
1111

1212
## What can you do with Functions?
13-
Functions can help you bring external data into Segment ([Source functions](/docs/connections/functions/source-functions)) and send data in Segment out to external destinations ([Destination functions](/docs/connections/functions/destination-functions)). Functions are scoped to your specific workspace. If you're a technology partner and want to build a new integration and publish it in Segment's catalog, see the [Developer Center documentation](/docs/partners/).
13+
Functions can help you bring external data into Segment ([Source functions](/docs/connections/functions/source-functions)) and send data in Segment out to external destinations ([Destination functions](/docs/connections/functions/destination-functions)). Use [Insert functions](/docs/connections/functions/insert-functions) to transform data before it reaches your downstream destinations. Functions are scoped to your specific workspace. If you're a technology partner and want to build a new integration and publish it in Segment's catalog, see the [Developer Center documentation](/docs/partners/).
1414

1515
#### Source functions
1616
Source functions receive external data from a webhook and can create Segment events, objects, or both. Source functions have access to the full power of JavaScript so you can validate and transform the incoming data and even make external API requests to annotate your data.
@@ -31,3 +31,16 @@ Use cases:
3131
- Enrich outgoing data using external APIs
3232

3333
Learn more about [destination functions](/docs/connections/functions/destination-functions).
34+
35+
#### Destination insert functions
36+
Destination insert functions help you enrich your data with code before you send it to downstream destinations.
37+
38+
> info "Destination Insert Functions in Private Beta"
39+
> Destination Insert Functions is in Private Beta, and Segment is actively working on this feature. Some functionality may change before it becomes generally available. [Contact Segment](https://segment.com/help/contact/){:target="_blank"} with any feedback or questions.
40+
41+
Use cases:
42+
- Implement custom logic and enrich data with third party sources
43+
- Transform outgoing data with advanced filtration and computation
44+
- Ensure data compliance by performing tokenisation, encryption, or decryption before sending data downstream
45+
46+
To learn more, visit [destination insert functions](/docs/connections/functions/insert-functions).

0 commit comments

Comments
 (0)