1.39.2
(fix): WebhooksHelper.verifyRequest now parses name=value settings headers when
webhook-signature.algorithm-header sets key-id-parameter/algorithm-parameter
(e.g. Twilio’s X-Twilio-Webhooks-Signature-Settings: key=<id>,algorithm=HMAC_SHA256),
so the key resolver receives the bare key ID instead of key=<id>. Requires IR 67.33.0.
1.39.1
(fix): The generated WebhooksHelper now consumes algorithm-header from api.settings.webhook-signature:
a request-level verifyRequest helper reads the configured signature header first (missing or empty
fails early with “could not run: missing signature header”), then the algorithm-selection header
(e.g. X-Twilio-Webhook-Signature-Settings: <key_id>;HMAC_SHA256) to pick the HMAC algorithm from
the configured wire values and hand the key ID to an application-supplied secret resolver. When the
header is absent the configured default algorithm and the plain secret are used, so legacy
auth-token flows keep working. The lower-level verifySignature is unchanged and still returns
false without throwing.
1.39.0
(fix): Pagination now works when the next cursor, the items, or the has-next-page flag is nested inside the
response (e.g. $response.pagination.nextToken). The pager used to read only the last field name
from the top-level response (response.next_token), which raised NoMethodError. It now follows
the full path (response.pagination.next_token).
(feat): Generated wire tests now cover every example of an endpoint instead of only the first, including
autogenerated error examples (one per error) for endpoints without a user-specified error example.
Error tests assert the typed error raised for the status code (assert_raises) along with its status
code and body. Each test’s X-Test-Id header selects a dedicated WireMock mapping that serves that
example’s response, success mappings use the endpoint’s declared status code, and the test client
disables retries. Set wireTestsFallbackToAutoGeneratedErrorExamples: false to leave out the
autogenerated error examples.
1.38.2
(fix): Models no longer keep an unknown JSON key as an extra field when it matches a declared field
case-insensitively (e.g. VALUE next to value). Previously the extra key was re-emitted after the
declared field, so a case-insensitive, last-wins JSON decoder downstream (such as Go’s encoding/json)
read the extra key’s value instead of the declared field’s. Non-colliding unknown keys are still
preserved and re-emitted. XML-encoded models are unchanged, since XML attribute names are case-sensitive.
1.38.1
(fix): Fix paginated results silently skipping records. Every each/map/to_a/first/any?/count
over a pager (or its pages) now starts again from the first page, reading pages no longer
moves item iteration forward, items are no longer removed from fetched pages as they are read,
and each without a block returns an Enumerator. Manual next_element/next_page loops,
including retrying after a failed page, behave as before. Because each loop starts again,
reading the same pager more than once (or reading both pages and items) requests the pages
again, except a first page kept by load_first_page (or fetchFirstPageOnCall), which every
loop reuses.
1.38.0
(fix): Cursor and offset paginated methods now document what they return. The YARD @return tag and
the reference.md signature name the CursorItemIterator / OffsetItemIterator instead of the
response type, the method docs say which items it yields, that pages gives each page’s full
response, and when the request is sent and API errors are raised. The README pagination example
uses a paginated endpoint even when the default endpoint is not paginated, and shows pages
instead of the nonexistent results method. Iterators gain load_first_page, which sends the
first request immediately so its API error is raised at that call.
1.37.3
(fix): Connection-level failures now raise the SDK’s new Errors::ConnectionError (a subclass of
Errors::ApiError) instead of leaking raw Errno::ECONNREFUSED, Errno::ECONNRESET,
EOFError, SocketError (DNS) or OpenSSL::SSL::SSLError, so rescue Errors::ApiError
catches every failed call as the README documents. The original exception is kept as cause.
Errno::ETIMEDOUT now raises Errors::TimeoutError like the other socket timeouts.
Other SystemCallErrors (e.g. file errors) are not wrapped. Code that rescued the wrapped classes
directly should rescue Errors::ConnectionError instead (or inspect cause). Transport failures are still not retried. The README errors example shows the new class.
1.37.2
(fix): Parsing an XML (TwiML) element without a text property keeps the text before its first child in the
ordered content, so Gather.from_xml('<Gather>Press a key, then <Say>one</Say></Gather>') round-trips
instead of dropping Press a key, then . Types with a text property (e.g. Say) are unchanged: that
text is still the property’s value.
1.37.1
(fix): Generate float and double fields and parameters as Ruby Float instead of Integer.
Decimal values (e.g. a balance of 100.57) previously lost their fractional part when a
response was decoded or a request was sent. Integer types stay Integer.
Generated wire tests now also assert that numbers in request bodies reach the wire unchanged
and that numbers in mocked responses decode unchanged.
Integer and Float map keys nested in models now decode as numbers instead of staying symbols.
1.37.0
(feat): XML (TwiML) models can now carry XML comments. comment(text) adds <!--text--> inside the element at
its position in the ordered content (interleaved with add_text segments and child elements), while
comment_before(text) / comment_after(text) render a comment immediately before or after the element
itself (as a sibling in its parent, or around the root element after the XML declaration). Comments in
parsed documents are preserved by from_xml and round-trip through to_xml; Element#add_comment and
the new Internal::Xml::Comment node expose the same for untyped elements.
1.36.0
(feat): Generate a unit test file per XML-encoded (TwiML) type alongside the models, covering
fromXml/toXml round trips, escaping, unknown attributes/children, open enum passthrough,
child ordering, and rejection of malformed XML, wrong root elements and DOCTYPE declarations.
1.35.2
(fix): List-valued XML (TwiML) attributes and text accept a space-separated String or a single
value (including a Symbol) in addition to an Array, matching the legacy call style:
response.gather(input: "speech dtmf") and dial(status_callback_event: :answered) no
longer raise NoMethodError.
1.35.1
(fix): Fluent XML (TwiML) child methods accept the text content as a keyword as well as positionally,
matching the legacy call style: response.say(message: "x"), response.dial(number: "+1555") and
response.message(body: "hi") now emit the text instead of silently dropping it. Passing the text
both positionally and as a keyword raises ArgumentError.
1.35.0
(feat): XML (TwiML) types support the legacy twilio-ruby building style: constructors and fluent child methods yield the
new element to a block (VoiceResponse.new { |r| r.say("hi") }, r.gather { |g| g.say("one") }), and
add_child also accepts an element name with text and attributes (r.add_child("Custom", "v", a: "1")).
1.34.2
(fix): Enum-typed attributes and text on XML (TwiML) types are open on the wire: from_xml keeps a value the enum does
not declare (e.g. a voice added after the SDK was generated) instead of raising, and it round-trips through
to_xml. This matches how the same enums already behave in JSON.
1.34.1
(fix): Endpoints whose request body is an array, set, map, primitive, enum, optional/nullable object, or an alias of
one of these now send the body argument itself (e.g. [{"name":"Monstera"}]) instead of wrapping it with the
other keyword arguments (e.g. {"request": [...]}). This also applies to such bodies on endpoints with headers
or query parameters, which no longer leak into the body. Objects inside these bodies (optional/nullable objects,
list and set items, and map values) are serialized through their model so fields use their wire names, sets are
sent as JSON arrays, and an omitted optional body is still sent without a body.
1.34.0
(feat): Add opt-in userAgentOnly config. When enabled, generated clients send the User-Agent
header (including the structured form from includePlatformHeaders) but omit the
X-Fern-Language, X-Fern-SDK-Name, and X-Fern-SDK-Version headers. Disabled by default,
so existing generated output is unchanged. omitFernHeaders still takes precedence and drops
the User-Agent too.
1.33.0
(feat): The generated WebhooksHelper HMAC verifier now accepts a per-call algorithm override via an optional algorithm parameter on verifySignature,
one of sha1, sha256, sha384 or sha512. When omitted, the algorithm configured in
webhook-signature is used, so existing callers are unchanged. This lets one endpoint verify both
legacy HMAC-SHA1 (auth-token) and HMAC-SHA256 (shared-key) signed webhooks.
The verifier also logs a warning distinguishing an early failure (missing signature header) from a
failed verification (signature mismatch); it still returns false and never throws.
1.32.0
(feat): XML (TwiML) types keep text segments, typed child models and raw Element children in a single
ordered content list, so to_xml emits them in the order they were added
(response.say("a"); response.add_child(Element.new("Custom")); response.say("b") yields
<Say>a</Say><Custom/><Say>b</Say>) and from_xml preserves document order, including the
position of unknown elements. Adds add_text(String) to XML types and Element for mixed content
such as <Say>Hi <break strength="weak"/> world</Say>. Typed child properties and additional
children remain available and are reconciled into the content order on serialization.
1.31.1
(fix): XML-encoded (TwiML) types now include the <?xml version="1.0" encoding="UTF-8"?>
declaration by default when serialized to XML; pass the declaration flag as false
to omit it. Nested child elements and raw XmlElements are still written without it.