Skip to content

fix(recombee): Fix API inconsistencies#3767

Open
mstieranka wants to merge 5 commits into
segmentio:mainfrom
recombee:recombee-fix-timestamp-type
Open

fix(recombee): Fix API inconsistencies#3767
mstieranka wants to merge 5 commits into
segmentio:mainfrom
recombee:recombee-fix-timestamp-type

Conversation

@mstieranka
Copy link
Copy Markdown
Contributor

@mstieranka mstieranka commented Apr 29, 2026

Hi, we have identified several issues with out Recombee destination, and this pull request fixes all of them.

  1. In the actions Delete Cart Addition and Delete Bookmark, the request to our API was incorrectly setting the timestamp to milliseconds since epoch where seconds were expected. The following changes were made:
  • The tests now correctly expect a seconds-based timestamp, and the integration code has been updated to reflect this change.
  • In all actions, the optional field timestamp has been modified to use the datetime type instead of string, which more accurately reflects the intended values.
    • Note: When testing using the local server, the mapping accepts an arbitrary string field, however, when sending the payload, the current live version ends up returning HTTP 400 (the API rejects this parameter), whereas this version returns HTTP 500 (the validation already fails in Segment). I'm not sure if this is a breaking change, since both requests would have failed and the field itself is optional in all mappings. This is why the "Tested for backwards compatibility" task below is not yet marked as complete.
  • The timestamp handling has generally been made more robust to accept any form of date string parseable by new Date(str) or a number representing either seconds or milliseconds since epoch. The field description has been changed to reflect this fact.
  1. The default timestamp used by Segment ($.timestamp) is corrected for clock skew, however, that means that the Recombee API receives a different timestamp than the user sent. Since the Delete Bookmark action expects the exact same timestamp as when sending the request, this meant that such a use case wouldn't work. The following changes were made:
  • The timestamp mapping in Add* events has been changed to use $.properties.timestamp by default, falling back to $.timestamp if not present.
  • The timestamp mapping in Delete* events now also uses $.properties.timestamp.
  • The field descriptions were updated to clearly state this fact and advise users.
  1. In Segment Ecommerce events, the price field is stated per-unit, however, the Recombee API expects the price and profit fields to be stated per the given quantity. Therefore, the destination now multiplies price by amount to match the expectation of the Recombee API.

Testing

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

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

Security Review

Please ensure sensitive data is properly protected in your integration.

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

New Destination Checklist

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

Copilot AI review requested due to automatic review settings April 29, 2026 15:37
@mstieranka mstieranka requested a review from a team as a code owner April 29, 2026 15:37
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes timestamp handling for the Recombee destination, ensuring delete interactions send timestamps in seconds (as required by Recombee) and aligning action field schemas to use the datetime field type.

Changes:

  • Update Delete Bookmark / Delete Cart Addition URL construction to send timestamp as epoch seconds (converting from ms/ISO when needed).
  • Change timestamp input fields across Recombee actions from string to datetime (and update generated types accordingly).
  • Update unit tests/snapshots to reflect the new timestamp expectations and payload shapes.

Reviewed changes

Copilot reviewed 31 out of 31 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/destination-actions/src/destinations/recombee/setViewPortionFromWatchTime/index.ts Switch timestamp field to datetime.
packages/destination-actions/src/destinations/recombee/setViewPortionFromWatchTime/generated-types.ts Update timestamp payload type to string | number.
packages/destination-actions/src/destinations/recombee/setViewPortionFromWatchTime/tests/snapshots/snapshot.test.ts.snap Snapshot update for timestamp value shape.
packages/destination-actions/src/destinations/recombee/setViewPortion/index.ts Switch timestamp field to datetime.
packages/destination-actions/src/destinations/recombee/setViewPortion/generated-types.ts Update timestamp payload type to string | number.
packages/destination-actions/src/destinations/recombee/setViewPortion/tests/snapshots/snapshot.test.ts.snap Snapshot update for timestamp value shape.
packages/destination-actions/src/destinations/recombee/recombeeApiClient.ts Convert delete timestamp to epoch seconds and build query via URLSearchParams.
packages/destination-actions/src/destinations/recombee/deleteCartAddition/index.ts Switch timestamp field to datetime.
packages/destination-actions/src/destinations/recombee/deleteCartAddition/generated-types.ts Update timestamp payload type to string | number.
packages/destination-actions/src/destinations/recombee/deleteCartAddition/tests/index.test.ts Update tests to expect 10-digit (seconds) timestamps and seconds-based URL assertions.
packages/destination-actions/src/destinations/recombee/deleteCartAddition/tests/snapshots/snapshot.test.ts.snap Snapshot update for timestamp value shape.
packages/destination-actions/src/destinations/recombee/deleteBookmark/index.ts Switch timestamp field to datetime.
packages/destination-actions/src/destinations/recombee/deleteBookmark/generated-types.ts Update timestamp payload type to string | number.
packages/destination-actions/src/destinations/recombee/deleteBookmark/tests/index.test.ts Update tests to expect 10-digit (seconds) timestamps and seconds-based URL assertions.
packages/destination-actions/src/destinations/recombee/deleteBookmark/tests/snapshots/snapshot.test.ts.snap Snapshot update for timestamp value shape.
packages/destination-actions/src/destinations/recombee/addRating/index.ts Switch timestamp field to datetime.
packages/destination-actions/src/destinations/recombee/addRating/generated-types.ts Update timestamp payload type to string | number.
packages/destination-actions/src/destinations/recombee/addRating/tests/snapshots/snapshot.test.ts.snap Snapshot update for timestamp value shape.
packages/destination-actions/src/destinations/recombee/addPurchase/index.ts Switch timestamp field to datetime.
packages/destination-actions/src/destinations/recombee/addPurchase/generated-types.ts Update timestamp payload type to string | number.
packages/destination-actions/src/destinations/recombee/addPurchase/tests/snapshots/snapshot.test.ts.snap Snapshot update for timestamp value shape.
packages/destination-actions/src/destinations/recombee/addDetailView/index.ts Switch timestamp field to datetime.
packages/destination-actions/src/destinations/recombee/addDetailView/generated-types.ts Update timestamp payload type to string | number.
packages/destination-actions/src/destinations/recombee/addDetailView/tests/snapshots/snapshot.test.ts.snap Snapshot update for timestamp value shape.
packages/destination-actions/src/destinations/recombee/addCartAddition/index.ts Switch timestamp field to datetime.
packages/destination-actions/src/destinations/recombee/addCartAddition/generated-types.ts Update timestamp payload type to string | number.
packages/destination-actions/src/destinations/recombee/addCartAddition/tests/snapshots/snapshot.test.ts.snap Snapshot update for timestamp value shape.
packages/destination-actions/src/destinations/recombee/addBookmark/index.ts Switch timestamp field to datetime.
packages/destination-actions/src/destinations/recombee/addBookmark/generated-types.ts Update timestamp payload type to string | number.
packages/destination-actions/src/destinations/recombee/addBookmark/tests/snapshots/snapshot.test.ts.snap Snapshot update for timestamp value shape.
packages/destination-actions/src/destinations/recombee/tests/snapshots/snapshot.test.ts.snap Update destination-level snapshots for timestamp value shape across actions.

Comment thread packages/destination-actions/src/destinations/recombee/recombeeApiClient.ts Outdated
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Copilot AI review requested due to automatic review settings April 30, 2026 13:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes Recombee delete-interaction timestamp handling (seconds vs. milliseconds) and updates Recombee action field schemas so timestamp is modeled as a datetime (and thus typed as string | number) across the destination.

Changes:

  • Fix Delete Cart Addition and Delete Bookmark URL timestamp to send Unix seconds (and add more robust timestamp parsing/normalization for deletes).
  • Change timestamp input field type from stringdatetime across Recombee actions and update generated payload types accordingly.
  • Update unit tests and snapshots to reflect the datetime field behavior and the corrected delete timestamp semantics.

Reviewed changes

