Skip to content

[Wingify] - new cloud more Destination#3839

Open
atharvnagar-git wants to merge 1 commit into
segmentio:mainfrom
atharvnagar-git:domain_name_change
Open

[Wingify] - new cloud more Destination#3839
atharvnagar-git wants to merge 1 commit into
segmentio:mainfrom
atharvnagar-git:domain_name_change

Conversation

@atharvnagar-git

Copy link
Copy Markdown

Adds a new Wingify Cloud Mode (Actions) cloud destination (actions-wingify-cloud) to support Wingify’s updated event ingestion infrastructure. The existing VWO destination is left unchanged so current integrations keep working.Adds a new Wingify Cloud Mode (Actions) cloud destination (actions-wingify-cloud) to support Wingify’s updated event ingestion infrastructure. The existing VWO destination is left unchanged so current integrations keep working.

Testing

Include any additional information about the testing you have completed to
ensure your changes behave as expected. For a speedy review, please check
any of the tasks you completed below during your testing.

  • Added unit tests for new functionality
  • Tested end-to-end using the local server
  • [If destination is already live] Tested for backward compatibility of destination. Note: New required fields are a breaking change.
  • [Segmenters] Tested in the staging environment
  • [Segmenters] [If applicable for this change] Tested for regression with Hadron.

Security Review

Please ensure sensitive data is properly protected in your integration.

  • Reviewed all field definitions for sensitive data (API keys, tokens, passwords, client secrets) and confirmed they use type: 'password'

