@walkeros/server-destination-reddit 3.4.2 → 4.0.0-next-1777882869103
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev.js +1 -1
- package/dist/dev.js.map +1 -1
- package/dist/dev.mjs +1 -1
- package/dist/dev.mjs.map +1 -1
- package/dist/examples/index.js +18 -32
- package/dist/examples/index.mjs +18 -32
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/walkerOS.json +26 -96
- package/package.json +4 -4
package/dist/dev.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,
|
|
1
|
+
"use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,n=(e,a)=>{for(var r in a)t(e,r,{get:a[r],enumerable:!0})},s={};n(s,{examples:()=>y,schemas:()=>d}),module.exports=(e=s,((e,n,s,d)=>{if(n&&"object"==typeof n||"function"==typeof n)for(let o of r(n))i.call(e,o)||o===s||t(e,o,{get:()=>n[o],enumerable:!(d=a(n,o))||d.enumerable});return e})(t({},"__esModule",{value:!0}),e));var d={};n(d,{ActionSourceSchema:()=>p,MappingSchema:()=>l,SettingsSchema:()=>v,TrackingTypeSchema:()=>m,mapping:()=>_,settings:()=>g});var o=require("@walkeros/core/dev"),c=require("@walkeros/core/dev"),u=require("@walkeros/core/dev"),p=u.z.enum(["WEBSITE","APP","PHYSICAL_STORE"]),m=u.z.enum(["PageVisit","ViewContent","Search","AddToCart","AddToWishlist","Purchase","Lead","SignUp","Custom"]),v=c.z.object({accessToken:c.z.string().min(1).describe("Reddit Conversion Access Token for Bearer authentication (like rdt_ABC123...)"),pixelId:c.z.string().min(1).describe("Reddit Pixel ID used as the API path parameter (like a2_abcdef123456)"),action_source:p.describe("Source of the event (WEBSITE, APP, PHYSICAL_STORE) (like WEBSITE)").optional(),doNotHash:c.z.array(c.z.string()).describe("Array of user fields that should not be hashed (like ['email'])").optional(),test_mode:c.z.boolean().describe("Enable test mode by sending test_mode: true in the request body (like true)").optional(),url:c.z.string().url().describe("Custom URL for Reddit Conversions API endpoint (like https://ads-api.reddit.com/api/v2.0/conversions/events/)").optional(),user_data:c.z.record(c.z.string(),c.z.string()).describe("Mapping configuration for user fields (like { email: 'user.email', external_id: 'user.id' })").optional()}),l=require("@walkeros/core/dev").z.object({}),g=(0,o.zodToSchema)(v),_=(0,o.zodToSchema)(l),y={};n(y,{env:()=>f,step:()=>S});var f={};n(f,{push:()=>h,simulation:()=>b});var h={sendServer:async()=>({ok:!0,data:{success:!0}})},b=["sendServer"],S={};n(S,{addToCart:()=>E,lead:()=>w,pageVisit:()=>R,purchase:()=>T,search:()=>z,signUp:()=>x});var k=require("@walkeros/core"),A="https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456",P={headers:{Authorization:"Bearer s3cr3t"}},T={title:"Purchase",description:"A completed order is sent to the Reddit Conversions API as a Purchase event with value, currency, and items.",in:(0,k.getEvent)("order complete",{id:"ev-1700000900",timestamp:1700000900,data:{id:"ORD-300",total:249.99,currency:"EUR"},nested:[{entity:"product",data:{id:"SKU-A1",name:"Everyday Ruck Snack",category:"bags",price:"129.99",quantity:2}}],user:{id:"user-123",device:"device-456"},source:{type:"express",platform:"server"}}),mapping:{name:"Purchase",data:{map:{event_metadata:{map:{value_decimal:"data.total",currency:{key:"data.currency",value:"EUR"},item_count:{fn:e=>e.nested.filter(e=>"product"===e.entity).length},products:{loop:["nested",{condition:e=>(0,k.isObject)(e)&&"product"===e.entity,map:{id:"data.id",name:"data.name",category:{key:"data.category",value:"uncategorized"}}}]}}}}}},out:[["sendServer",A,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.900Z",event_at_ms:1700000900,event_type:{tracking_type:"Purchase"},user:{},event_metadata:{conversion_id:"ev-1700000900",value_decimal:249.99,currency:"EUR",item_count:1,products:[{id:"SKU-A1",name:"Everyday Ruck Snack",category:"bags"}]}}]}}),P]]},E={title:"Add to cart",description:"A product add is sent to Reddit as an AddToCart conversion with value and product details.",in:(0,k.getEvent)("product add",{id:"ev-1700000901",timestamp:1700000901,data:{id:"SKU-B2",name:"Cool Cap",category:"hats",price:"42.00",quantity:1},user:{id:"user-456"},source:{type:"express",platform:"server"}}),mapping:{name:"AddToCart",data:{map:{event_metadata:{map:{value_decimal:"data.price",currency:{value:"EUR"},item_count:{value:1},products:{set:[{map:{id:"data.id",name:"data.name",category:{key:"data.category",value:"uncategorized"}}}]}}}}}},out:[["sendServer",A,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.901Z",event_at_ms:1700000901,event_type:{tracking_type:"AddToCart"},user:{},event_metadata:{conversion_id:"ev-1700000901",value_decimal:"42.00",currency:"EUR",item_count:1,products:[{id:"SKU-B2",name:"Cool Cap",category:"hats"}]}}]}}),P]]},R={title:"Page visit",description:"A page view is sent to Reddit as a PageVisit conversion used for retargeting audiences.",in:(0,k.getEvent)("page view",{id:"ev-1700000902",timestamp:1700000902,user:{id:"user-789"},source:{type:"express",platform:"server"}}),mapping:{name:"PageVisit"},out:[["sendServer",A,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.902Z",event_at_ms:1700000902,event_type:{tracking_type:"PageVisit"},user:{},event_metadata:{conversion_id:"ev-1700000902"}}]}}),P]]},w={title:"Lead",description:"A form submission is sent to Reddit as a Lead conversion with the SHA-256 hashed email and external id.",in:(0,k.getEvent)("form submit",{id:"ev-1700000903",timestamp:1700000903,data:{form:"contact"},user:{id:"user-lead-1",email:"lead@example.com"},source:{type:"express",platform:"server"}}),mapping:{name:"Lead",data:{map:{user:{map:{email:"user.email",external_id:"user.id"}}}}},out:[["sendServer",A,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.903Z",event_at_ms:1700000903,event_type:{tracking_type:"Lead"},user:{email:"9fbdefe2837a03c9225be80e741f316f4d174d1732b719b6abb6477efc1ae9d2",external_id:"ee818eebb052cf288ffeeb2e09ee35c9946e1a7f53a959cb3ef06d5d4adb78e8"},event_metadata:{conversion_id:"ev-1700000903"}}]}}),P]]},x={title:"Sign up",description:"A user signup is sent to Reddit as a SignUp conversion with hashed user identifiers.",in:(0,k.getEvent)("user signup",{id:"ev-1700000904",timestamp:1700000904,data:{method:"email"},user:{id:"new-user-1",email:"new@example.com"},source:{type:"express",platform:"server"}}),mapping:{name:"SignUp",data:{map:{user:{map:{email:"user.email",external_id:"user.id"}}}}},out:[["sendServer",A,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.904Z",event_at_ms:1700000904,event_type:{tracking_type:"SignUp"},user:{email:"f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716",external_id:"b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde"},event_metadata:{conversion_id:"ev-1700000904"}}]}}),P]]},z={title:"Search",description:"A site search is sent to Reddit as a Search conversion with an item count in event_metadata.",in:(0,k.getEvent)("site search",{id:"ev-1700000905",timestamp:1700000905,data:{query:"walkerOS destinations"},user:{id:"user-101"},source:{type:"express",platform:"server"}}),mapping:{name:"Search",data:{map:{event_metadata:{map:{item_count:{value:1}}}}}},out:[["sendServer",A,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.905Z",event_at_ms:1700000905,event_type:{tracking_type:"Search"},user:{},event_metadata:{conversion_id:"ev-1700000905",item_count:1}}]}}),P]]};//# sourceMappingURL=dev.js.map
|
package/dist/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/primitives.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport * from './primitives';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\nimport { ActionSourceSchema } from './primitives';\n\nexport const SettingsSchema = z.object({\n accessToken: z\n .string()\n .min(1)\n .describe(\n 'Reddit Conversion Access Token for Bearer authentication (like rdt_ABC123...)',\n ),\n pixelId: z\n .string()\n .min(1)\n .describe(\n 'Reddit Pixel ID used as the API path parameter (like a2_abcdef123456)',\n ),\n action_source: ActionSourceSchema.describe(\n 'Source of the event (WEBSITE, APP, PHYSICAL_STORE) (like WEBSITE)',\n ).optional(),\n doNotHash: z\n .array(z.string())\n .describe(\"Array of user fields that should not be hashed (like ['email'])\")\n .optional(),\n test_mode: z\n .boolean()\n .describe(\n 'Enable test mode by sending test_mode: true in the request body (like true)',\n )\n .optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom URL for Reddit Conversions API endpoint (like https://ads-api.reddit.com/api/v2.0/conversions/events/)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping configuration for user fields (like { email: 'user.email', external_id: 'user.id' })\",\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Action Source Enum\n * Where the conversion event took place\n * https://ads-api.reddit.com/docs/v2/#tag/Conversions-API\n */\nexport const ActionSourceSchema = z.enum(['WEBSITE', 'APP', 'PHYSICAL_STORE']);\n\n/**\n * Tracking Type\n * Standard Reddit Conversions API event types.\n * Custom events use `Custom` with a `custom_event_name`.\n */\nexport const TrackingTypeSchema = z.enum([\n 'PageVisit',\n 'ViewContent',\n 'Search',\n 'AddToCart',\n 'AddToWishlist',\n 'Purchase',\n 'Lead',\n 'SignUp',\n 'Custom',\n]);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Reddit Conversions API Mapping Schema\n * Reddit CAPI has no event-level mapping configuration\n */\nexport const MappingSchema = z.object({});\n\n/**\n * Type inference from MappingSchema\n */\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { SendDataValue, SendResponse } from '@walkeros/core';\nimport type { SendServerOptions } from '@walkeros/server-core';\nimport type { Env } from '../types';\n\n/**\n * Example environment configurations for Reddit Conversions API destination\n *\n * These environments provide standardized mock structures for testing\n * and development without requiring actual HTTP requests.\n */\n\ntype MockSendServer = (\n url: string,\n data?: SendDataValue,\n options?: SendServerOptions,\n) => Promise<SendResponse>;\n\n/**\n * Mock sendServer function that simulates successful HTTP responses\n */\nconst mockSendServer: MockSendServer = async () => {\n // Simulate successful Reddit API response\n return {\n ok: true,\n data: {\n success: true,\n },\n };\n};\n\n/**\n * Standard mock environment for push operations\n *\n * Use this for testing Reddit Conversions API events without making\n * actual HTTP requests to Reddit's servers.\n */\nexport const push: Env = {\n sendServer: mockSendServer,\n};\n\nexport const simulation = ['sendServer'];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { getEvent, isObject } from '@walkeros/core';\n\n/**\n * Reddit Conversions API step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), options)` where\n * `endpoint = ${settings.url}${settings.pixelId}` and\n * `body = { data: { events: [hashedServerEvent] } }`.\n *\n * Test fixture pins `pixelId = 'a2_abcdef123456'` and the default url, so\n * every endpoint resolves to:\n * https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456\n *\n * The serverEvent keys are assembled in this order (insertion order matters\n * for `JSON.stringify` string equality):\n * 1. event_at (ISO timestamp)\n * 2. event_at_ms\n * 3. event_type ({ tracking_type, custom_event_name? })\n * 4. ...restEventData (mapped event data minus user/event_metadata/click_id)\n * 5. user (hashed — email, external_id, ip_address, user_agent, idfa, aaid)\n * 6. event_metadata (conversion_id first, then merged metadata)\n * 7. click_id (only when a string is present)\n *\n * `options` carries the Authorization: Bearer <accessToken> header.\n */\nconst ENDPOINT =\n 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456';\nconst OPTIONS = {\n headers: { Authorization: 'Bearer s3cr3t' },\n};\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase',\n description:\n 'A completed order is sent to the Reddit Conversions API as a Purchase event with value, currency, and items.',\n in: getEvent('order complete', {\n timestamp: 1700000900,\n data: { id: 'ORD-300', total: 249.99, currency: 'EUR' },\n nested: [\n {\n entity: 'product',\n data: {\n id: 'SKU-A1',\n name: 'Everyday Ruck Snack',\n category: 'bags',\n price: '129.99',\n quantity: 2,\n },\n },\n ],\n user: { id: 'user-123', device: 'device-456' },\n source: { type: 'server', id: 'https://shop.example.com', previous_id: '' },\n }),\n mapping: {\n name: 'Purchase',\n data: {\n map: {\n event_metadata: {\n map: {\n value_decimal: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n item_count: {\n fn: (event: unknown) =>\n (event as WalkerOS.Event).nested.filter(\n (item) => item.entity === 'product',\n ).length,\n },\n products: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n name: 'data.name',\n category: { key: 'data.category', value: 'uncategorized' },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.900Z',\n event_at_ms: 1700000900,\n event_type: { tracking_type: 'Purchase' },\n user: {},\n event_metadata: {\n conversion_id: '1700000900-gr0up-1',\n value_decimal: 249.99,\n currency: 'EUR',\n item_count: 1,\n products: [\n {\n id: 'SKU-A1',\n name: 'Everyday Ruck Snack',\n category: 'bags',\n },\n ],\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A product add is sent to Reddit as an AddToCart conversion with value and product details.',\n in: getEvent('product add', {\n timestamp: 1700000901,\n data: {\n id: 'SKU-B2',\n name: 'Cool Cap',\n category: 'hats',\n price: '42.00',\n quantity: 1,\n },\n user: { id: 'user-456' },\n source: {\n type: 'server',\n id: 'https://shop.example.com/products',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'AddToCart',\n data: {\n map: {\n event_metadata: {\n map: {\n value_decimal: 'data.price',\n currency: { value: 'EUR' },\n item_count: { value: 1 },\n products: {\n set: [\n {\n map: {\n id: 'data.id',\n name: 'data.name',\n category: { key: 'data.category', value: 'uncategorized' },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.901Z',\n event_at_ms: 1700000901,\n event_type: { tracking_type: 'AddToCart' },\n user: {},\n event_metadata: {\n conversion_id: '1700000901-gr0up-1',\n value_decimal: '42.00',\n currency: 'EUR',\n item_count: 1,\n products: [\n { id: 'SKU-B2', name: 'Cool Cap', category: 'hats' },\n ],\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const pageVisit: Flow.StepExample = {\n title: 'Page visit',\n description:\n 'A page view is sent to Reddit as a PageVisit conversion used for retargeting audiences.',\n in: getEvent('page view', {\n timestamp: 1700000902,\n user: { id: 'user-789' },\n source: {\n type: 'server',\n id: 'https://www.example.com/docs/',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'PageVisit',\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.902Z',\n event_at_ms: 1700000902,\n event_type: { tracking_type: 'PageVisit' },\n user: {},\n event_metadata: { conversion_id: '1700000902-gr0up-1' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const lead: Flow.StepExample = {\n title: 'Lead',\n description:\n 'A form submission is sent to Reddit as a Lead conversion with the SHA-256 hashed email and external id.',\n in: getEvent('form submit', {\n timestamp: 1700000903,\n data: { form: 'contact' },\n user: { id: 'user-lead-1', email: 'lead@example.com' },\n source: {\n type: 'server',\n id: 'https://www.example.com/contact',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'Lead',\n data: {\n map: {\n user: {\n map: {\n email: 'user.email',\n external_id: 'user.id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.903Z',\n event_at_ms: 1700000903,\n event_type: { tracking_type: 'Lead' },\n user: {\n // sha256('lead@example.com')\n email:\n '9fbdefe2837a03c9225be80e741f316f4d174d1732b719b6abb6477efc1ae9d2',\n // sha256('user-lead-1')\n external_id:\n 'ee818eebb052cf288ffeeb2e09ee35c9946e1a7f53a959cb3ef06d5d4adb78e8',\n },\n event_metadata: { conversion_id: '1700000903-gr0up-1' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const signUp: Flow.StepExample = {\n title: 'Sign up',\n description:\n 'A user signup is sent to Reddit as a SignUp conversion with hashed user identifiers.',\n in: getEvent('user signup', {\n timestamp: 1700000904,\n data: { method: 'email' },\n user: { id: 'new-user-1', email: 'new@example.com' },\n source: {\n type: 'server',\n id: 'https://www.example.com/register',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'SignUp',\n data: {\n map: {\n user: {\n map: {\n email: 'user.email',\n external_id: 'user.id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.904Z',\n event_at_ms: 1700000904,\n event_type: { tracking_type: 'SignUp' },\n user: {\n // sha256('new@example.com')\n email:\n 'f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716',\n // sha256('new-user-1')\n external_id:\n 'b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde',\n },\n event_metadata: { conversion_id: '1700000904-gr0up-1' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const search: Flow.StepExample = {\n title: 'Search',\n description:\n 'A site search is sent to Reddit as a Search conversion with an item count in event_metadata.',\n in: getEvent('site search', {\n timestamp: 1700000905,\n data: { query: 'walkerOS destinations' },\n user: { id: 'user-101' },\n source: {\n type: 'server',\n id: 'https://www.example.com/search',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'Search',\n data: {\n map: {\n event_metadata: {\n map: {\n item_count: { value: 1 },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.905Z',\n event_at_ms: 1700000905,\n event_type: { tracking_type: 'Search' },\n user: {},\n event_metadata: {\n conversion_id: '1700000905-gr0up-1',\n item_count: 1,\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n"],"mappings":"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","names":["import_dev","import_dev","import_dev"]}
|
|
1
|
+
{"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/primitives.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport * from './primitives';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\nimport { ActionSourceSchema } from './primitives';\n\nexport const SettingsSchema = z.object({\n accessToken: z\n .string()\n .min(1)\n .describe(\n 'Reddit Conversion Access Token for Bearer authentication (like rdt_ABC123...)',\n ),\n pixelId: z\n .string()\n .min(1)\n .describe(\n 'Reddit Pixel ID used as the API path parameter (like a2_abcdef123456)',\n ),\n action_source: ActionSourceSchema.describe(\n 'Source of the event (WEBSITE, APP, PHYSICAL_STORE) (like WEBSITE)',\n ).optional(),\n doNotHash: z\n .array(z.string())\n .describe(\"Array of user fields that should not be hashed (like ['email'])\")\n .optional(),\n test_mode: z\n .boolean()\n .describe(\n 'Enable test mode by sending test_mode: true in the request body (like true)',\n )\n .optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom URL for Reddit Conversions API endpoint (like https://ads-api.reddit.com/api/v2.0/conversions/events/)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping configuration for user fields (like { email: 'user.email', external_id: 'user.id' })\",\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Action Source Enum\n * Where the conversion event took place\n * https://ads-api.reddit.com/docs/v2/#tag/Conversions-API\n */\nexport const ActionSourceSchema = z.enum(['WEBSITE', 'APP', 'PHYSICAL_STORE']);\n\n/**\n * Tracking Type\n * Standard Reddit Conversions API event types.\n * Custom events use `Custom` with a `custom_event_name`.\n */\nexport const TrackingTypeSchema = z.enum([\n 'PageVisit',\n 'ViewContent',\n 'Search',\n 'AddToCart',\n 'AddToWishlist',\n 'Purchase',\n 'Lead',\n 'SignUp',\n 'Custom',\n]);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Reddit Conversions API Mapping Schema\n * Reddit CAPI has no event-level mapping configuration\n */\nexport const MappingSchema = z.object({});\n\n/**\n * Type inference from MappingSchema\n */\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { SendDataValue, SendResponse } from '@walkeros/core';\nimport type { SendServerOptions } from '@walkeros/server-core';\nimport type { Env } from '../types';\n\n/**\n * Example environment configurations for Reddit Conversions API destination\n *\n * These environments provide standardized mock structures for testing\n * and development without requiring actual HTTP requests.\n */\n\ntype MockSendServer = (\n url: string,\n data?: SendDataValue,\n options?: SendServerOptions,\n) => Promise<SendResponse>;\n\n/**\n * Mock sendServer function that simulates successful HTTP responses\n */\nconst mockSendServer: MockSendServer = async () => {\n // Simulate successful Reddit API response\n return {\n ok: true,\n data: {\n success: true,\n },\n };\n};\n\n/**\n * Standard mock environment for push operations\n *\n * Use this for testing Reddit Conversions API events without making\n * actual HTTP requests to Reddit's servers.\n */\nexport const push: Env = {\n sendServer: mockSendServer,\n};\n\nexport const simulation = ['sendServer'];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { getEvent, isObject } from '@walkeros/core';\n\n/**\n * Reddit Conversions API step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), options)` where\n * `endpoint = ${settings.url}${settings.pixelId}` and\n * `body = { data: { events: [hashedServerEvent] } }`.\n *\n * Test fixture pins `pixelId = 'a2_abcdef123456'` and the default url, so\n * every endpoint resolves to:\n * https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456\n *\n * The serverEvent keys are assembled in this order (insertion order matters\n * for `JSON.stringify` string equality):\n * 1. event_at (ISO timestamp)\n * 2. event_at_ms\n * 3. event_type ({ tracking_type, custom_event_name? })\n * 4. ...restEventData (mapped event data minus user/event_metadata/click_id)\n * 5. user (hashed - email, external_id, ip_address, user_agent, idfa, aaid)\n * 6. event_metadata (conversion_id first, then merged metadata)\n * 7. click_id (only when a string is present)\n *\n * `options` carries the Authorization: Bearer <accessToken> header.\n */\nconst ENDPOINT =\n 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456';\nconst OPTIONS = {\n headers: { Authorization: 'Bearer s3cr3t' },\n};\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase',\n description:\n 'A completed order is sent to the Reddit Conversions API as a Purchase event with value, currency, and items.',\n in: getEvent('order complete', {\n id: 'ev-1700000900',\n timestamp: 1700000900,\n data: { id: 'ORD-300', total: 249.99, currency: 'EUR' },\n nested: [\n {\n entity: 'product',\n data: {\n id: 'SKU-A1',\n name: 'Everyday Ruck Snack',\n category: 'bags',\n price: '129.99',\n quantity: 2,\n },\n },\n ],\n user: { id: 'user-123', device: 'device-456' },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: {\n name: 'Purchase',\n data: {\n map: {\n event_metadata: {\n map: {\n value_decimal: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n item_count: {\n fn: (event: unknown) =>\n (event as WalkerOS.Event).nested.filter(\n (item) => item.entity === 'product',\n ).length,\n },\n products: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n name: 'data.name',\n category: { key: 'data.category', value: 'uncategorized' },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.900Z',\n event_at_ms: 1700000900,\n event_type: { tracking_type: 'Purchase' },\n user: {},\n event_metadata: {\n conversion_id: 'ev-1700000900',\n value_decimal: 249.99,\n currency: 'EUR',\n item_count: 1,\n products: [\n {\n id: 'SKU-A1',\n name: 'Everyday Ruck Snack',\n category: 'bags',\n },\n ],\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A product add is sent to Reddit as an AddToCart conversion with value and product details.',\n in: getEvent('product add', {\n id: 'ev-1700000901',\n timestamp: 1700000901,\n data: {\n id: 'SKU-B2',\n name: 'Cool Cap',\n category: 'hats',\n price: '42.00',\n quantity: 1,\n },\n user: { id: 'user-456' },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: {\n name: 'AddToCart',\n data: {\n map: {\n event_metadata: {\n map: {\n value_decimal: 'data.price',\n currency: { value: 'EUR' },\n item_count: { value: 1 },\n products: {\n set: [\n {\n map: {\n id: 'data.id',\n name: 'data.name',\n category: { key: 'data.category', value: 'uncategorized' },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.901Z',\n event_at_ms: 1700000901,\n event_type: { tracking_type: 'AddToCart' },\n user: {},\n event_metadata: {\n conversion_id: 'ev-1700000901',\n value_decimal: '42.00',\n currency: 'EUR',\n item_count: 1,\n products: [\n { id: 'SKU-B2', name: 'Cool Cap', category: 'hats' },\n ],\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const pageVisit: Flow.StepExample = {\n title: 'Page visit',\n description:\n 'A page view is sent to Reddit as a PageVisit conversion used for retargeting audiences.',\n in: getEvent('page view', {\n id: 'ev-1700000902',\n timestamp: 1700000902,\n user: { id: 'user-789' },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: {\n name: 'PageVisit',\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.902Z',\n event_at_ms: 1700000902,\n event_type: { tracking_type: 'PageVisit' },\n user: {},\n event_metadata: { conversion_id: 'ev-1700000902' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const lead: Flow.StepExample = {\n title: 'Lead',\n description:\n 'A form submission is sent to Reddit as a Lead conversion with the SHA-256 hashed email and external id.',\n in: getEvent('form submit', {\n id: 'ev-1700000903',\n timestamp: 1700000903,\n data: { form: 'contact' },\n user: { id: 'user-lead-1', email: 'lead@example.com' },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: {\n name: 'Lead',\n data: {\n map: {\n user: {\n map: {\n email: 'user.email',\n external_id: 'user.id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.903Z',\n event_at_ms: 1700000903,\n event_type: { tracking_type: 'Lead' },\n user: {\n // sha256('lead@example.com')\n email:\n '9fbdefe2837a03c9225be80e741f316f4d174d1732b719b6abb6477efc1ae9d2',\n // sha256('user-lead-1')\n external_id:\n 'ee818eebb052cf288ffeeb2e09ee35c9946e1a7f53a959cb3ef06d5d4adb78e8',\n },\n event_metadata: { conversion_id: 'ev-1700000903' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const signUp: Flow.StepExample = {\n title: 'Sign up',\n description:\n 'A user signup is sent to Reddit as a SignUp conversion with hashed user identifiers.',\n in: getEvent('user signup', {\n id: 'ev-1700000904',\n timestamp: 1700000904,\n data: { method: 'email' },\n user: { id: 'new-user-1', email: 'new@example.com' },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: {\n name: 'SignUp',\n data: {\n map: {\n user: {\n map: {\n email: 'user.email',\n external_id: 'user.id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.904Z',\n event_at_ms: 1700000904,\n event_type: { tracking_type: 'SignUp' },\n user: {\n // sha256('new@example.com')\n email:\n 'f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716',\n // sha256('new-user-1')\n external_id:\n 'b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde',\n },\n event_metadata: { conversion_id: 'ev-1700000904' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const search: Flow.StepExample = {\n title: 'Search',\n description:\n 'A site search is sent to Reddit as a Search conversion with an item count in event_metadata.',\n in: getEvent('site search', {\n id: 'ev-1700000905',\n timestamp: 1700000905,\n data: { query: 'walkerOS destinations' },\n user: { id: 'user-101' },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: {\n name: 'Search',\n data: {\n map: {\n event_metadata: {\n map: {\n item_count: { value: 1 },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.905Z',\n event_at_ms: 1700000905,\n event_type: { tracking_type: 'Search' },\n user: {},\n event_metadata: {\n conversion_id: 'ev-1700000905',\n item_count: 1,\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n"],"mappings":"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","names":["import_dev","import_dev","import_dev"]}
|
package/dist/dev.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.defineProperty,t=(t,a)=>{for(var i in a)e(t,i,{get:a[i],enumerable:!0})},a={};t(a,{ActionSourceSchema:()=>n,MappingSchema:()=>
|
|
1
|
+
var e=Object.defineProperty,t=(t,a)=>{for(var i in a)e(t,i,{get:a[i],enumerable:!0})},a={};t(a,{ActionSourceSchema:()=>n,MappingSchema:()=>m,SettingsSchema:()=>o,TrackingTypeSchema:()=>d,mapping:()=>u,settings:()=>p});import{zodToSchema as i}from"@walkeros/core/dev";import{z as r}from"@walkeros/core/dev";import{z as s}from"@walkeros/core/dev";var n=s.enum(["WEBSITE","APP","PHYSICAL_STORE"]),d=s.enum(["PageVisit","ViewContent","Search","AddToCart","AddToWishlist","Purchase","Lead","SignUp","Custom"]),o=r.object({accessToken:r.string().min(1).describe("Reddit Conversion Access Token for Bearer authentication (like rdt_ABC123...)"),pixelId:r.string().min(1).describe("Reddit Pixel ID used as the API path parameter (like a2_abcdef123456)"),action_source:n.describe("Source of the event (WEBSITE, APP, PHYSICAL_STORE) (like WEBSITE)").optional(),doNotHash:r.array(r.string()).describe("Array of user fields that should not be hashed (like ['email'])").optional(),test_mode:r.boolean().describe("Enable test mode by sending test_mode: true in the request body (like true)").optional(),url:r.string().url().describe("Custom URL for Reddit Conversions API endpoint (like https://ads-api.reddit.com/api/v2.0/conversions/events/)").optional(),user_data:r.record(r.string(),r.string()).describe("Mapping configuration for user fields (like { email: 'user.email', external_id: 'user.id' })").optional()});import{z as c}from"@walkeros/core/dev";var m=c.object({}),p=i(o),u=i(m),v={};t(v,{env:()=>l,step:()=>y});var l={};t(l,{push:()=>_,simulation:()=>g});var _={sendServer:async()=>({ok:!0,data:{success:!0}})},g=["sendServer"],y={};t(y,{addToCart:()=>A,lead:()=>T,pageVisit:()=>P,purchase:()=>k,search:()=>x,signUp:()=>R});import{getEvent as f,isObject as h}from"@walkeros/core";var S="https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456",b={headers:{Authorization:"Bearer s3cr3t"}},k={title:"Purchase",description:"A completed order is sent to the Reddit Conversions API as a Purchase event with value, currency, and items.",in:f("order complete",{id:"ev-1700000900",timestamp:1700000900,data:{id:"ORD-300",total:249.99,currency:"EUR"},nested:[{entity:"product",data:{id:"SKU-A1",name:"Everyday Ruck Snack",category:"bags",price:"129.99",quantity:2}}],user:{id:"user-123",device:"device-456"},source:{type:"express",platform:"server"}}),mapping:{name:"Purchase",data:{map:{event_metadata:{map:{value_decimal:"data.total",currency:{key:"data.currency",value:"EUR"},item_count:{fn:e=>e.nested.filter(e=>"product"===e.entity).length},products:{loop:["nested",{condition:e=>h(e)&&"product"===e.entity,map:{id:"data.id",name:"data.name",category:{key:"data.category",value:"uncategorized"}}}]}}}}}},out:[["sendServer",S,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.900Z",event_at_ms:1700000900,event_type:{tracking_type:"Purchase"},user:{},event_metadata:{conversion_id:"ev-1700000900",value_decimal:249.99,currency:"EUR",item_count:1,products:[{id:"SKU-A1",name:"Everyday Ruck Snack",category:"bags"}]}}]}}),b]]},A={title:"Add to cart",description:"A product add is sent to Reddit as an AddToCart conversion with value and product details.",in:f("product add",{id:"ev-1700000901",timestamp:1700000901,data:{id:"SKU-B2",name:"Cool Cap",category:"hats",price:"42.00",quantity:1},user:{id:"user-456"},source:{type:"express",platform:"server"}}),mapping:{name:"AddToCart",data:{map:{event_metadata:{map:{value_decimal:"data.price",currency:{value:"EUR"},item_count:{value:1},products:{set:[{map:{id:"data.id",name:"data.name",category:{key:"data.category",value:"uncategorized"}}}]}}}}}},out:[["sendServer",S,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.901Z",event_at_ms:1700000901,event_type:{tracking_type:"AddToCart"},user:{},event_metadata:{conversion_id:"ev-1700000901",value_decimal:"42.00",currency:"EUR",item_count:1,products:[{id:"SKU-B2",name:"Cool Cap",category:"hats"}]}}]}}),b]]},P={title:"Page visit",description:"A page view is sent to Reddit as a PageVisit conversion used for retargeting audiences.",in:f("page view",{id:"ev-1700000902",timestamp:1700000902,user:{id:"user-789"},source:{type:"express",platform:"server"}}),mapping:{name:"PageVisit"},out:[["sendServer",S,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.902Z",event_at_ms:1700000902,event_type:{tracking_type:"PageVisit"},user:{},event_metadata:{conversion_id:"ev-1700000902"}}]}}),b]]},T={title:"Lead",description:"A form submission is sent to Reddit as a Lead conversion with the SHA-256 hashed email and external id.",in:f("form submit",{id:"ev-1700000903",timestamp:1700000903,data:{form:"contact"},user:{id:"user-lead-1",email:"lead@example.com"},source:{type:"express",platform:"server"}}),mapping:{name:"Lead",data:{map:{user:{map:{email:"user.email",external_id:"user.id"}}}}},out:[["sendServer",S,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.903Z",event_at_ms:1700000903,event_type:{tracking_type:"Lead"},user:{email:"9fbdefe2837a03c9225be80e741f316f4d174d1732b719b6abb6477efc1ae9d2",external_id:"ee818eebb052cf288ffeeb2e09ee35c9946e1a7f53a959cb3ef06d5d4adb78e8"},event_metadata:{conversion_id:"ev-1700000903"}}]}}),b]]},R={title:"Sign up",description:"A user signup is sent to Reddit as a SignUp conversion with hashed user identifiers.",in:f("user signup",{id:"ev-1700000904",timestamp:1700000904,data:{method:"email"},user:{id:"new-user-1",email:"new@example.com"},source:{type:"express",platform:"server"}}),mapping:{name:"SignUp",data:{map:{user:{map:{email:"user.email",external_id:"user.id"}}}}},out:[["sendServer",S,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.904Z",event_at_ms:1700000904,event_type:{tracking_type:"SignUp"},user:{email:"f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716",external_id:"b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde"},event_metadata:{conversion_id:"ev-1700000904"}}]}}),b]]},x={title:"Search",description:"A site search is sent to Reddit as a Search conversion with an item count in event_metadata.",in:f("site search",{id:"ev-1700000905",timestamp:1700000905,data:{query:"walkerOS destinations"},user:{id:"user-101"},source:{type:"express",platform:"server"}}),mapping:{name:"Search",data:{map:{event_metadata:{map:{item_count:{value:1}}}}}},out:[["sendServer",S,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.905Z",event_at_ms:1700000905,event_type:{tracking_type:"Search"},user:{},event_metadata:{conversion_id:"ev-1700000905",item_count:1}}]}}),b]]};export{v as examples,a as schemas};//# sourceMappingURL=dev.mjs.map
|
package/dist/dev.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/primitives.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport * from './primitives';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\nimport { ActionSourceSchema } from './primitives';\n\nexport const SettingsSchema = z.object({\n accessToken: z\n .string()\n .min(1)\n .describe(\n 'Reddit Conversion Access Token for Bearer authentication (like rdt_ABC123...)',\n ),\n pixelId: z\n .string()\n .min(1)\n .describe(\n 'Reddit Pixel ID used as the API path parameter (like a2_abcdef123456)',\n ),\n action_source: ActionSourceSchema.describe(\n 'Source of the event (WEBSITE, APP, PHYSICAL_STORE) (like WEBSITE)',\n ).optional(),\n doNotHash: z\n .array(z.string())\n .describe(\"Array of user fields that should not be hashed (like ['email'])\")\n .optional(),\n test_mode: z\n .boolean()\n .describe(\n 'Enable test mode by sending test_mode: true in the request body (like true)',\n )\n .optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom URL for Reddit Conversions API endpoint (like https://ads-api.reddit.com/api/v2.0/conversions/events/)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping configuration for user fields (like { email: 'user.email', external_id: 'user.id' })\",\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Action Source Enum\n * Where the conversion event took place\n * https://ads-api.reddit.com/docs/v2/#tag/Conversions-API\n */\nexport const ActionSourceSchema = z.enum(['WEBSITE', 'APP', 'PHYSICAL_STORE']);\n\n/**\n * Tracking Type\n * Standard Reddit Conversions API event types.\n * Custom events use `Custom` with a `custom_event_name`.\n */\nexport const TrackingTypeSchema = z.enum([\n 'PageVisit',\n 'ViewContent',\n 'Search',\n 'AddToCart',\n 'AddToWishlist',\n 'Purchase',\n 'Lead',\n 'SignUp',\n 'Custom',\n]);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Reddit Conversions API Mapping Schema\n * Reddit CAPI has no event-level mapping configuration\n */\nexport const MappingSchema = z.object({});\n\n/**\n * Type inference from MappingSchema\n */\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { SendDataValue, SendResponse } from '@walkeros/core';\nimport type { SendServerOptions } from '@walkeros/server-core';\nimport type { Env } from '../types';\n\n/**\n * Example environment configurations for Reddit Conversions API destination\n *\n * These environments provide standardized mock structures for testing\n * and development without requiring actual HTTP requests.\n */\n\ntype MockSendServer = (\n url: string,\n data?: SendDataValue,\n options?: SendServerOptions,\n) => Promise<SendResponse>;\n\n/**\n * Mock sendServer function that simulates successful HTTP responses\n */\nconst mockSendServer: MockSendServer = async () => {\n // Simulate successful Reddit API response\n return {\n ok: true,\n data: {\n success: true,\n },\n };\n};\n\n/**\n * Standard mock environment for push operations\n *\n * Use this for testing Reddit Conversions API events without making\n * actual HTTP requests to Reddit's servers.\n */\nexport const push: Env = {\n sendServer: mockSendServer,\n};\n\nexport const simulation = ['sendServer'];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { getEvent, isObject } from '@walkeros/core';\n\n/**\n * Reddit Conversions API step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), options)` where\n * `endpoint = ${settings.url}${settings.pixelId}` and\n * `body = { data: { events: [hashedServerEvent] } }`.\n *\n * Test fixture pins `pixelId = 'a2_abcdef123456'` and the default url, so\n * every endpoint resolves to:\n * https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456\n *\n * The serverEvent keys are assembled in this order (insertion order matters\n * for `JSON.stringify` string equality):\n * 1. event_at (ISO timestamp)\n * 2. event_at_ms\n * 3. event_type ({ tracking_type, custom_event_name? })\n * 4. ...restEventData (mapped event data minus user/event_metadata/click_id)\n * 5. user (hashed — email, external_id, ip_address, user_agent, idfa, aaid)\n * 6. event_metadata (conversion_id first, then merged metadata)\n * 7. click_id (only when a string is present)\n *\n * `options` carries the Authorization: Bearer <accessToken> header.\n */\nconst ENDPOINT =\n 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456';\nconst OPTIONS = {\n headers: { Authorization: 'Bearer s3cr3t' },\n};\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase',\n description:\n 'A completed order is sent to the Reddit Conversions API as a Purchase event with value, currency, and items.',\n in: getEvent('order complete', {\n timestamp: 1700000900,\n data: { id: 'ORD-300', total: 249.99, currency: 'EUR' },\n nested: [\n {\n entity: 'product',\n data: {\n id: 'SKU-A1',\n name: 'Everyday Ruck Snack',\n category: 'bags',\n price: '129.99',\n quantity: 2,\n },\n },\n ],\n user: { id: 'user-123', device: 'device-456' },\n source: { type: 'server', id: 'https://shop.example.com', previous_id: '' },\n }),\n mapping: {\n name: 'Purchase',\n data: {\n map: {\n event_metadata: {\n map: {\n value_decimal: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n item_count: {\n fn: (event: unknown) =>\n (event as WalkerOS.Event).nested.filter(\n (item) => item.entity === 'product',\n ).length,\n },\n products: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n name: 'data.name',\n category: { key: 'data.category', value: 'uncategorized' },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.900Z',\n event_at_ms: 1700000900,\n event_type: { tracking_type: 'Purchase' },\n user: {},\n event_metadata: {\n conversion_id: '1700000900-gr0up-1',\n value_decimal: 249.99,\n currency: 'EUR',\n item_count: 1,\n products: [\n {\n id: 'SKU-A1',\n name: 'Everyday Ruck Snack',\n category: 'bags',\n },\n ],\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A product add is sent to Reddit as an AddToCart conversion with value and product details.',\n in: getEvent('product add', {\n timestamp: 1700000901,\n data: {\n id: 'SKU-B2',\n name: 'Cool Cap',\n category: 'hats',\n price: '42.00',\n quantity: 1,\n },\n user: { id: 'user-456' },\n source: {\n type: 'server',\n id: 'https://shop.example.com/products',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'AddToCart',\n data: {\n map: {\n event_metadata: {\n map: {\n value_decimal: 'data.price',\n currency: { value: 'EUR' },\n item_count: { value: 1 },\n products: {\n set: [\n {\n map: {\n id: 'data.id',\n name: 'data.name',\n category: { key: 'data.category', value: 'uncategorized' },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.901Z',\n event_at_ms: 1700000901,\n event_type: { tracking_type: 'AddToCart' },\n user: {},\n event_metadata: {\n conversion_id: '1700000901-gr0up-1',\n value_decimal: '42.00',\n currency: 'EUR',\n item_count: 1,\n products: [\n { id: 'SKU-B2', name: 'Cool Cap', category: 'hats' },\n ],\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const pageVisit: Flow.StepExample = {\n title: 'Page visit',\n description:\n 'A page view is sent to Reddit as a PageVisit conversion used for retargeting audiences.',\n in: getEvent('page view', {\n timestamp: 1700000902,\n user: { id: 'user-789' },\n source: {\n type: 'server',\n id: 'https://www.example.com/docs/',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'PageVisit',\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.902Z',\n event_at_ms: 1700000902,\n event_type: { tracking_type: 'PageVisit' },\n user: {},\n event_metadata: { conversion_id: '1700000902-gr0up-1' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const lead: Flow.StepExample = {\n title: 'Lead',\n description:\n 'A form submission is sent to Reddit as a Lead conversion with the SHA-256 hashed email and external id.',\n in: getEvent('form submit', {\n timestamp: 1700000903,\n data: { form: 'contact' },\n user: { id: 'user-lead-1', email: 'lead@example.com' },\n source: {\n type: 'server',\n id: 'https://www.example.com/contact',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'Lead',\n data: {\n map: {\n user: {\n map: {\n email: 'user.email',\n external_id: 'user.id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.903Z',\n event_at_ms: 1700000903,\n event_type: { tracking_type: 'Lead' },\n user: {\n // sha256('lead@example.com')\n email:\n '9fbdefe2837a03c9225be80e741f316f4d174d1732b719b6abb6477efc1ae9d2',\n // sha256('user-lead-1')\n external_id:\n 'ee818eebb052cf288ffeeb2e09ee35c9946e1a7f53a959cb3ef06d5d4adb78e8',\n },\n event_metadata: { conversion_id: '1700000903-gr0up-1' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const signUp: Flow.StepExample = {\n title: 'Sign up',\n description:\n 'A user signup is sent to Reddit as a SignUp conversion with hashed user identifiers.',\n in: getEvent('user signup', {\n timestamp: 1700000904,\n data: { method: 'email' },\n user: { id: 'new-user-1', email: 'new@example.com' },\n source: {\n type: 'server',\n id: 'https://www.example.com/register',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'SignUp',\n data: {\n map: {\n user: {\n map: {\n email: 'user.email',\n external_id: 'user.id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.904Z',\n event_at_ms: 1700000904,\n event_type: { tracking_type: 'SignUp' },\n user: {\n // sha256('new@example.com')\n email:\n 'f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716',\n // sha256('new-user-1')\n external_id:\n 'b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde',\n },\n event_metadata: { conversion_id: '1700000904-gr0up-1' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const search: Flow.StepExample = {\n title: 'Search',\n description:\n 'A site search is sent to Reddit as a Search conversion with an item count in event_metadata.',\n in: getEvent('site search', {\n timestamp: 1700000905,\n data: { query: 'walkerOS destinations' },\n user: { id: 'user-101' },\n source: {\n type: 'server',\n id: 'https://www.example.com/search',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'Search',\n data: {\n map: {\n event_metadata: {\n map: {\n item_count: { value: 1 },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.905Z',\n event_at_ms: 1700000905,\n event_type: { tracking_type: 'Search' },\n user: {},\n event_metadata: {\n conversion_id: '1700000905-gr0up-1',\n item_count: 1,\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n"],"mappings":";;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,mBAAmB;;;ACA5B,SAAS,KAAAA,UAAS;;;ACAlB,SAAS,SAAS;AAOX,IAAM,qBAAqB,EAAE,KAAK,CAAC,WAAW,OAAO,gBAAgB,CAAC;AAOtE,IAAM,qBAAqB,EAAE,KAAK;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;;;ADrBM,IAAM,iBAAiBC,GAAE,OAAO;AAAA,EACrC,aAAaA,GACV,OAAO,EACP,IAAI,CAAC,EACL;AAAA,IACC;AAAA,EACF;AAAA,EACF,SAASA,GACN,OAAO,EACP,IAAI,CAAC,EACL;AAAA,IACC;AAAA,EACF;AAAA,EACF,eAAe,mBAAmB;AAAA,IAChC;AAAA,EACF,EAAE,SAAS;AAAA,EACX,WAAWA,GACR,MAAMA,GAAE,OAAO,CAAC,EAChB,SAAS,iEAAiE,EAC1E,SAAS;AAAA,EACZ,WAAWA,GACR,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,KAAKA,GACF,OAAO,EACP,IAAI,EACJ;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,WAAWA,GACR,OAAOA,GAAE,OAAO,GAAGA,GAAE,OAAO,CAAC,EAC7B;AAAA,IACC;AAAA,EACF,EACC,SAAS;AACd,CAAC;;;AE1CD,SAAS,KAAAC,UAAS;AAMX,IAAM,gBAAgBA,GAAE,OAAO,CAAC,CAAC;;;AHIjC,IAAM,WAAW,YAAY,cAAc;AAC3C,IAAM,UAAU,YAAY,aAAa;;;AIXhD;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAoBA,IAAM,iBAAiC,YAAY;AAEjD,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,MACJ,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAQO,IAAM,OAAY;AAAA,EACvB,YAAY;AACd;AAEO,IAAM,aAAa,CAAC,YAAY;;;ACxCvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,SAAS,UAAU,gBAAgB;AA0BnC,IAAM,WACJ;AACF,IAAM,UAAU;AAAA,EACd,SAAS,EAAE,eAAe,gBAAgB;AAC5C;AAEO,IAAM,WAA6B;AAAA,EACxC,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,kBAAkB;AAAA,IAC7B,WAAW;AAAA,IACX,MAAM,EAAE,IAAI,WAAW,OAAO,QAAQ,UAAU,MAAM;AAAA,IACtD,QAAQ;AAAA,MACN;AAAA,QACE,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,UAAU;AAAA,UACV,OAAO;AAAA,UACP,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA,MAAM,EAAE,IAAI,YAAY,QAAQ,aAAa;AAAA,IAC7C,QAAQ,EAAE,MAAM,UAAU,IAAI,4BAA4B,aAAa,GAAG;AAAA,EAC5E,CAAC;AAAA,EACD,SAAS;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,KAAK;AAAA,QACH,gBAAgB;AAAA,UACd,KAAK;AAAA,YACH,eAAe;AAAA,YACf,UAAU,EAAE,KAAK,iBAAiB,OAAO,MAAM;AAAA,YAC/C,YAAY;AAAA,cACV,IAAI,CAAC,UACF,MAAyB,OAAO;AAAA,gBAC/B,CAAC,SAAS,KAAK,WAAW;AAAA,cAC5B,EAAE;AAAA,YACN;AAAA,YACA,UAAU;AAAA,cACR,MAAM;AAAA,gBACJ;AAAA,gBACA;AAAA,kBACE,WAAW,CAAC,WACV,SAAS,MAAM,KAAK,OAAO,WAAW;AAAA,kBACxC,KAAK;AAAA,oBACH,IAAI;AAAA,oBACJ,MAAM;AAAA,oBACN,UAAU,EAAE,KAAK,iBAAiB,OAAO,gBAAgB;AAAA,kBAC3D;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA,KAAK,UAAU;AAAA,QACb,MAAM;AAAA,UACJ,QAAQ;AAAA,YACN;AAAA,cACE,UAAU;AAAA,cACV,aAAa;AAAA,cACb,YAAY,EAAE,eAAe,WAAW;AAAA,cACxC,MAAM,CAAC;AAAA,cACP,gBAAgB;AAAA,gBACd,eAAe;AAAA,gBACf,eAAe;AAAA,gBACf,UAAU;AAAA,gBACV,YAAY;AAAA,gBACZ,UAAU;AAAA,kBACR;AAAA,oBACE,IAAI;AAAA,oBACJ,MAAM;AAAA,oBACN,UAAU;AAAA,kBACZ;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,YAA8B;AAAA,EACzC,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,eAAe;AAAA,IAC1B,WAAW;AAAA,IACX,MAAM;AAAA,MACJ,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,UAAU;AAAA,MACV,OAAO;AAAA,MACP,UAAU;AAAA,IACZ;AAAA,IACA,MAAM,EAAE,IAAI,WAAW;AAAA,IACvB,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,aAAa;AAAA,IACf;AAAA,EACF,CAAC;AAAA,EACD,SAAS;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,KAAK;AAAA,QACH,gBAAgB;AAAA,UACd,KAAK;AAAA,YACH,eAAe;AAAA,YACf,UAAU,EAAE,OAAO,MAAM;AAAA,YACzB,YAAY,EAAE,OAAO,EAAE;AAAA,YACvB,UAAU;AAAA,cACR,KAAK;AAAA,gBACH;AAAA,kBACE,KAAK;AAAA,oBACH,IAAI;AAAA,oBACJ,MAAM;AAAA,oBACN,UAAU,EAAE,KAAK,iBAAiB,OAAO,gBAAgB;AAAA,kBAC3D;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA,KAAK,UAAU;AAAA,QACb,MAAM;AAAA,UACJ,QAAQ;AAAA,YACN;AAAA,cACE,UAAU;AAAA,cACV,aAAa;AAAA,cACb,YAAY,EAAE,eAAe,YAAY;AAAA,cACzC,MAAM,CAAC;AAAA,cACP,gBAAgB;AAAA,gBACd,eAAe;AAAA,gBACf,eAAe;AAAA,gBACf,UAAU;AAAA,gBACV,YAAY;AAAA,gBACZ,UAAU;AAAA,kBACR,EAAE,IAAI,UAAU,MAAM,YAAY,UAAU,OAAO;AAAA,gBACrD;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,YAA8B;AAAA,EACzC,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,aAAa;AAAA,IACxB,WAAW;AAAA,IACX,MAAM,EAAE,IAAI,WAAW;AAAA,IACvB,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,aAAa;AAAA,IACf;AAAA,EACF,CAAC;AAAA,EACD,SAAS;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA,KAAK,UAAU;AAAA,QACb,MAAM;AAAA,UACJ,QAAQ;AAAA,YACN;AAAA,cACE,UAAU;AAAA,cACV,aAAa;AAAA,cACb,YAAY,EAAE,eAAe,YAAY;AAAA,cACzC,MAAM,CAAC;AAAA,cACP,gBAAgB,EAAE,eAAe,qBAAqB;AAAA,YACxD;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,OAAyB;AAAA,EACpC,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,eAAe;AAAA,IAC1B,WAAW;AAAA,IACX,MAAM,EAAE,MAAM,UAAU;AAAA,IACxB,MAAM,EAAE,IAAI,eAAe,OAAO,mBAAmB;AAAA,IACrD,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,aAAa;AAAA,IACf;AAAA,EACF,CAAC;AAAA,EACD,SAAS;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,KAAK;AAAA,QACH,MAAM;AAAA,UACJ,KAAK;AAAA,YACH,OAAO;AAAA,YACP,aAAa;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA,KAAK,UAAU;AAAA,QACb,MAAM;AAAA,UACJ,QAAQ;AAAA,YACN;AAAA,cACE,UAAU;AAAA,cACV,aAAa;AAAA,cACb,YAAY,EAAE,eAAe,OAAO;AAAA,cACpC,MAAM;AAAA;AAAA,gBAEJ,OACE;AAAA;AAAA,gBAEF,aACE;AAAA,cACJ;AAAA,cACA,gBAAgB,EAAE,eAAe,qBAAqB;AAAA,YACxD;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,SAA2B;AAAA,EACtC,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,eAAe;AAAA,IAC1B,WAAW;AAAA,IACX,MAAM,EAAE,QAAQ,QAAQ;AAAA,IACxB,MAAM,EAAE,IAAI,cAAc,OAAO,kBAAkB;AAAA,IACnD,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,aAAa;AAAA,IACf;AAAA,EACF,CAAC;AAAA,EACD,SAAS;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,KAAK;AAAA,QACH,MAAM;AAAA,UACJ,KAAK;AAAA,YACH,OAAO;AAAA,YACP,aAAa;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA,KAAK,UAAU;AAAA,QACb,MAAM;AAAA,UACJ,QAAQ;AAAA,YACN;AAAA,cACE,UAAU;AAAA,cACV,aAAa;AAAA,cACb,YAAY,EAAE,eAAe,SAAS;AAAA,cACtC,MAAM;AAAA;AAAA,gBAEJ,OACE;AAAA;AAAA,gBAEF,aACE;AAAA,cACJ;AAAA,cACA,gBAAgB,EAAE,eAAe,qBAAqB;AAAA,YACxD;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,SAA2B;AAAA,EACtC,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,eAAe;AAAA,IAC1B,WAAW;AAAA,IACX,MAAM,EAAE,OAAO,wBAAwB;AAAA,IACvC,MAAM,EAAE,IAAI,WAAW;AAAA,IACvB,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,aAAa;AAAA,IACf;AAAA,EACF,CAAC;AAAA,EACD,SAAS;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,KAAK;AAAA,QACH,gBAAgB;AAAA,UACd,KAAK;AAAA,YACH,YAAY,EAAE,OAAO,EAAE;AAAA,UACzB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA,KAAK,UAAU;AAAA,QACb,MAAM;AAAA,UACJ,QAAQ;AAAA,YACN;AAAA,cACE,UAAU;AAAA,cACV,aAAa;AAAA,cACb,YAAY,EAAE,eAAe,SAAS;AAAA,cACtC,MAAM,CAAC;AAAA,cACP,gBAAgB;AAAA,gBACd,eAAe;AAAA,gBACf,YAAY;AAAA,cACd;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AACF;","names":["z","z","z"]}
|
|
1
|
+
{"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/primitives.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport * from './primitives';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\nimport { ActionSourceSchema } from './primitives';\n\nexport const SettingsSchema = z.object({\n accessToken: z\n .string()\n .min(1)\n .describe(\n 'Reddit Conversion Access Token for Bearer authentication (like rdt_ABC123...)',\n ),\n pixelId: z\n .string()\n .min(1)\n .describe(\n 'Reddit Pixel ID used as the API path parameter (like a2_abcdef123456)',\n ),\n action_source: ActionSourceSchema.describe(\n 'Source of the event (WEBSITE, APP, PHYSICAL_STORE) (like WEBSITE)',\n ).optional(),\n doNotHash: z\n .array(z.string())\n .describe(\"Array of user fields that should not be hashed (like ['email'])\")\n .optional(),\n test_mode: z\n .boolean()\n .describe(\n 'Enable test mode by sending test_mode: true in the request body (like true)',\n )\n .optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom URL for Reddit Conversions API endpoint (like https://ads-api.reddit.com/api/v2.0/conversions/events/)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping configuration for user fields (like { email: 'user.email', external_id: 'user.id' })\",\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Action Source Enum\n * Where the conversion event took place\n * https://ads-api.reddit.com/docs/v2/#tag/Conversions-API\n */\nexport const ActionSourceSchema = z.enum(['WEBSITE', 'APP', 'PHYSICAL_STORE']);\n\n/**\n * Tracking Type\n * Standard Reddit Conversions API event types.\n * Custom events use `Custom` with a `custom_event_name`.\n */\nexport const TrackingTypeSchema = z.enum([\n 'PageVisit',\n 'ViewContent',\n 'Search',\n 'AddToCart',\n 'AddToWishlist',\n 'Purchase',\n 'Lead',\n 'SignUp',\n 'Custom',\n]);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Reddit Conversions API Mapping Schema\n * Reddit CAPI has no event-level mapping configuration\n */\nexport const MappingSchema = z.object({});\n\n/**\n * Type inference from MappingSchema\n */\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { SendDataValue, SendResponse } from '@walkeros/core';\nimport type { SendServerOptions } from '@walkeros/server-core';\nimport type { Env } from '../types';\n\n/**\n * Example environment configurations for Reddit Conversions API destination\n *\n * These environments provide standardized mock structures for testing\n * and development without requiring actual HTTP requests.\n */\n\ntype MockSendServer = (\n url: string,\n data?: SendDataValue,\n options?: SendServerOptions,\n) => Promise<SendResponse>;\n\n/**\n * Mock sendServer function that simulates successful HTTP responses\n */\nconst mockSendServer: MockSendServer = async () => {\n // Simulate successful Reddit API response\n return {\n ok: true,\n data: {\n success: true,\n },\n };\n};\n\n/**\n * Standard mock environment for push operations\n *\n * Use this for testing Reddit Conversions API events without making\n * actual HTTP requests to Reddit's servers.\n */\nexport const push: Env = {\n sendServer: mockSendServer,\n};\n\nexport const simulation = ['sendServer'];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { getEvent, isObject } from '@walkeros/core';\n\n/**\n * Reddit Conversions API step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), options)` where\n * `endpoint = ${settings.url}${settings.pixelId}` and\n * `body = { data: { events: [hashedServerEvent] } }`.\n *\n * Test fixture pins `pixelId = 'a2_abcdef123456'` and the default url, so\n * every endpoint resolves to:\n * https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456\n *\n * The serverEvent keys are assembled in this order (insertion order matters\n * for `JSON.stringify` string equality):\n * 1. event_at (ISO timestamp)\n * 2. event_at_ms\n * 3. event_type ({ tracking_type, custom_event_name? })\n * 4. ...restEventData (mapped event data minus user/event_metadata/click_id)\n * 5. user (hashed - email, external_id, ip_address, user_agent, idfa, aaid)\n * 6. event_metadata (conversion_id first, then merged metadata)\n * 7. click_id (only when a string is present)\n *\n * `options` carries the Authorization: Bearer <accessToken> header.\n */\nconst ENDPOINT =\n 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456';\nconst OPTIONS = {\n headers: { Authorization: 'Bearer s3cr3t' },\n};\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase',\n description:\n 'A completed order is sent to the Reddit Conversions API as a Purchase event with value, currency, and items.',\n in: getEvent('order complete', {\n id: 'ev-1700000900',\n timestamp: 1700000900,\n data: { id: 'ORD-300', total: 249.99, currency: 'EUR' },\n nested: [\n {\n entity: 'product',\n data: {\n id: 'SKU-A1',\n name: 'Everyday Ruck Snack',\n category: 'bags',\n price: '129.99',\n quantity: 2,\n },\n },\n ],\n user: { id: 'user-123', device: 'device-456' },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: {\n name: 'Purchase',\n data: {\n map: {\n event_metadata: {\n map: {\n value_decimal: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n item_count: {\n fn: (event: unknown) =>\n (event as WalkerOS.Event).nested.filter(\n (item) => item.entity === 'product',\n ).length,\n },\n products: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n name: 'data.name',\n category: { key: 'data.category', value: 'uncategorized' },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.900Z',\n event_at_ms: 1700000900,\n event_type: { tracking_type: 'Purchase' },\n user: {},\n event_metadata: {\n conversion_id: 'ev-1700000900',\n value_decimal: 249.99,\n currency: 'EUR',\n item_count: 1,\n products: [\n {\n id: 'SKU-A1',\n name: 'Everyday Ruck Snack',\n category: 'bags',\n },\n ],\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A product add is sent to Reddit as an AddToCart conversion with value and product details.',\n in: getEvent('product add', {\n id: 'ev-1700000901',\n timestamp: 1700000901,\n data: {\n id: 'SKU-B2',\n name: 'Cool Cap',\n category: 'hats',\n price: '42.00',\n quantity: 1,\n },\n user: { id: 'user-456' },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: {\n name: 'AddToCart',\n data: {\n map: {\n event_metadata: {\n map: {\n value_decimal: 'data.price',\n currency: { value: 'EUR' },\n item_count: { value: 1 },\n products: {\n set: [\n {\n map: {\n id: 'data.id',\n name: 'data.name',\n category: { key: 'data.category', value: 'uncategorized' },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.901Z',\n event_at_ms: 1700000901,\n event_type: { tracking_type: 'AddToCart' },\n user: {},\n event_metadata: {\n conversion_id: 'ev-1700000901',\n value_decimal: '42.00',\n currency: 'EUR',\n item_count: 1,\n products: [\n { id: 'SKU-B2', name: 'Cool Cap', category: 'hats' },\n ],\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const pageVisit: Flow.StepExample = {\n title: 'Page visit',\n description:\n 'A page view is sent to Reddit as a PageVisit conversion used for retargeting audiences.',\n in: getEvent('page view', {\n id: 'ev-1700000902',\n timestamp: 1700000902,\n user: { id: 'user-789' },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: {\n name: 'PageVisit',\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.902Z',\n event_at_ms: 1700000902,\n event_type: { tracking_type: 'PageVisit' },\n user: {},\n event_metadata: { conversion_id: 'ev-1700000902' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const lead: Flow.StepExample = {\n title: 'Lead',\n description:\n 'A form submission is sent to Reddit as a Lead conversion with the SHA-256 hashed email and external id.',\n in: getEvent('form submit', {\n id: 'ev-1700000903',\n timestamp: 1700000903,\n data: { form: 'contact' },\n user: { id: 'user-lead-1', email: 'lead@example.com' },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: {\n name: 'Lead',\n data: {\n map: {\n user: {\n map: {\n email: 'user.email',\n external_id: 'user.id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.903Z',\n event_at_ms: 1700000903,\n event_type: { tracking_type: 'Lead' },\n user: {\n // sha256('lead@example.com')\n email:\n '9fbdefe2837a03c9225be80e741f316f4d174d1732b719b6abb6477efc1ae9d2',\n // sha256('user-lead-1')\n external_id:\n 'ee818eebb052cf288ffeeb2e09ee35c9946e1a7f53a959cb3ef06d5d4adb78e8',\n },\n event_metadata: { conversion_id: 'ev-1700000903' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const signUp: Flow.StepExample = {\n title: 'Sign up',\n description:\n 'A user signup is sent to Reddit as a SignUp conversion with hashed user identifiers.',\n in: getEvent('user signup', {\n id: 'ev-1700000904',\n timestamp: 1700000904,\n data: { method: 'email' },\n user: { id: 'new-user-1', email: 'new@example.com' },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: {\n name: 'SignUp',\n data: {\n map: {\n user: {\n map: {\n email: 'user.email',\n external_id: 'user.id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.904Z',\n event_at_ms: 1700000904,\n event_type: { tracking_type: 'SignUp' },\n user: {\n // sha256('new@example.com')\n email:\n 'f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716',\n // sha256('new-user-1')\n external_id:\n 'b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde',\n },\n event_metadata: { conversion_id: 'ev-1700000904' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const search: Flow.StepExample = {\n title: 'Search',\n description:\n 'A site search is sent to Reddit as a Search conversion with an item count in event_metadata.',\n in: getEvent('site search', {\n id: 'ev-1700000905',\n timestamp: 1700000905,\n data: { query: 'walkerOS destinations' },\n user: { id: 'user-101' },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: {\n name: 'Search',\n data: {\n map: {\n event_metadata: {\n map: {\n item_count: { value: 1 },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.905Z',\n event_at_ms: 1700000905,\n event_type: { tracking_type: 'Search' },\n user: {},\n event_metadata: {\n conversion_id: 'ev-1700000905',\n item_count: 1,\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n"],"mappings":"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","names":["z","z","z"]}
|
package/dist/examples/index.js
CHANGED
|
@@ -63,6 +63,7 @@ var purchase = {
|
|
|
63
63
|
title: "Purchase",
|
|
64
64
|
description: "A completed order is sent to the Reddit Conversions API as a Purchase event with value, currency, and items.",
|
|
65
65
|
in: (0, import_core.getEvent)("order complete", {
|
|
66
|
+
id: "ev-1700000900",
|
|
66
67
|
timestamp: 1700000900,
|
|
67
68
|
data: { id: "ORD-300", total: 249.99, currency: "EUR" },
|
|
68
69
|
nested: [
|
|
@@ -78,7 +79,7 @@ var purchase = {
|
|
|
78
79
|
}
|
|
79
80
|
],
|
|
80
81
|
user: { id: "user-123", device: "device-456" },
|
|
81
|
-
source: { type: "
|
|
82
|
+
source: { type: "express", platform: "server" }
|
|
82
83
|
}),
|
|
83
84
|
mapping: {
|
|
84
85
|
name: "Purchase",
|
|
@@ -124,7 +125,7 @@ var purchase = {
|
|
|
124
125
|
event_type: { tracking_type: "Purchase" },
|
|
125
126
|
user: {},
|
|
126
127
|
event_metadata: {
|
|
127
|
-
conversion_id: "1700000900
|
|
128
|
+
conversion_id: "ev-1700000900",
|
|
128
129
|
value_decimal: 249.99,
|
|
129
130
|
currency: "EUR",
|
|
130
131
|
item_count: 1,
|
|
@@ -148,6 +149,7 @@ var addToCart = {
|
|
|
148
149
|
title: "Add to cart",
|
|
149
150
|
description: "A product add is sent to Reddit as an AddToCart conversion with value and product details.",
|
|
150
151
|
in: (0, import_core.getEvent)("product add", {
|
|
152
|
+
id: "ev-1700000901",
|
|
151
153
|
timestamp: 1700000901,
|
|
152
154
|
data: {
|
|
153
155
|
id: "SKU-B2",
|
|
@@ -157,11 +159,7 @@ var addToCart = {
|
|
|
157
159
|
quantity: 1
|
|
158
160
|
},
|
|
159
161
|
user: { id: "user-456" },
|
|
160
|
-
source: {
|
|
161
|
-
type: "server",
|
|
162
|
-
id: "https://shop.example.com/products",
|
|
163
|
-
previous_id: ""
|
|
164
|
-
}
|
|
162
|
+
source: { type: "express", platform: "server" }
|
|
165
163
|
}),
|
|
166
164
|
mapping: {
|
|
167
165
|
name: "AddToCart",
|
|
@@ -201,7 +199,7 @@ var addToCart = {
|
|
|
201
199
|
event_type: { tracking_type: "AddToCart" },
|
|
202
200
|
user: {},
|
|
203
201
|
event_metadata: {
|
|
204
|
-
conversion_id: "1700000901
|
|
202
|
+
conversion_id: "ev-1700000901",
|
|
205
203
|
value_decimal: "42.00",
|
|
206
204
|
currency: "EUR",
|
|
207
205
|
item_count: 1,
|
|
@@ -221,13 +219,10 @@ var pageVisit = {
|
|
|
221
219
|
title: "Page visit",
|
|
222
220
|
description: "A page view is sent to Reddit as a PageVisit conversion used for retargeting audiences.",
|
|
223
221
|
in: (0, import_core.getEvent)("page view", {
|
|
222
|
+
id: "ev-1700000902",
|
|
224
223
|
timestamp: 1700000902,
|
|
225
224
|
user: { id: "user-789" },
|
|
226
|
-
source: {
|
|
227
|
-
type: "server",
|
|
228
|
-
id: "https://www.example.com/docs/",
|
|
229
|
-
previous_id: ""
|
|
230
|
-
}
|
|
225
|
+
source: { type: "express", platform: "server" }
|
|
231
226
|
}),
|
|
232
227
|
mapping: {
|
|
233
228
|
name: "PageVisit"
|
|
@@ -244,7 +239,7 @@ var pageVisit = {
|
|
|
244
239
|
event_at_ms: 1700000902,
|
|
245
240
|
event_type: { tracking_type: "PageVisit" },
|
|
246
241
|
user: {},
|
|
247
|
-
event_metadata: { conversion_id: "1700000902
|
|
242
|
+
event_metadata: { conversion_id: "ev-1700000902" }
|
|
248
243
|
}
|
|
249
244
|
]
|
|
250
245
|
}
|
|
@@ -257,14 +252,11 @@ var lead = {
|
|
|
257
252
|
title: "Lead",
|
|
258
253
|
description: "A form submission is sent to Reddit as a Lead conversion with the SHA-256 hashed email and external id.",
|
|
259
254
|
in: (0, import_core.getEvent)("form submit", {
|
|
255
|
+
id: "ev-1700000903",
|
|
260
256
|
timestamp: 1700000903,
|
|
261
257
|
data: { form: "contact" },
|
|
262
258
|
user: { id: "user-lead-1", email: "lead@example.com" },
|
|
263
|
-
source: {
|
|
264
|
-
type: "server",
|
|
265
|
-
id: "https://www.example.com/contact",
|
|
266
|
-
previous_id: ""
|
|
267
|
-
}
|
|
259
|
+
source: { type: "express", platform: "server" }
|
|
268
260
|
}),
|
|
269
261
|
mapping: {
|
|
270
262
|
name: "Lead",
|
|
@@ -296,7 +288,7 @@ var lead = {
|
|
|
296
288
|
// sha256('user-lead-1')
|
|
297
289
|
external_id: "ee818eebb052cf288ffeeb2e09ee35c9946e1a7f53a959cb3ef06d5d4adb78e8"
|
|
298
290
|
},
|
|
299
|
-
event_metadata: { conversion_id: "1700000903
|
|
291
|
+
event_metadata: { conversion_id: "ev-1700000903" }
|
|
300
292
|
}
|
|
301
293
|
]
|
|
302
294
|
}
|
|
@@ -309,14 +301,11 @@ var signUp = {
|
|
|
309
301
|
title: "Sign up",
|
|
310
302
|
description: "A user signup is sent to Reddit as a SignUp conversion with hashed user identifiers.",
|
|
311
303
|
in: (0, import_core.getEvent)("user signup", {
|
|
304
|
+
id: "ev-1700000904",
|
|
312
305
|
timestamp: 1700000904,
|
|
313
306
|
data: { method: "email" },
|
|
314
307
|
user: { id: "new-user-1", email: "new@example.com" },
|
|
315
|
-
source: {
|
|
316
|
-
type: "server",
|
|
317
|
-
id: "https://www.example.com/register",
|
|
318
|
-
previous_id: ""
|
|
319
|
-
}
|
|
308
|
+
source: { type: "express", platform: "server" }
|
|
320
309
|
}),
|
|
321
310
|
mapping: {
|
|
322
311
|
name: "SignUp",
|
|
@@ -348,7 +337,7 @@ var signUp = {
|
|
|
348
337
|
// sha256('new-user-1')
|
|
349
338
|
external_id: "b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde"
|
|
350
339
|
},
|
|
351
|
-
event_metadata: { conversion_id: "1700000904
|
|
340
|
+
event_metadata: { conversion_id: "ev-1700000904" }
|
|
352
341
|
}
|
|
353
342
|
]
|
|
354
343
|
}
|
|
@@ -361,14 +350,11 @@ var search = {
|
|
|
361
350
|
title: "Search",
|
|
362
351
|
description: "A site search is sent to Reddit as a Search conversion with an item count in event_metadata.",
|
|
363
352
|
in: (0, import_core.getEvent)("site search", {
|
|
353
|
+
id: "ev-1700000905",
|
|
364
354
|
timestamp: 1700000905,
|
|
365
355
|
data: { query: "walkerOS destinations" },
|
|
366
356
|
user: { id: "user-101" },
|
|
367
|
-
source: {
|
|
368
|
-
type: "server",
|
|
369
|
-
id: "https://www.example.com/search",
|
|
370
|
-
previous_id: ""
|
|
371
|
-
}
|
|
357
|
+
source: { type: "express", platform: "server" }
|
|
372
358
|
}),
|
|
373
359
|
mapping: {
|
|
374
360
|
name: "Search",
|
|
@@ -395,7 +381,7 @@ var search = {
|
|
|
395
381
|
event_type: { tracking_type: "Search" },
|
|
396
382
|
user: {},
|
|
397
383
|
event_metadata: {
|
|
398
|
-
conversion_id: "1700000905
|
|
384
|
+
conversion_id: "ev-1700000905",
|
|
399
385
|
item_count: 1
|
|
400
386
|
}
|
|
401
387
|
}
|
package/dist/examples/index.mjs
CHANGED
|
@@ -42,6 +42,7 @@ var purchase = {
|
|
|
42
42
|
title: "Purchase",
|
|
43
43
|
description: "A completed order is sent to the Reddit Conversions API as a Purchase event with value, currency, and items.",
|
|
44
44
|
in: getEvent("order complete", {
|
|
45
|
+
id: "ev-1700000900",
|
|
45
46
|
timestamp: 1700000900,
|
|
46
47
|
data: { id: "ORD-300", total: 249.99, currency: "EUR" },
|
|
47
48
|
nested: [
|
|
@@ -57,7 +58,7 @@ var purchase = {
|
|
|
57
58
|
}
|
|
58
59
|
],
|
|
59
60
|
user: { id: "user-123", device: "device-456" },
|
|
60
|
-
source: { type: "
|
|
61
|
+
source: { type: "express", platform: "server" }
|
|
61
62
|
}),
|
|
62
63
|
mapping: {
|
|
63
64
|
name: "Purchase",
|
|
@@ -103,7 +104,7 @@ var purchase = {
|
|
|
103
104
|
event_type: { tracking_type: "Purchase" },
|
|
104
105
|
user: {},
|
|
105
106
|
event_metadata: {
|
|
106
|
-
conversion_id: "1700000900
|
|
107
|
+
conversion_id: "ev-1700000900",
|
|
107
108
|
value_decimal: 249.99,
|
|
108
109
|
currency: "EUR",
|
|
109
110
|
item_count: 1,
|
|
@@ -127,6 +128,7 @@ var addToCart = {
|
|
|
127
128
|
title: "Add to cart",
|
|
128
129
|
description: "A product add is sent to Reddit as an AddToCart conversion with value and product details.",
|
|
129
130
|
in: getEvent("product add", {
|
|
131
|
+
id: "ev-1700000901",
|
|
130
132
|
timestamp: 1700000901,
|
|
131
133
|
data: {
|
|
132
134
|
id: "SKU-B2",
|
|
@@ -136,11 +138,7 @@ var addToCart = {
|
|
|
136
138
|
quantity: 1
|
|
137
139
|
},
|
|
138
140
|
user: { id: "user-456" },
|
|
139
|
-
source: {
|
|
140
|
-
type: "server",
|
|
141
|
-
id: "https://shop.example.com/products",
|
|
142
|
-
previous_id: ""
|
|
143
|
-
}
|
|
141
|
+
source: { type: "express", platform: "server" }
|
|
144
142
|
}),
|
|
145
143
|
mapping: {
|
|
146
144
|
name: "AddToCart",
|
|
@@ -180,7 +178,7 @@ var addToCart = {
|
|
|
180
178
|
event_type: { tracking_type: "AddToCart" },
|
|
181
179
|
user: {},
|
|
182
180
|
event_metadata: {
|
|
183
|
-
conversion_id: "1700000901
|
|
181
|
+
conversion_id: "ev-1700000901",
|
|
184
182
|
value_decimal: "42.00",
|
|
185
183
|
currency: "EUR",
|
|
186
184
|
item_count: 1,
|
|
@@ -200,13 +198,10 @@ var pageVisit = {
|
|
|
200
198
|
title: "Page visit",
|
|
201
199
|
description: "A page view is sent to Reddit as a PageVisit conversion used for retargeting audiences.",
|
|
202
200
|
in: getEvent("page view", {
|
|
201
|
+
id: "ev-1700000902",
|
|
203
202
|
timestamp: 1700000902,
|
|
204
203
|
user: { id: "user-789" },
|
|
205
|
-
source: {
|
|
206
|
-
type: "server",
|
|
207
|
-
id: "https://www.example.com/docs/",
|
|
208
|
-
previous_id: ""
|
|
209
|
-
}
|
|
204
|
+
source: { type: "express", platform: "server" }
|
|
210
205
|
}),
|
|
211
206
|
mapping: {
|
|
212
207
|
name: "PageVisit"
|
|
@@ -223,7 +218,7 @@ var pageVisit = {
|
|
|
223
218
|
event_at_ms: 1700000902,
|
|
224
219
|
event_type: { tracking_type: "PageVisit" },
|
|
225
220
|
user: {},
|
|
226
|
-
event_metadata: { conversion_id: "1700000902
|
|
221
|
+
event_metadata: { conversion_id: "ev-1700000902" }
|
|
227
222
|
}
|
|
228
223
|
]
|
|
229
224
|
}
|
|
@@ -236,14 +231,11 @@ var lead = {
|
|
|
236
231
|
title: "Lead",
|
|
237
232
|
description: "A form submission is sent to Reddit as a Lead conversion with the SHA-256 hashed email and external id.",
|
|
238
233
|
in: getEvent("form submit", {
|
|
234
|
+
id: "ev-1700000903",
|
|
239
235
|
timestamp: 1700000903,
|
|
240
236
|
data: { form: "contact" },
|
|
241
237
|
user: { id: "user-lead-1", email: "lead@example.com" },
|
|
242
|
-
source: {
|
|
243
|
-
type: "server",
|
|
244
|
-
id: "https://www.example.com/contact",
|
|
245
|
-
previous_id: ""
|
|
246
|
-
}
|
|
238
|
+
source: { type: "express", platform: "server" }
|
|
247
239
|
}),
|
|
248
240
|
mapping: {
|
|
249
241
|
name: "Lead",
|
|
@@ -275,7 +267,7 @@ var lead = {
|
|
|
275
267
|
// sha256('user-lead-1')
|
|
276
268
|
external_id: "ee818eebb052cf288ffeeb2e09ee35c9946e1a7f53a959cb3ef06d5d4adb78e8"
|
|
277
269
|
},
|
|
278
|
-
event_metadata: { conversion_id: "1700000903
|
|
270
|
+
event_metadata: { conversion_id: "ev-1700000903" }
|
|
279
271
|
}
|
|
280
272
|
]
|
|
281
273
|
}
|
|
@@ -288,14 +280,11 @@ var signUp = {
|
|
|
288
280
|
title: "Sign up",
|
|
289
281
|
description: "A user signup is sent to Reddit as a SignUp conversion with hashed user identifiers.",
|
|
290
282
|
in: getEvent("user signup", {
|
|
283
|
+
id: "ev-1700000904",
|
|
291
284
|
timestamp: 1700000904,
|
|
292
285
|
data: { method: "email" },
|
|
293
286
|
user: { id: "new-user-1", email: "new@example.com" },
|
|
294
|
-
source: {
|
|
295
|
-
type: "server",
|
|
296
|
-
id: "https://www.example.com/register",
|
|
297
|
-
previous_id: ""
|
|
298
|
-
}
|
|
287
|
+
source: { type: "express", platform: "server" }
|
|
299
288
|
}),
|
|
300
289
|
mapping: {
|
|
301
290
|
name: "SignUp",
|
|
@@ -327,7 +316,7 @@ var signUp = {
|
|
|
327
316
|
// sha256('new-user-1')
|
|
328
317
|
external_id: "b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde"
|
|
329
318
|
},
|
|
330
|
-
event_metadata: { conversion_id: "1700000904
|
|
319
|
+
event_metadata: { conversion_id: "ev-1700000904" }
|
|
331
320
|
}
|
|
332
321
|
]
|
|
333
322
|
}
|
|
@@ -340,14 +329,11 @@ var search = {
|
|
|
340
329
|
title: "Search",
|
|
341
330
|
description: "A site search is sent to Reddit as a Search conversion with an item count in event_metadata.",
|
|
342
331
|
in: getEvent("site search", {
|
|
332
|
+
id: "ev-1700000905",
|
|
343
333
|
timestamp: 1700000905,
|
|
344
334
|
data: { query: "walkerOS destinations" },
|
|
345
335
|
user: { id: "user-101" },
|
|
346
|
-
source: {
|
|
347
|
-
type: "server",
|
|
348
|
-
id: "https://www.example.com/search",
|
|
349
|
-
previous_id: ""
|
|
350
|
-
}
|
|
336
|
+
source: { type: "express", platform: "server" }
|
|
351
337
|
}),
|
|
352
338
|
mapping: {
|
|
353
339
|
name: "Search",
|
|
@@ -374,7 +360,7 @@ var search = {
|
|
|
374
360
|
event_type: { tracking_type: "Search" },
|
|
375
361
|
user: {},
|
|
376
362
|
event_metadata: {
|
|
377
|
-
conversion_id: "1700000905
|
|
363
|
+
conversion_id: "ev-1700000905",
|
|
378
364
|
item_count: 1
|
|
379
365
|
}
|
|
380
366
|
}
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var mod,__defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropNames=Object.getOwnPropertyNames,__hasOwnProp=Object.prototype.hasOwnProperty,index_exports={};((target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})})(index_exports,{DestinationReddit:()=>types_exports,default:()=>index_default,destinationReddit:()=>destinationReddit}),module.exports=(mod=index_exports,((to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to})(__defProp({},"__esModule",{value:!0}),mod));var import_core2=require("@walkeros/core"),import_server_core2=require("@walkeros/server-core"),import_core=require("@walkeros/core"),import_server_core=require("@walkeros/server-core"),keysToHash=["email","external_id","ip_address","user_agent","idfa","aaid"];function shouldBeHashed(key,doNotHash=[]){return keysToHash.includes(key)&&!doNotHash.includes(key)}async function processValue(value,shouldHash){return shouldHash?(0,import_core.isArray)(value)?Promise.all(value.map(item=>(0,import_server_core.getHashServer)(String(item)))):(0,import_server_core.getHashServer)(String(value)):value}var STANDARD_TRACKING_TYPES=new Set(["PageVisit","ViewContent","Search","AddToCart","AddToWishlist","Purchase","Lead","SignUp","Custom"]);function buildEventType(name){return function(name){return STANDARD_TRACKING_TYPES.has(name)}(name)&&"Custom"!==name?{tracking_type:name}:{tracking_type:"Custom",custom_event_name:name}}var push=async function(event,{config:config,data:data,env:env,logger:logger}){
|
|
1
|
+
"use strict";var mod,__defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropNames=Object.getOwnPropertyNames,__hasOwnProp=Object.prototype.hasOwnProperty,index_exports={};((target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})})(index_exports,{DestinationReddit:()=>types_exports,default:()=>index_default,destinationReddit:()=>destinationReddit}),module.exports=(mod=index_exports,((to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to})(__defProp({},"__esModule",{value:!0}),mod));var import_core2=require("@walkeros/core"),import_server_core2=require("@walkeros/server-core"),import_core=require("@walkeros/core"),import_server_core=require("@walkeros/server-core"),keysToHash=["email","external_id","ip_address","user_agent","idfa","aaid"];function shouldBeHashed(key,doNotHash=[]){return keysToHash.includes(key)&&!doNotHash.includes(key)}async function processValue(value,shouldHash){return shouldHash?(0,import_core.isArray)(value)?Promise.all(value.map(item=>(0,import_server_core.getHashServer)(String(item)))):(0,import_server_core.getHashServer)(String(value)):value}var STANDARD_TRACKING_TYPES=new Set(["PageVisit","ViewContent","Search","AddToCart","AddToWishlist","Purchase","Lead","SignUp","Custom"]);function buildEventType(name){return function(name){return STANDARD_TRACKING_TYPES.has(name)}(name)&&"Custom"!==name?{tracking_type:name}:{tracking_type:"Custom",custom_event_name:name}}var push=async function(event,{config:config,data:data,env:env,logger:logger,collector:collector}){const{accessToken:accessToken,pixelId:pixelId,action_source:_action_source,doNotHash:doNotHash,test_mode:test_mode,url:url="https://ads-api.reddit.com/api/v2.0/conversions/events/",user_data:user_data}=config.settings,eventData=(0,import_core2.isObject)(data)?data:{},configData=config.data?await(0,import_core2.getMappingValue)(event,config.data,{collector:collector}):{},userDataCustom=user_data?await(0,import_core2.getMappingValue)(event,{map:user_data},{collector:collector}):{},userData={...(0,import_core2.isObject)(configData)&&(0,import_core2.isObject)(configData.user)?configData.user:{},...(0,import_core2.isObject)(userDataCustom)?userDataCustom:{},...(0,import_core2.isObject)(eventData.user)?eventData.user:{}},{user:_u,event_metadata:eventMetadata,click_id:eventClickId,...restEventData}=eventData,timestampMs=event.timestamp||Date.now(),serverEvent={event_at:new Date(timestampMs).toISOString(),event_at_ms:timestampMs,event_type:buildEventType(event.name),...restEventData,user:userData},metadataFromMapping=(0,import_core2.isObject)(eventMetadata)?eventMetadata:{};serverEvent.event_metadata={conversion_id:event.id,...metadataFromMapping},"string"==typeof eventClickId&&(serverEvent.click_id=eventClickId);const hashedServerEvent=await async function(value,doNotHash=[]){if(!(0,import_core.isObject)(value))return value;const isUser="user"in value,target=isUser?value.user:value,result=(await Promise.all(Object.entries(target).map(async([k,v])=>[k,await processValue(v,isUser&&shouldBeHashed(k,doNotHash))]))).reduce((acc,[k,v])=>((0,import_core.isString)(k)&&(acc[k]=v),acc),{});return isUser?{...value,user:result}:result}(serverEvent,doNotHash),body={...test_mode?{test_mode:!0}:{},data:{events:[hashedServerEvent]}},endpoint=`${url}${pixelId}`;logger.debug("Calling Reddit API",{endpoint:endpoint,method:"POST",trackingType:serverEvent.event_type.tracking_type,eventId:serverEvent.event_metadata?.conversion_id});const sendServerFn=env?.sendServer||import_server_core2.sendServer,result=await sendServerFn(endpoint,JSON.stringify(body),{headers:{Authorization:`Bearer ${accessToken}`}});logger.debug("Reddit API response",{ok:!(0,import_core2.isObject)(result)||result.ok}),(0,import_core2.isObject)(result)&&!1===result.ok&&logger.throw(`Reddit API error: ${JSON.stringify(result)}`)},types_exports={},destinationReddit={type:"reddit",config:{},async init({config:partialConfig,logger:logger}){const config=function(partialConfig={},logger){const settings=partialConfig.settings||{},{accessToken:accessToken,pixelId:pixelId}=settings;accessToken||logger.throw("Config settings accessToken missing"),pixelId||logger.throw("Config settings pixelId missing");const settingsConfig={...settings,accessToken:accessToken,pixelId:pixelId};return{...partialConfig,settings:settingsConfig}}(partialConfig,logger);return config},push:async(event,context)=>await push(event,context)},index_default=destinationReddit;//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/push.ts","../src/hash.ts","../src/types/index.ts"],"sourcesContent":["import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationReddit from './types';\n\nexport const destinationReddit: Destination = {\n type: 'reddit',\n\n config: {},\n\n async init({ config: partialConfig, logger }) {\n const config = getConfig(partialConfig, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n};\n\nexport default destinationReddit;\n","import type { Config, Settings, PartialConfig } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { accessToken, pixelId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!pixelId) logger.throw('Config settings pixelId missing');\n\n const settingsConfig: Settings = {\n ...settings,\n accessToken,\n pixelId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type {\n ConversionEvent,\n EventType,\n PushFn,\n RequestBody,\n TrackingType,\n UserData,\n} from './types';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashEvent } from './hash';\n\nconst STANDARD_TRACKING_TYPES: ReadonlySet<TrackingType> =\n new Set<TrackingType>([\n 'PageVisit',\n 'ViewContent',\n 'Search',\n 'AddToCart',\n 'AddToWishlist',\n 'Purchase',\n 'Lead',\n 'SignUp',\n 'Custom',\n ]);\n\nfunction isStandardTrackingType(name: string): name is TrackingType {\n return STANDARD_TRACKING_TYPES.has(name as TrackingType);\n}\n\nfunction buildEventType(name: string): EventType {\n if (isStandardTrackingType(name) && name !== 'Custom') {\n return { tracking_type: name };\n }\n return { tracking_type: 'Custom', custom_event_name: name };\n}\n\nexport const push: PushFn = async function (\n event,\n { config, data, env, logger },\n) {\n const {\n accessToken,\n pixelId,\n action_source: _action_source,\n doNotHash,\n test_mode,\n url = 'https://ads-api.reddit.com/api/v2.0/conversions/events/',\n user_data,\n } = config.settings!;\n\n const eventData = isObject(data) ? data : {};\n const configData = config.data\n ? await getMappingValue(event, config.data)\n : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data })\n : {};\n\n // Merge user data from config.data, settings.user_data, and event mapping\n const userData: UserData = {\n ...(isObject(configData) && isObject(configData.user)\n ? configData.user\n : {}),\n ...(isObject(userDataCustom) ? userDataCustom : {}),\n ...(isObject(eventData.user) ? eventData.user : {}),\n };\n\n const {\n user: _u,\n event_metadata: eventMetadata,\n click_id: eventClickId,\n ...restEventData\n } = eventData;\n\n const timestampMs = event.timestamp || Date.now();\n\n const serverEvent: ConversionEvent = {\n event_at: new Date(timestampMs).toISOString(),\n event_at_ms: timestampMs,\n event_type: buildEventType(event.name),\n ...restEventData,\n user: userData,\n };\n\n // Merge event_metadata with auto-populated conversion_id (event.id for dedup)\n const metadataFromMapping = isObject(eventMetadata) ? eventMetadata : {};\n serverEvent.event_metadata = {\n conversion_id: event.id,\n ...metadataFromMapping,\n };\n\n if (typeof eventClickId === 'string') {\n serverEvent.click_id = eventClickId;\n }\n\n const hashedServerEvent = await hashEvent(serverEvent, doNotHash);\n\n const body: RequestBody = {\n ...(test_mode ? { test_mode: true } : {}),\n data: { events: [hashedServerEvent] },\n };\n\n const endpoint = `${url}${pixelId}`;\n\n logger.debug('Calling Reddit API', {\n endpoint,\n method: 'POST',\n trackingType: serverEvent.event_type.tracking_type,\n eventId: serverEvent.event_metadata?.conversion_id,\n });\n\n const sendServerFn = env?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(body), {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n\n logger.debug('Reddit API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Reddit API error: ${JSON.stringify(result)}`);\n }\n};\n","import { WalkerOS } from '@walkeros/core';\nimport { isArray, isObject, isString } from '@walkeros/core';\nimport { getHashServer } from '@walkeros/server-core';\n\nconst keysToHash = [\n 'email',\n 'external_id',\n 'ip_address',\n 'user_agent',\n 'idfa',\n 'aaid',\n];\n\nfunction shouldBeHashed(key: string, doNotHash: string[] = []): boolean {\n return keysToHash.includes(key) && !doNotHash.includes(key);\n}\n\ntype HashableValue = WalkerOS.AnyObject | unknown | unknown[];\n\nasync function processValue(\n value: unknown,\n shouldHash: boolean,\n): Promise<unknown> {\n if (!shouldHash) return value;\n if (isArray(value)) {\n return Promise.all(value.map((item) => getHashServer(String(item))));\n }\n return getHashServer(String(value));\n}\n\nexport async function hashEvent<T extends HashableValue>(\n value: T,\n doNotHash: string[] = [],\n): Promise<T> {\n if (!isObject(value)) return value;\n\n const isUser = 'user' in value;\n const target = (isUser ? value.user : value) as WalkerOS.AnyObject;\n\n const entries = await Promise.all(\n Object.entries(target).map(async ([k, v]) => [\n k,\n await processValue(v, isUser && shouldBeHashed(k, doNotHash)),\n ]),\n );\n\n const result = entries.reduce((acc, [k, v]) => {\n if (isString(k)) acc[k] = v;\n return acc;\n }, {} as WalkerOS.AnyObject);\n\n return isUser ? { ...value, user: result } : (result as T);\n}\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer, sendServer } from '@walkeros/server-core';\n\nexport interface Settings {\n accessToken: string;\n pixelId: string;\n action_source?: ActionSource;\n doNotHash?: string[];\n test_mode?: boolean;\n url?: string;\n user_data?: WalkerOSMapping.Map;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n// Reddit Conversions API types\n// https://ads-api.reddit.com/docs/v2/#tag/Conversions-API\n\nexport type ActionSource = 'WEBSITE' | 'APP' | 'PHYSICAL_STORE';\n\nexport type TrackingType =\n | 'PageVisit'\n | 'ViewContent'\n | 'Search'\n | 'AddToCart'\n | 'AddToWishlist'\n | 'Purchase'\n | 'Lead'\n | 'SignUp'\n | 'Custom';\n\nexport interface EventType {\n tracking_type: TrackingType;\n custom_event_name?: string;\n}\n\nexport interface Product {\n id: string;\n name?: string;\n category: string;\n}\n\nexport interface EventMetadata {\n conversion_id?: string;\n item_count?: number;\n currency?: string;\n value?: number;\n value_decimal?: number;\n products?: Product[];\n units_sold?: number;\n country_code?: string;\n}\n\nexport interface ScreenDimensions {\n width: number;\n height: number;\n}\n\nexport interface DataProcessingOptions {\n modes: string[];\n country?: string;\n region?: string;\n}\n\nexport interface UserData {\n // Hashable fields (SHA-256)\n email?: string;\n external_id?: string;\n ip_address?: string;\n user_agent?: string;\n idfa?: string;\n aaid?: string;\n\n // Pass-through fields (not hashed)\n uuid?: string;\n opt_out?: boolean;\n screen_dimensions?: ScreenDimensions;\n data_processing_options?: DataProcessingOptions;\n}\n\nexport interface ConversionEvent {\n click_id?: string;\n event_at: string;\n event_at_ms?: number;\n event_type: EventType;\n event_metadata?: EventMetadata;\n user: UserData;\n}\n\nexport interface RequestBody {\n test_mode?: boolean;\n data: {\n events: ConversionEvent[];\n };\n}\n\nexport interface ResponseBody {\n success?: boolean;\n message?: string;\n}\n"],"mappings":"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","names":["import_core","import_server_core"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/push.ts","../src/hash.ts","../src/types/index.ts"],"sourcesContent":["import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationReddit from './types';\n\nexport const destinationReddit: Destination = {\n type: 'reddit',\n\n config: {},\n\n async init({ config: partialConfig, logger }) {\n const config = getConfig(partialConfig, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n};\n\nexport default destinationReddit;\n","import type { Config, Settings, PartialConfig } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { accessToken, pixelId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!pixelId) logger.throw('Config settings pixelId missing');\n\n const settingsConfig: Settings = {\n ...settings,\n accessToken,\n pixelId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type {\n ConversionEvent,\n EventType,\n PushFn,\n RequestBody,\n TrackingType,\n UserData,\n} from './types';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashEvent } from './hash';\n\nconst STANDARD_TRACKING_TYPES: ReadonlySet<TrackingType> =\n new Set<TrackingType>([\n 'PageVisit',\n 'ViewContent',\n 'Search',\n 'AddToCart',\n 'AddToWishlist',\n 'Purchase',\n 'Lead',\n 'SignUp',\n 'Custom',\n ]);\n\nfunction isStandardTrackingType(name: string): name is TrackingType {\n return STANDARD_TRACKING_TYPES.has(name as TrackingType);\n}\n\nfunction buildEventType(name: string): EventType {\n if (isStandardTrackingType(name) && name !== 'Custom') {\n return { tracking_type: name };\n }\n return { tracking_type: 'Custom', custom_event_name: name };\n}\n\nexport const push: PushFn = async function (\n event,\n { config, data, env, logger, collector },\n) {\n const {\n accessToken,\n pixelId,\n action_source: _action_source,\n doNotHash,\n test_mode,\n url = 'https://ads-api.reddit.com/api/v2.0/conversions/events/',\n user_data,\n } = config.settings!;\n\n const eventData = isObject(data) ? data : {};\n const configData = config.data\n ? await getMappingValue(event, config.data, { collector })\n : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data }, { collector })\n : {};\n\n // Merge user data from config.data, settings.user_data, and event mapping\n const userData: UserData = {\n ...(isObject(configData) && isObject(configData.user)\n ? configData.user\n : {}),\n ...(isObject(userDataCustom) ? userDataCustom : {}),\n ...(isObject(eventData.user) ? eventData.user : {}),\n };\n\n const {\n user: _u,\n event_metadata: eventMetadata,\n click_id: eventClickId,\n ...restEventData\n } = eventData;\n\n const timestampMs = event.timestamp || Date.now();\n\n const serverEvent: ConversionEvent = {\n event_at: new Date(timestampMs).toISOString(),\n event_at_ms: timestampMs,\n event_type: buildEventType(event.name),\n ...restEventData,\n user: userData,\n };\n\n // Merge event_metadata with auto-populated conversion_id (event.id for dedup)\n const metadataFromMapping = isObject(eventMetadata) ? eventMetadata : {};\n serverEvent.event_metadata = {\n conversion_id: event.id,\n ...metadataFromMapping,\n };\n\n if (typeof eventClickId === 'string') {\n serverEvent.click_id = eventClickId;\n }\n\n const hashedServerEvent = await hashEvent(serverEvent, doNotHash);\n\n const body: RequestBody = {\n ...(test_mode ? { test_mode: true } : {}),\n data: { events: [hashedServerEvent] },\n };\n\n const endpoint = `${url}${pixelId}`;\n\n logger.debug('Calling Reddit API', {\n endpoint,\n method: 'POST',\n trackingType: serverEvent.event_type.tracking_type,\n eventId: serverEvent.event_metadata?.conversion_id,\n });\n\n const sendServerFn = env?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(body), {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n\n logger.debug('Reddit API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Reddit API error: ${JSON.stringify(result)}`);\n }\n};\n","import { WalkerOS } from '@walkeros/core';\nimport { isArray, isObject, isString } from '@walkeros/core';\nimport { getHashServer } from '@walkeros/server-core';\n\nconst keysToHash = [\n 'email',\n 'external_id',\n 'ip_address',\n 'user_agent',\n 'idfa',\n 'aaid',\n];\n\nfunction shouldBeHashed(key: string, doNotHash: string[] = []): boolean {\n return keysToHash.includes(key) && !doNotHash.includes(key);\n}\n\ntype HashableValue = WalkerOS.AnyObject | unknown | unknown[];\n\nasync function processValue(\n value: unknown,\n shouldHash: boolean,\n): Promise<unknown> {\n if (!shouldHash) return value;\n if (isArray(value)) {\n return Promise.all(value.map((item) => getHashServer(String(item))));\n }\n return getHashServer(String(value));\n}\n\nexport async function hashEvent<T extends HashableValue>(\n value: T,\n doNotHash: string[] = [],\n): Promise<T> {\n if (!isObject(value)) return value;\n\n const isUser = 'user' in value;\n const target = (isUser ? value.user : value) as WalkerOS.AnyObject;\n\n const entries = await Promise.all(\n Object.entries(target).map(async ([k, v]) => [\n k,\n await processValue(v, isUser && shouldBeHashed(k, doNotHash)),\n ]),\n );\n\n const result = entries.reduce((acc, [k, v]) => {\n if (isString(k)) acc[k] = v;\n return acc;\n }, {} as WalkerOS.AnyObject);\n\n return isUser ? { ...value, user: result } : (result as T);\n}\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer, sendServer } from '@walkeros/server-core';\n\nexport interface Settings {\n accessToken: string;\n pixelId: string;\n action_source?: ActionSource;\n doNotHash?: string[];\n test_mode?: boolean;\n url?: string;\n user_data?: WalkerOSMapping.Map;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n// Reddit Conversions API types\n// https://ads-api.reddit.com/docs/v2/#tag/Conversions-API\n\nexport type ActionSource = 'WEBSITE' | 'APP' | 'PHYSICAL_STORE';\n\nexport type TrackingType =\n | 'PageVisit'\n | 'ViewContent'\n | 'Search'\n | 'AddToCart'\n | 'AddToWishlist'\n | 'Purchase'\n | 'Lead'\n | 'SignUp'\n | 'Custom';\n\nexport interface EventType {\n tracking_type: TrackingType;\n custom_event_name?: string;\n}\n\nexport interface Product {\n id: string;\n name?: string;\n category: string;\n}\n\nexport interface EventMetadata {\n conversion_id?: string;\n item_count?: number;\n currency?: string;\n value?: number;\n value_decimal?: number;\n products?: Product[];\n units_sold?: number;\n country_code?: string;\n}\n\nexport interface ScreenDimensions {\n width: number;\n height: number;\n}\n\nexport interface DataProcessingOptions {\n modes: string[];\n country?: string;\n region?: string;\n}\n\nexport interface UserData {\n // Hashable fields (SHA-256)\n email?: string;\n external_id?: string;\n ip_address?: string;\n user_agent?: string;\n idfa?: string;\n aaid?: string;\n\n // Pass-through fields (not hashed)\n uuid?: string;\n opt_out?: boolean;\n screen_dimensions?: ScreenDimensions;\n data_processing_options?: DataProcessingOptions;\n}\n\nexport interface ConversionEvent {\n click_id?: string;\n event_at: string;\n event_at_ms?: number;\n event_type: EventType;\n event_metadata?: EventMetadata;\n user: UserData;\n}\n\nexport interface RequestBody {\n test_mode?: boolean;\n data: {\n events: ConversionEvent[];\n };\n}\n\nexport interface ResponseBody {\n success?: boolean;\n message?: string;\n}\n"],"mappings":"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","names":["import_core","import_server_core"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getMappingValue,isObject as isObject2}from"@walkeros/core";import{sendServer}from"@walkeros/server-core";import{isArray,isObject,isString}from"@walkeros/core";import{getHashServer}from"@walkeros/server-core";var keysToHash=["email","external_id","ip_address","user_agent","idfa","aaid"];function shouldBeHashed(key,doNotHash=[]){return keysToHash.includes(key)&&!doNotHash.includes(key)}async function processValue(value,shouldHash){return shouldHash?isArray(value)?Promise.all(value.map(item=>getHashServer(String(item)))):getHashServer(String(value)):value}var STANDARD_TRACKING_TYPES=new Set(["PageVisit","ViewContent","Search","AddToCart","AddToWishlist","Purchase","Lead","SignUp","Custom"]);function buildEventType(name){return function(name){return STANDARD_TRACKING_TYPES.has(name)}(name)&&"Custom"!==name?{tracking_type:name}:{tracking_type:"Custom",custom_event_name:name}}var push=async function(event,{config:config,data:data,env:env,logger:logger}){
|
|
1
|
+
import{getMappingValue,isObject as isObject2}from"@walkeros/core";import{sendServer}from"@walkeros/server-core";import{isArray,isObject,isString}from"@walkeros/core";import{getHashServer}from"@walkeros/server-core";var keysToHash=["email","external_id","ip_address","user_agent","idfa","aaid"];function shouldBeHashed(key,doNotHash=[]){return keysToHash.includes(key)&&!doNotHash.includes(key)}async function processValue(value,shouldHash){return shouldHash?isArray(value)?Promise.all(value.map(item=>getHashServer(String(item)))):getHashServer(String(value)):value}var STANDARD_TRACKING_TYPES=new Set(["PageVisit","ViewContent","Search","AddToCart","AddToWishlist","Purchase","Lead","SignUp","Custom"]);function buildEventType(name){return function(name){return STANDARD_TRACKING_TYPES.has(name)}(name)&&"Custom"!==name?{tracking_type:name}:{tracking_type:"Custom",custom_event_name:name}}var push=async function(event,{config:config,data:data,env:env,logger:logger,collector:collector}){const{accessToken:accessToken,pixelId:pixelId,action_source:_action_source,doNotHash:doNotHash,test_mode:test_mode,url:url="https://ads-api.reddit.com/api/v2.0/conversions/events/",user_data:user_data}=config.settings,eventData=isObject2(data)?data:{},configData=config.data?await getMappingValue(event,config.data,{collector:collector}):{},userDataCustom=user_data?await getMappingValue(event,{map:user_data},{collector:collector}):{},userData={...isObject2(configData)&&isObject2(configData.user)?configData.user:{},...isObject2(userDataCustom)?userDataCustom:{},...isObject2(eventData.user)?eventData.user:{}},{user:_u,event_metadata:eventMetadata,click_id:eventClickId,...restEventData}=eventData,timestampMs=event.timestamp||Date.now(),serverEvent={event_at:new Date(timestampMs).toISOString(),event_at_ms:timestampMs,event_type:buildEventType(event.name),...restEventData,user:userData},metadataFromMapping=isObject2(eventMetadata)?eventMetadata:{};serverEvent.event_metadata={conversion_id:event.id,...metadataFromMapping},"string"==typeof eventClickId&&(serverEvent.click_id=eventClickId);const hashedServerEvent=await async function(value,doNotHash=[]){if(!isObject(value))return value;const isUser="user"in value,target=isUser?value.user:value,result=(await Promise.all(Object.entries(target).map(async([k,v])=>[k,await processValue(v,isUser&&shouldBeHashed(k,doNotHash))]))).reduce((acc,[k,v])=>(isString(k)&&(acc[k]=v),acc),{});return isUser?{...value,user:result}:result}(serverEvent,doNotHash),body={...test_mode?{test_mode:!0}:{},data:{events:[hashedServerEvent]}},endpoint=`${url}${pixelId}`;logger.debug("Calling Reddit API",{endpoint:endpoint,method:"POST",trackingType:serverEvent.event_type.tracking_type,eventId:serverEvent.event_metadata?.conversion_id});const sendServerFn=env?.sendServer||sendServer,result=await sendServerFn(endpoint,JSON.stringify(body),{headers:{Authorization:`Bearer ${accessToken}`}});logger.debug("Reddit API response",{ok:!isObject2(result)||result.ok}),isObject2(result)&&!1===result.ok&&logger.throw(`Reddit API error: ${JSON.stringify(result)}`)},types_exports={},destinationReddit={type:"reddit",config:{},async init({config:partialConfig,logger:logger}){const config=function(partialConfig={},logger){const settings=partialConfig.settings||{},{accessToken:accessToken,pixelId:pixelId}=settings;accessToken||logger.throw("Config settings accessToken missing"),pixelId||logger.throw("Config settings pixelId missing");const settingsConfig={...settings,accessToken:accessToken,pixelId:pixelId};return{...partialConfig,settings:settingsConfig}}(partialConfig,logger);return config},push:async(event,context)=>await push(event,context)},index_default=destinationReddit;export{types_exports as DestinationReddit,index_default as default,destinationReddit};//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/push.ts","../src/hash.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { Config, Settings, PartialConfig } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { accessToken, pixelId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!pixelId) logger.throw('Config settings pixelId missing');\n\n const settingsConfig: Settings = {\n ...settings,\n accessToken,\n pixelId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type {\n ConversionEvent,\n EventType,\n PushFn,\n RequestBody,\n TrackingType,\n UserData,\n} from './types';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashEvent } from './hash';\n\nconst STANDARD_TRACKING_TYPES: ReadonlySet<TrackingType> =\n new Set<TrackingType>([\n 'PageVisit',\n 'ViewContent',\n 'Search',\n 'AddToCart',\n 'AddToWishlist',\n 'Purchase',\n 'Lead',\n 'SignUp',\n 'Custom',\n ]);\n\nfunction isStandardTrackingType(name: string): name is TrackingType {\n return STANDARD_TRACKING_TYPES.has(name as TrackingType);\n}\n\nfunction buildEventType(name: string): EventType {\n if (isStandardTrackingType(name) && name !== 'Custom') {\n return { tracking_type: name };\n }\n return { tracking_type: 'Custom', custom_event_name: name };\n}\n\nexport const push: PushFn = async function (\n event,\n { config, data, env, logger },\n) {\n const {\n accessToken,\n pixelId,\n action_source: _action_source,\n doNotHash,\n test_mode,\n url = 'https://ads-api.reddit.com/api/v2.0/conversions/events/',\n user_data,\n } = config.settings!;\n\n const eventData = isObject(data) ? data : {};\n const configData = config.data\n ? await getMappingValue(event, config.data)\n : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data })\n : {};\n\n // Merge user data from config.data, settings.user_data, and event mapping\n const userData: UserData = {\n ...(isObject(configData) && isObject(configData.user)\n ? configData.user\n : {}),\n ...(isObject(userDataCustom) ? userDataCustom : {}),\n ...(isObject(eventData.user) ? eventData.user : {}),\n };\n\n const {\n user: _u,\n event_metadata: eventMetadata,\n click_id: eventClickId,\n ...restEventData\n } = eventData;\n\n const timestampMs = event.timestamp || Date.now();\n\n const serverEvent: ConversionEvent = {\n event_at: new Date(timestampMs).toISOString(),\n event_at_ms: timestampMs,\n event_type: buildEventType(event.name),\n ...restEventData,\n user: userData,\n };\n\n // Merge event_metadata with auto-populated conversion_id (event.id for dedup)\n const metadataFromMapping = isObject(eventMetadata) ? eventMetadata : {};\n serverEvent.event_metadata = {\n conversion_id: event.id,\n ...metadataFromMapping,\n };\n\n if (typeof eventClickId === 'string') {\n serverEvent.click_id = eventClickId;\n }\n\n const hashedServerEvent = await hashEvent(serverEvent, doNotHash);\n\n const body: RequestBody = {\n ...(test_mode ? { test_mode: true } : {}),\n data: { events: [hashedServerEvent] },\n };\n\n const endpoint = `${url}${pixelId}`;\n\n logger.debug('Calling Reddit API', {\n endpoint,\n method: 'POST',\n trackingType: serverEvent.event_type.tracking_type,\n eventId: serverEvent.event_metadata?.conversion_id,\n });\n\n const sendServerFn = env?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(body), {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n\n logger.debug('Reddit API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Reddit API error: ${JSON.stringify(result)}`);\n }\n};\n","import { WalkerOS } from '@walkeros/core';\nimport { isArray, isObject, isString } from '@walkeros/core';\nimport { getHashServer } from '@walkeros/server-core';\n\nconst keysToHash = [\n 'email',\n 'external_id',\n 'ip_address',\n 'user_agent',\n 'idfa',\n 'aaid',\n];\n\nfunction shouldBeHashed(key: string, doNotHash: string[] = []): boolean {\n return keysToHash.includes(key) && !doNotHash.includes(key);\n}\n\ntype HashableValue = WalkerOS.AnyObject | unknown | unknown[];\n\nasync function processValue(\n value: unknown,\n shouldHash: boolean,\n): Promise<unknown> {\n if (!shouldHash) return value;\n if (isArray(value)) {\n return Promise.all(value.map((item) => getHashServer(String(item))));\n }\n return getHashServer(String(value));\n}\n\nexport async function hashEvent<T extends HashableValue>(\n value: T,\n doNotHash: string[] = [],\n): Promise<T> {\n if (!isObject(value)) return value;\n\n const isUser = 'user' in value;\n const target = (isUser ? value.user : value) as WalkerOS.AnyObject;\n\n const entries = await Promise.all(\n Object.entries(target).map(async ([k, v]) => [\n k,\n await processValue(v, isUser && shouldBeHashed(k, doNotHash)),\n ]),\n );\n\n const result = entries.reduce((acc, [k, v]) => {\n if (isString(k)) acc[k] = v;\n return acc;\n }, {} as WalkerOS.AnyObject);\n\n return isUser ? { ...value, user: result } : (result as T);\n}\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer, sendServer } from '@walkeros/server-core';\n\nexport interface Settings {\n accessToken: string;\n pixelId: string;\n action_source?: ActionSource;\n doNotHash?: string[];\n test_mode?: boolean;\n url?: string;\n user_data?: WalkerOSMapping.Map;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n// Reddit Conversions API types\n// https://ads-api.reddit.com/docs/v2/#tag/Conversions-API\n\nexport type ActionSource = 'WEBSITE' | 'APP' | 'PHYSICAL_STORE';\n\nexport type TrackingType =\n | 'PageVisit'\n | 'ViewContent'\n | 'Search'\n | 'AddToCart'\n | 'AddToWishlist'\n | 'Purchase'\n | 'Lead'\n | 'SignUp'\n | 'Custom';\n\nexport interface EventType {\n tracking_type: TrackingType;\n custom_event_name?: string;\n}\n\nexport interface Product {\n id: string;\n name?: string;\n category: string;\n}\n\nexport interface EventMetadata {\n conversion_id?: string;\n item_count?: number;\n currency?: string;\n value?: number;\n value_decimal?: number;\n products?: Product[];\n units_sold?: number;\n country_code?: string;\n}\n\nexport interface ScreenDimensions {\n width: number;\n height: number;\n}\n\nexport interface DataProcessingOptions {\n modes: string[];\n country?: string;\n region?: string;\n}\n\nexport interface UserData {\n // Hashable fields (SHA-256)\n email?: string;\n external_id?: string;\n ip_address?: string;\n user_agent?: string;\n idfa?: string;\n aaid?: string;\n\n // Pass-through fields (not hashed)\n uuid?: string;\n opt_out?: boolean;\n screen_dimensions?: ScreenDimensions;\n data_processing_options?: DataProcessingOptions;\n}\n\nexport interface ConversionEvent {\n click_id?: string;\n event_at: string;\n event_at_ms?: number;\n event_type: EventType;\n event_metadata?: EventMetadata;\n user: UserData;\n}\n\nexport interface RequestBody {\n test_mode?: boolean;\n data: {\n events: ConversionEvent[];\n };\n}\n\nexport interface ResponseBody {\n success?: boolean;\n message?: string;\n}\n","import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationReddit from './types';\n\nexport const destinationReddit: Destination = {\n type: 'reddit',\n\n config: {},\n\n async init({ config: partialConfig, logger }) {\n const config = getConfig(partialConfig, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n};\n\nexport default destinationReddit;\n"],"mappings":"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","names":["isObject","isObject"]}
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/push.ts","../src/hash.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { Config, Settings, PartialConfig } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { accessToken, pixelId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!pixelId) logger.throw('Config settings pixelId missing');\n\n const settingsConfig: Settings = {\n ...settings,\n accessToken,\n pixelId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type {\n ConversionEvent,\n EventType,\n PushFn,\n RequestBody,\n TrackingType,\n UserData,\n} from './types';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashEvent } from './hash';\n\nconst STANDARD_TRACKING_TYPES: ReadonlySet<TrackingType> =\n new Set<TrackingType>([\n 'PageVisit',\n 'ViewContent',\n 'Search',\n 'AddToCart',\n 'AddToWishlist',\n 'Purchase',\n 'Lead',\n 'SignUp',\n 'Custom',\n ]);\n\nfunction isStandardTrackingType(name: string): name is TrackingType {\n return STANDARD_TRACKING_TYPES.has(name as TrackingType);\n}\n\nfunction buildEventType(name: string): EventType {\n if (isStandardTrackingType(name) && name !== 'Custom') {\n return { tracking_type: name };\n }\n return { tracking_type: 'Custom', custom_event_name: name };\n}\n\nexport const push: PushFn = async function (\n event,\n { config, data, env, logger, collector },\n) {\n const {\n accessToken,\n pixelId,\n action_source: _action_source,\n doNotHash,\n test_mode,\n url = 'https://ads-api.reddit.com/api/v2.0/conversions/events/',\n user_data,\n } = config.settings!;\n\n const eventData = isObject(data) ? data : {};\n const configData = config.data\n ? await getMappingValue(event, config.data, { collector })\n : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data }, { collector })\n : {};\n\n // Merge user data from config.data, settings.user_data, and event mapping\n const userData: UserData = {\n ...(isObject(configData) && isObject(configData.user)\n ? configData.user\n : {}),\n ...(isObject(userDataCustom) ? userDataCustom : {}),\n ...(isObject(eventData.user) ? eventData.user : {}),\n };\n\n const {\n user: _u,\n event_metadata: eventMetadata,\n click_id: eventClickId,\n ...restEventData\n } = eventData;\n\n const timestampMs = event.timestamp || Date.now();\n\n const serverEvent: ConversionEvent = {\n event_at: new Date(timestampMs).toISOString(),\n event_at_ms: timestampMs,\n event_type: buildEventType(event.name),\n ...restEventData,\n user: userData,\n };\n\n // Merge event_metadata with auto-populated conversion_id (event.id for dedup)\n const metadataFromMapping = isObject(eventMetadata) ? eventMetadata : {};\n serverEvent.event_metadata = {\n conversion_id: event.id,\n ...metadataFromMapping,\n };\n\n if (typeof eventClickId === 'string') {\n serverEvent.click_id = eventClickId;\n }\n\n const hashedServerEvent = await hashEvent(serverEvent, doNotHash);\n\n const body: RequestBody = {\n ...(test_mode ? { test_mode: true } : {}),\n data: { events: [hashedServerEvent] },\n };\n\n const endpoint = `${url}${pixelId}`;\n\n logger.debug('Calling Reddit API', {\n endpoint,\n method: 'POST',\n trackingType: serverEvent.event_type.tracking_type,\n eventId: serverEvent.event_metadata?.conversion_id,\n });\n\n const sendServerFn = env?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(body), {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n\n logger.debug('Reddit API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Reddit API error: ${JSON.stringify(result)}`);\n }\n};\n","import { WalkerOS } from '@walkeros/core';\nimport { isArray, isObject, isString } from '@walkeros/core';\nimport { getHashServer } from '@walkeros/server-core';\n\nconst keysToHash = [\n 'email',\n 'external_id',\n 'ip_address',\n 'user_agent',\n 'idfa',\n 'aaid',\n];\n\nfunction shouldBeHashed(key: string, doNotHash: string[] = []): boolean {\n return keysToHash.includes(key) && !doNotHash.includes(key);\n}\n\ntype HashableValue = WalkerOS.AnyObject | unknown | unknown[];\n\nasync function processValue(\n value: unknown,\n shouldHash: boolean,\n): Promise<unknown> {\n if (!shouldHash) return value;\n if (isArray(value)) {\n return Promise.all(value.map((item) => getHashServer(String(item))));\n }\n return getHashServer(String(value));\n}\n\nexport async function hashEvent<T extends HashableValue>(\n value: T,\n doNotHash: string[] = [],\n): Promise<T> {\n if (!isObject(value)) return value;\n\n const isUser = 'user' in value;\n const target = (isUser ? value.user : value) as WalkerOS.AnyObject;\n\n const entries = await Promise.all(\n Object.entries(target).map(async ([k, v]) => [\n k,\n await processValue(v, isUser && shouldBeHashed(k, doNotHash)),\n ]),\n );\n\n const result = entries.reduce((acc, [k, v]) => {\n if (isString(k)) acc[k] = v;\n return acc;\n }, {} as WalkerOS.AnyObject);\n\n return isUser ? { ...value, user: result } : (result as T);\n}\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer, sendServer } from '@walkeros/server-core';\n\nexport interface Settings {\n accessToken: string;\n pixelId: string;\n action_source?: ActionSource;\n doNotHash?: string[];\n test_mode?: boolean;\n url?: string;\n user_data?: WalkerOSMapping.Map;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n// Reddit Conversions API types\n// https://ads-api.reddit.com/docs/v2/#tag/Conversions-API\n\nexport type ActionSource = 'WEBSITE' | 'APP' | 'PHYSICAL_STORE';\n\nexport type TrackingType =\n | 'PageVisit'\n | 'ViewContent'\n | 'Search'\n | 'AddToCart'\n | 'AddToWishlist'\n | 'Purchase'\n | 'Lead'\n | 'SignUp'\n | 'Custom';\n\nexport interface EventType {\n tracking_type: TrackingType;\n custom_event_name?: string;\n}\n\nexport interface Product {\n id: string;\n name?: string;\n category: string;\n}\n\nexport interface EventMetadata {\n conversion_id?: string;\n item_count?: number;\n currency?: string;\n value?: number;\n value_decimal?: number;\n products?: Product[];\n units_sold?: number;\n country_code?: string;\n}\n\nexport interface ScreenDimensions {\n width: number;\n height: number;\n}\n\nexport interface DataProcessingOptions {\n modes: string[];\n country?: string;\n region?: string;\n}\n\nexport interface UserData {\n // Hashable fields (SHA-256)\n email?: string;\n external_id?: string;\n ip_address?: string;\n user_agent?: string;\n idfa?: string;\n aaid?: string;\n\n // Pass-through fields (not hashed)\n uuid?: string;\n opt_out?: boolean;\n screen_dimensions?: ScreenDimensions;\n data_processing_options?: DataProcessingOptions;\n}\n\nexport interface ConversionEvent {\n click_id?: string;\n event_at: string;\n event_at_ms?: number;\n event_type: EventType;\n event_metadata?: EventMetadata;\n user: UserData;\n}\n\nexport interface RequestBody {\n test_mode?: boolean;\n data: {\n events: ConversionEvent[];\n };\n}\n\nexport interface ResponseBody {\n success?: boolean;\n message?: string;\n}\n","import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationReddit from './types';\n\nexport const destinationReddit: Destination = {\n type: 'reddit',\n\n config: {},\n\n async init({ config: partialConfig, logger }) {\n const config = getConfig(partialConfig, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n};\n\nexport default destinationReddit;\n"],"mappings":"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","names":["isObject","isObject"]}
|
package/dist/walkerOS.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$meta": {
|
|
3
3
|
"package": "@walkeros/server-destination-reddit",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.0-next-1777882869103",
|
|
5
5
|
"type": "destination",
|
|
6
6
|
"platform": [
|
|
7
7
|
"server"
|
|
@@ -116,22 +116,15 @@
|
|
|
116
116
|
"consent": {
|
|
117
117
|
"functional": true
|
|
118
118
|
},
|
|
119
|
-
"id": "1700000901
|
|
119
|
+
"id": "ev-1700000901",
|
|
120
120
|
"trigger": "click",
|
|
121
121
|
"entity": "product",
|
|
122
122
|
"action": "add",
|
|
123
123
|
"timestamp": 1700000901,
|
|
124
124
|
"timing": 3.14,
|
|
125
|
-
"group": "gr0up",
|
|
126
|
-
"count": 1,
|
|
127
|
-
"version": {
|
|
128
|
-
"source": "3.4.2",
|
|
129
|
-
"tagging": 1
|
|
130
|
-
},
|
|
131
125
|
"source": {
|
|
132
|
-
"type": "
|
|
133
|
-
"
|
|
134
|
-
"previous_id": ""
|
|
126
|
+
"type": "express",
|
|
127
|
+
"platform": "server"
|
|
135
128
|
}
|
|
136
129
|
},
|
|
137
130
|
"mapping": {
|
|
@@ -170,7 +163,7 @@
|
|
|
170
163
|
[
|
|
171
164
|
"sendServer",
|
|
172
165
|
"https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456",
|
|
173
|
-
"{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.901Z\",\"event_at_ms\":1700000901,\"event_type\":{\"tracking_type\":\"AddToCart\"},\"user\":{},\"event_metadata\":{\"conversion_id\":\"1700000901
|
|
166
|
+
"{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.901Z\",\"event_at_ms\":1700000901,\"event_type\":{\"tracking_type\":\"AddToCart\"},\"user\":{},\"event_metadata\":{\"conversion_id\":\"ev-1700000901\",\"value_decimal\":\"42.00\",\"currency\":\"EUR\",\"item_count\":1,\"products\":[{\"id\":\"SKU-B2\",\"name\":\"Cool Cap\",\"category\":\"hats\"}]}}]}}",
|
|
174
167
|
{
|
|
175
168
|
"headers": {
|
|
176
169
|
"Authorization": "Bearer s3cr3t"
|
|
@@ -208,35 +201,21 @@
|
|
|
208
201
|
"entity": "child",
|
|
209
202
|
"data": {
|
|
210
203
|
"is": "subordinated"
|
|
211
|
-
},
|
|
212
|
-
"nested": [],
|
|
213
|
-
"context": {
|
|
214
|
-
"element": [
|
|
215
|
-
"child",
|
|
216
|
-
0
|
|
217
|
-
]
|
|
218
204
|
}
|
|
219
205
|
}
|
|
220
206
|
],
|
|
221
207
|
"consent": {
|
|
222
208
|
"functional": true
|
|
223
209
|
},
|
|
224
|
-
"id": "1700000903
|
|
210
|
+
"id": "ev-1700000903",
|
|
225
211
|
"trigger": "test",
|
|
226
212
|
"entity": "form",
|
|
227
213
|
"action": "submit",
|
|
228
214
|
"timestamp": 1700000903,
|
|
229
215
|
"timing": 3.14,
|
|
230
|
-
"group": "gr0up",
|
|
231
|
-
"count": 1,
|
|
232
|
-
"version": {
|
|
233
|
-
"source": "3.4.2",
|
|
234
|
-
"tagging": 1
|
|
235
|
-
},
|
|
236
216
|
"source": {
|
|
237
|
-
"type": "
|
|
238
|
-
"
|
|
239
|
-
"previous_id": ""
|
|
217
|
+
"type": "express",
|
|
218
|
+
"platform": "server"
|
|
240
219
|
}
|
|
241
220
|
},
|
|
242
221
|
"mapping": {
|
|
@@ -256,7 +235,7 @@
|
|
|
256
235
|
[
|
|
257
236
|
"sendServer",
|
|
258
237
|
"https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456",
|
|
259
|
-
"{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.903Z\",\"event_at_ms\":1700000903,\"event_type\":{\"tracking_type\":\"Lead\"},\"user\":{\"email\":\"9fbdefe2837a03c9225be80e741f316f4d174d1732b719b6abb6477efc1ae9d2\",\"external_id\":\"ee818eebb052cf288ffeeb2e09ee35c9946e1a7f53a959cb3ef06d5d4adb78e8\"},\"event_metadata\":{\"conversion_id\":\"1700000903
|
|
238
|
+
"{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.903Z\",\"event_at_ms\":1700000903,\"event_type\":{\"tracking_type\":\"Lead\"},\"user\":{\"email\":\"9fbdefe2837a03c9225be80e741f316f4d174d1732b719b6abb6477efc1ae9d2\",\"external_id\":\"ee818eebb052cf288ffeeb2e09ee35c9946e1a7f53a959cb3ef06d5d4adb78e8\"},\"event_metadata\":{\"conversion_id\":\"ev-1700000903\"}}]}}",
|
|
260
239
|
{
|
|
261
240
|
"headers": {
|
|
262
241
|
"Authorization": "Bearer s3cr3t"
|
|
@@ -298,35 +277,21 @@
|
|
|
298
277
|
"entity": "child",
|
|
299
278
|
"data": {
|
|
300
279
|
"is": "subordinated"
|
|
301
|
-
},
|
|
302
|
-
"nested": [],
|
|
303
|
-
"context": {
|
|
304
|
-
"element": [
|
|
305
|
-
"child",
|
|
306
|
-
0
|
|
307
|
-
]
|
|
308
280
|
}
|
|
309
281
|
}
|
|
310
282
|
],
|
|
311
283
|
"consent": {
|
|
312
284
|
"functional": true
|
|
313
285
|
},
|
|
314
|
-
"id": "1700000902
|
|
286
|
+
"id": "ev-1700000902",
|
|
315
287
|
"trigger": "load",
|
|
316
288
|
"entity": "page",
|
|
317
289
|
"action": "view",
|
|
318
290
|
"timestamp": 1700000902,
|
|
319
291
|
"timing": 3.14,
|
|
320
|
-
"group": "gr0up",
|
|
321
|
-
"count": 1,
|
|
322
|
-
"version": {
|
|
323
|
-
"source": "3.4.2",
|
|
324
|
-
"tagging": 1
|
|
325
|
-
},
|
|
326
292
|
"source": {
|
|
327
|
-
"type": "
|
|
328
|
-
"
|
|
329
|
-
"previous_id": ""
|
|
293
|
+
"type": "express",
|
|
294
|
+
"platform": "server"
|
|
330
295
|
}
|
|
331
296
|
},
|
|
332
297
|
"mapping": {
|
|
@@ -336,7 +301,7 @@
|
|
|
336
301
|
[
|
|
337
302
|
"sendServer",
|
|
338
303
|
"https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456",
|
|
339
|
-
"{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.902Z\",\"event_at_ms\":1700000902,\"event_type\":{\"tracking_type\":\"PageVisit\"},\"user\":{},\"event_metadata\":{\"conversion_id\":\"1700000902
|
|
304
|
+
"{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.902Z\",\"event_at_ms\":1700000902,\"event_type\":{\"tracking_type\":\"PageVisit\"},\"user\":{},\"event_metadata\":{\"conversion_id\":\"ev-1700000902\"}}]}}",
|
|
340
305
|
{
|
|
341
306
|
"headers": {
|
|
342
307
|
"Authorization": "Bearer s3cr3t"
|
|
@@ -386,22 +351,15 @@
|
|
|
386
351
|
"consent": {
|
|
387
352
|
"functional": true
|
|
388
353
|
},
|
|
389
|
-
"id": "1700000900
|
|
354
|
+
"id": "ev-1700000900",
|
|
390
355
|
"trigger": "load",
|
|
391
356
|
"entity": "order",
|
|
392
357
|
"action": "complete",
|
|
393
358
|
"timestamp": 1700000900,
|
|
394
359
|
"timing": 3.14,
|
|
395
|
-
"group": "gr0up",
|
|
396
|
-
"count": 1,
|
|
397
|
-
"version": {
|
|
398
|
-
"source": "3.4.2",
|
|
399
|
-
"tagging": 1
|
|
400
|
-
},
|
|
401
360
|
"source": {
|
|
402
|
-
"type": "
|
|
403
|
-
"
|
|
404
|
-
"previous_id": ""
|
|
361
|
+
"type": "express",
|
|
362
|
+
"platform": "server"
|
|
405
363
|
}
|
|
406
364
|
},
|
|
407
365
|
"mapping": {
|
|
@@ -425,7 +383,7 @@
|
|
|
425
383
|
"nested",
|
|
426
384
|
{
|
|
427
385
|
"condition": {
|
|
428
|
-
"$code": "e=>
|
|
386
|
+
"$code": "e=>h(e)&&\"product\"===e.entity"
|
|
429
387
|
},
|
|
430
388
|
"map": {
|
|
431
389
|
"id": "data.id",
|
|
@@ -447,7 +405,7 @@
|
|
|
447
405
|
[
|
|
448
406
|
"sendServer",
|
|
449
407
|
"https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456",
|
|
450
|
-
"{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.900Z\",\"event_at_ms\":1700000900,\"event_type\":{\"tracking_type\":\"Purchase\"},\"user\":{},\"event_metadata\":{\"conversion_id\":\"1700000900
|
|
408
|
+
"{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.900Z\",\"event_at_ms\":1700000900,\"event_type\":{\"tracking_type\":\"Purchase\"},\"user\":{},\"event_metadata\":{\"conversion_id\":\"ev-1700000900\",\"value_decimal\":249.99,\"currency\":\"EUR\",\"item_count\":1,\"products\":[{\"id\":\"SKU-A1\",\"name\":\"Everyday Ruck Snack\",\"category\":\"bags\"}]}}]}}",
|
|
451
409
|
{
|
|
452
410
|
"headers": {
|
|
453
411
|
"Authorization": "Bearer s3cr3t"
|
|
@@ -484,35 +442,21 @@
|
|
|
484
442
|
"entity": "child",
|
|
485
443
|
"data": {
|
|
486
444
|
"is": "subordinated"
|
|
487
|
-
},
|
|
488
|
-
"nested": [],
|
|
489
|
-
"context": {
|
|
490
|
-
"element": [
|
|
491
|
-
"child",
|
|
492
|
-
0
|
|
493
|
-
]
|
|
494
445
|
}
|
|
495
446
|
}
|
|
496
447
|
],
|
|
497
448
|
"consent": {
|
|
498
449
|
"functional": true
|
|
499
450
|
},
|
|
500
|
-
"id": "1700000905
|
|
451
|
+
"id": "ev-1700000905",
|
|
501
452
|
"trigger": "test",
|
|
502
453
|
"entity": "site",
|
|
503
454
|
"action": "search",
|
|
504
455
|
"timestamp": 1700000905,
|
|
505
456
|
"timing": 3.14,
|
|
506
|
-
"group": "gr0up",
|
|
507
|
-
"count": 1,
|
|
508
|
-
"version": {
|
|
509
|
-
"source": "3.4.2",
|
|
510
|
-
"tagging": 1
|
|
511
|
-
},
|
|
512
457
|
"source": {
|
|
513
|
-
"type": "
|
|
514
|
-
"
|
|
515
|
-
"previous_id": ""
|
|
458
|
+
"type": "express",
|
|
459
|
+
"platform": "server"
|
|
516
460
|
}
|
|
517
461
|
},
|
|
518
462
|
"mapping": {
|
|
@@ -533,7 +477,7 @@
|
|
|
533
477
|
[
|
|
534
478
|
"sendServer",
|
|
535
479
|
"https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456",
|
|
536
|
-
"{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.905Z\",\"event_at_ms\":1700000905,\"event_type\":{\"tracking_type\":\"Search\"},\"user\":{},\"event_metadata\":{\"conversion_id\":\"1700000905
|
|
480
|
+
"{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.905Z\",\"event_at_ms\":1700000905,\"event_type\":{\"tracking_type\":\"Search\"},\"user\":{},\"event_metadata\":{\"conversion_id\":\"ev-1700000905\",\"item_count\":1}}]}}",
|
|
537
481
|
{
|
|
538
482
|
"headers": {
|
|
539
483
|
"Authorization": "Bearer s3cr3t"
|
|
@@ -571,35 +515,21 @@
|
|
|
571
515
|
"entity": "child",
|
|
572
516
|
"data": {
|
|
573
517
|
"is": "subordinated"
|
|
574
|
-
},
|
|
575
|
-
"nested": [],
|
|
576
|
-
"context": {
|
|
577
|
-
"element": [
|
|
578
|
-
"child",
|
|
579
|
-
0
|
|
580
|
-
]
|
|
581
518
|
}
|
|
582
519
|
}
|
|
583
520
|
],
|
|
584
521
|
"consent": {
|
|
585
522
|
"functional": true
|
|
586
523
|
},
|
|
587
|
-
"id": "1700000904
|
|
524
|
+
"id": "ev-1700000904",
|
|
588
525
|
"trigger": "test",
|
|
589
526
|
"entity": "user",
|
|
590
527
|
"action": "signup",
|
|
591
528
|
"timestamp": 1700000904,
|
|
592
529
|
"timing": 3.14,
|
|
593
|
-
"group": "gr0up",
|
|
594
|
-
"count": 1,
|
|
595
|
-
"version": {
|
|
596
|
-
"source": "3.4.2",
|
|
597
|
-
"tagging": 1
|
|
598
|
-
},
|
|
599
530
|
"source": {
|
|
600
|
-
"type": "
|
|
601
|
-
"
|
|
602
|
-
"previous_id": ""
|
|
531
|
+
"type": "express",
|
|
532
|
+
"platform": "server"
|
|
603
533
|
}
|
|
604
534
|
},
|
|
605
535
|
"mapping": {
|
|
@@ -619,7 +549,7 @@
|
|
|
619
549
|
[
|
|
620
550
|
"sendServer",
|
|
621
551
|
"https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456",
|
|
622
|
-
"{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.904Z\",\"event_at_ms\":1700000904,\"event_type\":{\"tracking_type\":\"SignUp\"},\"user\":{\"email\":\"f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716\",\"external_id\":\"b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde\"},\"event_metadata\":{\"conversion_id\":\"1700000904
|
|
552
|
+
"{\"data\":{\"events\":[{\"event_at\":\"1970-01-20T16:13:20.904Z\",\"event_at_ms\":1700000904,\"event_type\":{\"tracking_type\":\"SignUp\"},\"user\":{\"email\":\"f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716\",\"external_id\":\"b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde\"},\"event_metadata\":{\"conversion_id\":\"ev-1700000904\"}}]}}",
|
|
623
553
|
{
|
|
624
554
|
"headers": {
|
|
625
555
|
"Authorization": "Bearer s3cr3t"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walkeros/server-destination-reddit",
|
|
3
3
|
"description": "Reddit server destination for walkerOS",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.0-next-1777882869103",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"update": "npx npm-check-updates -u && npm update"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@walkeros/core": "
|
|
38
|
-
"@walkeros/server-core": "
|
|
37
|
+
"@walkeros/core": "4.0.0-next-1777882869103",
|
|
38
|
+
"@walkeros/server-core": "4.0.0-next-1777882869103"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@walkeros/collector": "
|
|
41
|
+
"@walkeros/collector": "4.0.0-next-1777882869103"
|
|
42
42
|
},
|
|
43
43
|
"repository": {
|
|
44
44
|
"url": "git+https://github.com/elbwalker/walkerOS.git",
|