Copilot reviewed 31 out of 31 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/destination-actions/src/destinations/recombee/recombeeApiClient.ts Normalize delete URL query params via URLSearchParams; convert/delete timestamp to epoch seconds and validate invalid timestamps.
packages/destination-actions/src/destinations/recombee/deleteCartAddition/index.ts Change timestamp field type to datetime.
packages/destination-actions/src/destinations/recombee/deleteCartAddition/generated-types.ts Update payload timestamp type to string | number.
packages/destination-actions/src/destinations/recombee/deleteCartAddition/tests/index.test.ts Update delete URL expectations to 10-digit seconds timestamps.
packages/destination-actions/src/destinations/recombee/deleteCartAddition/tests/snapshots/snapshot.test.ts.snap Snapshot update for datetime timestamp example.
packages/destination-actions/src/destinations/recombee/deleteBookmark/index.ts Change timestamp field type to datetime.
packages/destination-actions/src/destinations/recombee/deleteBookmark/generated-types.ts Update payload timestamp type to string | number.
packages/destination-actions/src/destinations/recombee/deleteBookmark/tests/index.test.ts Update delete URL expectations to 10-digit seconds timestamps.
packages/destination-actions/src/destinations/recombee/deleteBookmark/tests/snapshots/snapshot.test.ts.snap Snapshot update for datetime timestamp example.
packages/destination-actions/src/destinations/recombee/addBookmark/index.ts Change timestamp field type to datetime.
packages/destination-actions/src/destinations/recombee/addBookmark/generated-types.ts Update payload timestamp type to string | number.
packages/destination-actions/src/destinations/recombee/addBookmark/tests/snapshots/snapshot.test.ts.snap Snapshot update for datetime timestamp example.
packages/destination-actions/src/destinations/recombee/addCartAddition/index.ts Change timestamp field type to datetime.
packages/destination-actions/src/destinations/recombee/addCartAddition/generated-types.ts Update payload timestamp type to string | number.
packages/destination-actions/src/destinations/recombee/addCartAddition/tests/snapshots/snapshot.test.ts.snap Snapshot update for datetime timestamp example.
packages/destination-actions/src/destinations/recombee/addDetailView/index.ts Change timestamp field type to datetime.
packages/destination-actions/src/destinations/recombee/addDetailView/generated-types.ts Update payload timestamp type to string | number.
packages/destination-actions/src/destinations/recombee/addDetailView/tests/snapshots/snapshot.test.ts.snap Snapshot update for datetime timestamp example.
packages/destination-actions/src/destinations/recombee/addPurchase/index.ts Change timestamp field type to datetime.
packages/destination-actions/src/destinations/recombee/addPurchase/generated-types.ts Update payload timestamp type to string | number.
packages/destination-actions/src/destinations/recombee/addPurchase/tests/snapshots/snapshot.test.ts.snap Snapshot update for datetime timestamp example.
packages/destination-actions/src/destinations/recombee/addRating/index.ts Change timestamp field type to datetime.
packages/destination-actions/src/destinations/recombee/addRating/generated-types.ts Update payload timestamp type to string | number.
packages/destination-actions/src/destinations/recombee/addRating/tests/snapshots/snapshot.test.ts.snap Snapshot update for datetime timestamp example.
packages/destination-actions/src/destinations/recombee/setViewPortion/index.ts Change timestamp field type to datetime.
packages/destination-actions/src/destinations/recombee/setViewPortion/generated-types.ts Update payload timestamp type to string | number.
packages/destination-actions/src/destinations/recombee/setViewPortion/tests/snapshots/snapshot.test.ts.snap Snapshot update for datetime timestamp example.
packages/destination-actions/src/destinations/recombee/setViewPortionFromWatchTime/index.ts Change timestamp field type to datetime.
packages/destination-actions/src/destinations/recombee/setViewPortionFromWatchTime/generated-types.ts Update payload timestamp type to string | number.
packages/destination-actions/src/destinations/recombee/setViewPortionFromWatchTime/tests/snapshots/snapshot.test.ts.snap Snapshot update for datetime timestamp example.
packages/destination-actions/src/destinations/recombee/tests/snapshots/snapshot.test.ts.snap Aggregate snapshot updates for datetime timestamp examples across actions.

Comment thread packages/destination-actions/src/destinations/recombee/recombeeApiClient.ts Outdated
Comment thread packages/destination-actions/src/destinations/recombee/recombeeApiClient.ts Outdated
@mstieranka mstieranka marked this pull request as draft May 11, 2026 09:01
@joe-ayoub-segment
Copy link
Copy Markdown
Contributor

Hi @mstieranka please ping me when this PR is ready for review.

Copilot AI review requested due to automatic review settings May 12, 2026 10:09
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 39 out of 39 changed files in this pull request and generated 2 comments.

Comment on lines +97 to +101
// 10,000,000,000 is the year 2286 in seconds, anything larger is likely in milliseconds
if (numValue >= 10000000000) {
return numValue / 1000
} else {
return numValue
Comment on lines +159 to 170
function getDeleteUrl(interactionType: string, params: DeleteParams): string {
const query = new URLSearchParams({
userId: params.userId,
itemId: params.itemId
})

if (params.timestamp !== undefined && params.timestamp !== null) {
query.append('timestamp', String(datetimeToEpochSeconds(params.timestamp)))
}
return url

return `/${interactionType}/?${query.toString()}`
}
@mstieranka mstieranka changed the title fix(recombee): Send time as seconds in Delete events, change field type fix(recombee): Fix API inconsistencies May 12, 2026
@mstieranka mstieranka force-pushed the recombee-fix-timestamp-type branch from 61b9364 to 9b20518 Compare May 12, 2026 10:18
@mstieranka mstieranka marked this pull request as ready for review May 12, 2026 10:30
Copilot AI review requested due to automatic review settings May 12, 2026 10:30
@mstieranka
Copy link
Copy Markdown
Contributor Author

Hi @joe-ayoub-segment , this PR has had some changes added to it and is now ready for review.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 39 out of 39 changed files in this pull request and generated 1 comment.

Comment on lines +97 to +101
// 10,000,000,000 is the year 2286 in seconds, anything larger is likely in milliseconds
if (numValue >= 10000000000) {
return numValue / 1000
} else {
return numValue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants