Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "4.17.1"
".": "4.18.0"
}
8 changes: 4 additions & 4 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 134
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier/courier-97bb4b698571b6dbe884e93397d14aff0ec7e7279de272a15fa0defb3b2515d5.yml
openapi_spec_hash: c33bf8733151f4f5693788b6e57a8344
config_hash: 74aad10d1512ec69541ece3ca51cf7fa
configured_endpoints: 135
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier/courier-e593915c67b3e0e375b6f9cf57d9931f86bc3ee4fd6759ba0e8098d5421fa04e.yml
openapi_spec_hash: 66cc0ce5dda5bda9f416ea3e53c3f5a0
config_hash: 66d7703eac15d2affc326ac25b55bcd6
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

## 4.18.0 (2026-06-30)

Full Changelog: [v4.17.1...v4.18.0](https://github.com/trycourier/courier-ruby/compare/v4.17.1...v4.18.0)

### Features

* **openapi:** Journeys cancel-by-token endpoint + send-node experiments (C-18986) ([12613c6](https://github.com/trycourier/courier-ruby/commit/12613c65e9b4facc19f7fa23cc92fac0b2ea8684))


### Chores

* **internal:** bound formatter parallelism to CPU count ([192d613](https://github.com/trycourier/courier-ruby/commit/192d6133c29e2ae7bfcd7c54bd1c244894f01b94))

## 4.17.1 (2026-06-25)

Full Changelog: [v4.17.0...v4.17.1](https://github.com/trycourier/courier-ruby/compare/v4.17.0...v4.17.1)
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ GIT
PATH
remote: .
specs:
trycourier (4.17.1)
trycourier (4.18.0)
cgi
connection_pool

Expand Down
7 changes: 6 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

require "etc"
require "pathname"
require "securerandom"
require "shellwords"
Expand Down Expand Up @@ -37,7 +38,11 @@ multitask(:test) do
ruby(*%w[-w -e], rb, verbose: false) { fail unless _1 }
end

xargs = %w[xargs --no-run-if-empty --null --max-procs=0 --max-args=300 --]
# Cap parallelism at the CPU count. `--max-procs=0` spawns one process per
# 300-file batch with no upper bound; on large SDKs (thousands of files) that
# oversubscribes CPUs and stacks up rubocop processes, exhausting memory and
# slowing CI to the point of timing out.
xargs = %W[xargs --no-run-if-empty --null --max-procs=#{Etc.nprocessors} --max-args=300 --]
ruby_opt = {"RUBYOPT" => [ENV["RUBYOPT"], "--encoding=UTF-8"].compact.join(" ")}

filtered = ->(ext, dirs) do
Expand Down
5 changes: 5 additions & 0 deletions lib/courier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
require_relative "courier/models/base_check"
require_relative "courier/models/subscription_topic_new"
require_relative "courier/models/elemental_channel_node"
require_relative "courier/models/cancel_journey_request"
require_relative "courier/models/create_journey_request"
require_relative "courier/models/journeys_invoke_request"
require_relative "courier/models/journey_publish_request"
Expand Down Expand Up @@ -131,6 +132,7 @@
require_relative "courier/models/bulk_retrieve_job_params"
require_relative "courier/models/bulk_retrieve_job_response"
require_relative "courier/models/bulk_run_job_params"
require_relative "courier/models/cancel_journey_response"
require_relative "courier/models/channel"
require_relative "courier/models/channel_classification"
require_relative "courier/models/channel_metadata"
Expand Down Expand Up @@ -171,6 +173,7 @@
require_relative "courier/models/journey_ai_node"
require_relative "courier/models/journey_api_invoke_trigger_node"
require_relative "courier/models/journey_archive_params"
require_relative "courier/models/journey_cancel_params"
require_relative "courier/models/journey_condition_atom"
require_relative "courier/models/journey_condition_group"
require_relative "courier/models/journey_condition_nested_group"
Expand All @@ -179,6 +182,8 @@
require_relative "courier/models/journey_delay_duration_node"
require_relative "courier/models/journey_delay_until_node"
require_relative "courier/models/journey_exit_node"
require_relative "courier/models/journey_experiment"
require_relative "courier/models/journey_experiment_variant"
require_relative "courier/models/journey_fetch_get_delete_node"
require_relative "courier/models/journey_fetch_post_put_node"
require_relative "courier/models/journey_invoke_params"
Expand Down
10 changes: 10 additions & 0 deletions lib/courier/models.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ module Courier

BulkRunJobParams = Courier::Models::BulkRunJobParams

CancelJourneyRequest = Courier::Models::CancelJourneyRequest

CancelJourneyResponse = Courier::Models::CancelJourneyResponse

Channel = Courier::Models::Channel

ChannelClassification = Courier::Models::ChannelClassification
Expand Down Expand Up @@ -207,6 +211,8 @@ module Courier

JourneyArchiveParams = Courier::Models::JourneyArchiveParams

JourneyCancelParams = Courier::Models::JourneyCancelParams

# @type [Courier::Internal::Type::Converter]
JourneyConditionAtom = Courier::Models::JourneyConditionAtom

Expand All @@ -224,6 +230,10 @@ module Courier

JourneyExitNode = Courier::Models::JourneyExitNode

JourneyExperiment = Courier::Models::JourneyExperiment

JourneyExperimentVariant = Courier::Models::JourneyExperimentVariant

JourneyFetchGetDeleteNode = Courier::Models::JourneyFetchGetDeleteNode

JourneyFetchPostPutNode = Courier::Models::JourneyFetchPostPutNode
Expand Down
39 changes: 39 additions & 0 deletions lib/courier/models/cancel_journey_request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

module Courier
module Models
# Request body for `POST /journeys/cancel`. Provide EXACTLY ONE of
# `cancelation_token` (cancels every run associated with the token) or `run_id`
# (cancels a single tenant-scoped run).
module CancelJourneyRequest
extend Courier::Internal::Type::Union

variant -> { Courier::CancelJourneyRequest::ByCancelationToken }

variant -> { Courier::CancelJourneyRequest::ByRunID }

class ByCancelationToken < Courier::Internal::Type::BaseModel
# @!attribute cancelation_token
#
# @return [String]
required :cancelation_token, String

# @!method initialize(cancelation_token:)
# @param cancelation_token [String]
end

class ByRunID < Courier::Internal::Type::BaseModel
# @!attribute run_id
#
# @return [String]
required :run_id, String

# @!method initialize(run_id:)
# @param run_id [String]
end

# @!method self.variants
# @return [Array(Courier::Models::CancelJourneyRequest::ByCancelationToken, Courier::Models::CancelJourneyRequest::ByRunID)]
end
end
end
54 changes: 54 additions & 0 deletions lib/courier/models/cancel_journey_response.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

module Courier
module Models
# `202 Accepted` body for `POST /journeys/cancel`, echoing the submitted
# identifier. The token branch returns `{ cancelation_token }`; the run_id branch
# returns `{ run_id, status }`.
#
# @see Courier::Resources::Journeys#cancel
module CancelJourneyResponse
extend Courier::Internal::Type::Union

variant -> { Courier::CancelJourneyResponse::TokenBranch }

variant -> { Courier::CancelJourneyResponse::RunIDBranch }

class TokenBranch < Courier::Internal::Type::BaseModel
# @!attribute cancelation_token
#
# @return [String]
required :cancelation_token, String

# @!method initialize(cancelation_token:)
# @param cancelation_token [String]
end

class RunIDBranch < Courier::Internal::Type::BaseModel
# @!attribute run_id
#
# @return [String]
required :run_id, String

# @!attribute status
# The run's resulting status. `CANCELED` when the run was active and we canceled
# it; `PROCESSED` or `ERROR` when the run had already finished and was left
# untouched; `CANCELED` for an already-canceled run.
#
# @return [String]
required :status, String

# @!method initialize(run_id:, status:)
# Some parameter documentations has been truncated, see
# {Courier::Models::CancelJourneyResponse::RunIDBranch} for more details.
#
# @param run_id [String]
#
# @param status [String] The run's resulting status. `CANCELED` when the run was active and we canceled i
end

# @!method self.variants
# @return [Array(Courier::Models::CancelJourneyResponse::TokenBranch, Courier::Models::CancelJourneyResponse::RunIDBranch)]
end
end
end
14 changes: 14 additions & 0 deletions lib/courier/models/journey_cancel_params.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module Courier
module Models
# @see Courier::Resources::Journeys#cancel
class JourneyCancelParams < Courier::Internal::Type::BaseModel
extend Courier::Internal::Type::RequestParameters::Converter
include Courier::Internal::Type::RequestParameters

# @!method initialize(request_options: {})
# @param request_options [Courier::RequestOptions, Hash{Symbol=>Object}]
end
end
end
49 changes: 49 additions & 0 deletions lib/courier/models/journey_experiment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true

module Courier
module Models
class JourneyExperiment < Courier::Internal::Type::BaseModel
# @!attribute bucketing_key
# The value used to deterministically assign a recipient to a variant. Must be
# non-empty with no leading or trailing whitespace.
#
# @return [String]
required :bucketing_key, String, api_name: :bucketingKey

# @!attribute variants
# Between 2 and 10 weighted template variants.
#
# @return [Array<Courier::Models::JourneyExperimentVariant>]
required :variants, -> { Courier::Internal::Type::ArrayOf[Courier::JourneyExperimentVariant] }

# @!attribute id
# Server-authoritative experiment id (prefixed `exp_`). Omit to have the server
# mint one; when supplied it must be a valid `exp_` id.
#
# @return [String, nil]
optional :id, String

# @!attribute name
# Optional, cosmetic display name for the experiment.
#
# @return [String, nil]
optional :name, String

# @!method initialize(bucketing_key:, variants:, id: nil, name: nil)
# Some parameter documentations has been truncated, see
# {Courier::Models::JourneyExperiment} for more details.
#
# A/B experiment config for a send node. The recipient is deterministically
# bucketed by `bucketingKey` and routed to one of the `variants` in proportion to
# its `weight`. Present on a send node INSTEAD OF `message.template`.
#
# @param bucketing_key [String] The value used to deterministically assign a recipient to a variant. Must be non
#
# @param variants [Array<Courier::Models::JourneyExperimentVariant>] Between 2 and 10 weighted template variants.
#
# @param id [String] Server-authoritative experiment id (prefixed `exp_`). Omit to have the server mi
#
# @param name [String] Optional, cosmetic display name for the experiment.
end
end
end
44 changes: 44 additions & 0 deletions lib/courier/models/journey_experiment_variant.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true

module Courier
module Models
class JourneyExperimentVariant < Courier::Internal::Type::BaseModel
# @!attribute id
#
# @return [String]
required :id, String

# @!attribute template_id
# The notification template sent for this variant.
#
# @return [String]
required :template_id, String, api_name: :templateId

# @!attribute weight
# Relative routing weight. Must be non-negative.
#
# @return [Float]
required :weight, Float

# @!attribute name
# Optional, cosmetic display name for the variant.
#
# @return [String, nil]
optional :name, String

# @!method initialize(id:, template_id:, weight:, name: nil)
# A single weighted arm of an experiment. Variant ids must be unique within the
# experiment and the sum of all variant weights must be greater than 0. Weights
# are relative (no sum-to-100 requirement) — routing normalizes them
# proportionally.
#
# @param id [String]
#
# @param template_id [String] The notification template sent for this variant.
#
# @param weight [Float] Relative routing weight. Must be non-negative.
#
# @param name [String] Optional, cosmetic display name for the variant.
end
end
end
2 changes: 1 addition & 1 deletion lib/courier/models/journey_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module JourneyNode
# Trigger fired by a segment event (`identify`, `group`, or `track`).
variant -> { Courier::JourneySegmentTriggerNode }

# Send a notification template to the recipient. Optionally override the recipient address, delay the send, or attach `data`.
# Send to the recipient. A send node sources its content from EXACTLY ONE of `message.template` (a single notification template) or `experiment` (an A/B split across weighted template variants) — supplying both, or neither, is rejected. Optionally override the recipient address, delay the send, or attach `data`.
variant -> { Courier::JourneySendNode }

# Pause the journey run for a fixed `duration`.
Expand Down
Loading