New Destination Checklist

  • Extracted all action API versions to verioning-info.ts file. example

}
},
testAuthentication: (_request, { settings }) => {
if (settings.wingifyAccountId < 1 || settings.wingifyAccountId.toString().length > 7) {

@joe-ayoub-segment joe-ayoub-segment Jun 18, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intent for testAuthentication is that you actually check that the credentials passed by the cusomer are valid. If that's what's happening here it's OK. But usually you'd use the request object to make an API request to verify this.
Please confirm.

Also, please throw an InvalidAuthenticationError instead or a regular Error.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new cloud-mode destination under packages/destination-actions/src/destinations/wingify (“Wingify Cloud Mode (Actions)”, slug actions-wingify-cloud) with actions for Track, Identify, Page, and Audience sync, plus supporting utilities/types and unit tests.

Changes:

  • Introduces the Wingify destination definition (auth + presets + actions).
  • Implements four Wingify actions (trackEvent, identifyUser, pageVisit, syncAudience) plus shared payload utilities/types.
  • Adds unit tests for the destination and each action.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 23 comments.

Show a summary per file
File Description
packages/destination-actions/src/destinations/wingify/index.ts New destination definition (presets, auth, action wiring).
packages/destination-actions/src/destinations/wingify/generated-types.ts Generated Settings type for Wingify destination.
packages/destination-actions/src/destinations/wingify/utility.ts Shared host map, payload formatting, and UUID generation helpers.
packages/destination-actions/src/destinations/wingify/types.ts Shared payload type definitions.
packages/destination-actions/src/destinations/wingify/trackEvent/index.ts Track action implementation posting Wingify event payloads.
packages/destination-actions/src/destinations/wingify/trackEvent/generated-types.ts Generated payload types for Track action.
packages/destination-actions/src/destinations/wingify/trackEvent/tests/index.test.ts Unit tests for Track action behavior/request shape.
packages/destination-actions/src/destinations/wingify/identifyUser/index.ts Identify action implementation mapping traits to Wingify visitor attributes.
packages/destination-actions/src/destinations/wingify/identifyUser/generated-types.ts Generated payload types for Identify action.
packages/destination-actions/src/destinations/wingify/identifyUser/tests/index.test.ts Unit tests for Identify action behavior/request shape.
packages/destination-actions/src/destinations/wingify/pageVisit/index.ts Page action implementation posting page visit payloads.
packages/destination-actions/src/destinations/wingify/pageVisit/generated-types.ts Generated payload types for Page action.
packages/destination-actions/src/destinations/wingify/pageVisit/tests/index.test.ts Unit tests for Page action behavior/request shape.
packages/destination-actions/src/destinations/wingify/syncAudience/index.ts Audience sync action implementation posting audience enter/exit payloads.
packages/destination-actions/src/destinations/wingify/syncAudience/generated-types.ts Generated payload types for Audience sync action.
packages/destination-actions/src/destinations/wingify/syncAudience/tests/index.test.ts Unit tests for Audience sync action behavior/request shape.
packages/destination-actions/src/destinations/wingify/tests/index.test.ts Tests for auth validation and UUID generator.

authentication: {
scheme: 'custom',
fields: {
vwoAccountId: {

const destination: DestinationDefinition<Settings> = {
name: 'Wingify Cloud Mode (Actions)',
slug: 'actions-wingify-cloud',

const testDestination = createTestIntegration(Destination)

const BASE_ENDPOINT = 'https://dev.visualwebsiteoptimizer.com'
Comment on lines +18 to +20
properties: {
wingifyUuid: wingifyUuid
}

const testDestination = createTestIntegration(Destination)

const BASE_ENDPOINT = 'https://dev.visualwebsiteoptimizer.com'
const event = createTestEvent({
event: 'testEvent',
properties: {
wingifyUuid: wingifyUuid,
it('should send Page Visit event to Wingify', async () => {
const event = createTestEvent({
properties: {
wingifyUuid: wingifyUuid
it('should send Page Visit event to Wingify', async () => {
const event = createTestEvent({
properties: {
wingifyUuid: wingifyUuid
it('should send Page Visit event to Wingify', async () => {
const event = createTestEvent({
properties: {
wingifyUuid: wingifyUuid
Comment on lines +106 to +112
export function formatAttributes(attributes: { [k: string]: unknown } | undefined) {
const formattedAttributes: { [k: string]: unknown } = {}
for (const key in attributes) {
formattedAttributes[`segment.${key}`] = attributes[key]
}
return formattedAttributes
}
required: false,
type: 'string',
default: {
'@path': '$.context.ip'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a heads up here. If a customer sends a payload from a mobile or web device (using Segment mobile or web libraries), then the IP address will be useful.

However if the customer sends data using one of Segment's server side libraries, the IP address will become the IP address of Segment's server. This is probably not very useful to you. So be careful with assigning a default like this to a server side integration.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to change this in the other actions too.

const action: ActionDefinition<Settings, Payload> = {
title: 'Sync Audience',
description: 'Syncs Segment audiences to Wingify',
defaultSubscription: 'event = "Audience Entered" or event = "Audience Exited"',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Customers can change audience event names, so we should not rely on "Audience Entered" or "Audience Exited". I suggest changing this to type = identify or type = track.

Then see below for how to get the action value.

}
}
},
perform: (request, { settings, payload }) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
perform: (request, { settings, payload }) => {
perform: async (request, { settings, payload, audienceMembership }) => {

} else if (payload.name == 'Audience Exited') {
action = 'audience_exited'
}
const wingifyPayload = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const wingifyPayload = {
action = audienceMembership ? 'audience_entered' : 'audience_exited'

Comment on lines +41 to +43
default: {
'@path': '$.properties.audience_key'
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
default: {
'@path': '$.properties.audience_key'
}
default: {
'@if': {
exists: { '@path': '$.context.personas.computation_key' },
then: { '@path': '$.context.personas.computation_key' },
else: { '@path': '$.properties.audience_key' }
}
}

@joe-ayoub-segment

Copy link
Copy Markdown
Contributor

Hi @atharvnagar-git I reviewed the PR and left some comments for you to address. Nothing major, but a bunch of important things.
Copilot also did a review. Please take a look at its comments and resolve or close them as necessary.

@joe-ayoub-segment joe-ayoub-segment self-assigned this Jun 18, 2026
@joe-ayoub-segment joe-ayoub-segment changed the title feat(): addition of new folder for the domain name wingify [Wingify] - new cloud more Destination Jun 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants