telnyx 3.0.6 → 3.1.0.pre.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 119256278a1a98976546bc78f69fbc4f14f08deb8dea0f492833e1e7fc90d5f8
4
- data.tar.gz: 64c553ce027e5e14e79d93f635b32d5032aacfcf16c951dc6b8c6dc24f1a3a1c
3
+ metadata.gz: 84d4e73bfaa1a623aa43940a4f86155b938703fc3d7cf70ffa76b97569c70c35
4
+ data.tar.gz: e29d1cc3c049e1d38f2b1c49e09f365f55abac868a5684805db0fe6d72294b36
5
5
  SHA512:
6
- metadata.gz: 789ca83329b14511166e268d8a1549cd4aefb92d297b134df98761ef0b38fcb1877c9727777c827f84a896e1a37138799b647b2d7dcdc3bef951bc6551c207d0
7
- data.tar.gz: 9d71107f074a2bd0c8e33f9d1645545a0334931fce33e436bc5e06dc90bdda7bb6c8ec6364eb82f9f0a8de8203a7bee86e201b8b137f4eafbfcd8890e2146795
6
+ metadata.gz: c40236177980cbbc70d98075f11dfceb67661a8bc4a8c8660c03b961aadc2375c79f29f637952f53e1452d549c42e3d722bde7e4a7acfd7932e5a57f7ab0800b
7
+ data.tar.gz: 8e0c010b5699e9fb409d32d2eeee5c759c36391e4360f83e834c1f375b86c1ec79fee48cf6a0ea9734f758f05103f1339ea5cb185de4a647e9eece2dd26d4dda
@@ -0,0 +1,39 @@
1
+ # Publishes the gem to rubygems.org when a GitHub release is published on the
2
+ # legacy-3.x line (pre-releases included). It can also be run manually to
3
+ # re-publish in case it failed:
4
+ # https://www.github.com/team-telnyx/telnyx-ruby/actions/workflows/publish-gem.yml
5
+ #
6
+ # Same shape as publish-gem.yml on master: RubyGems trusted publishing (OIDC),
7
+ # no API-key secret. The release tag must equal "v#{Telnyx::VERSION}".
8
+ name: Publish Gem
9
+ on:
10
+ workflow_dispatch:
11
+
12
+ release:
13
+ types: [published]
14
+
15
+ jobs:
16
+ publish:
17
+ name: publish
18
+ # Match master: the pinned setup-ruby does not support ubuntu-latest's 26.04 image.
19
+ runs-on: ubuntu-24.04
20
+ permissions:
21
+ id-token: write
22
+ contents: read
23
+
24
+ steps:
25
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
26
+ - name: Set up Ruby
27
+ uses: ruby/setup-ruby@c4e5b1316158f92e3d49443a9d58b31d25ac0f8f # v1.306.0
28
+ with:
29
+ ruby-version: "3.2"
30
+ bundler-cache: false
31
+
32
+ - name: Configure RubyGems Credentials
33
+ uses: rubygems/configure-rubygems-credentials@6861877652452567c1a007a50badad3d316fc9ba
34
+
35
+ - name: Publish to RubyGems.org
36
+ env:
37
+ RELEASE_TAG: ${{ github.event.release.tag_name }}
38
+ run: |
39
+ bash ./bin/publish-gem
data/CHANGELOG.md CHANGED
@@ -1,2 +1,7 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.1.0.pre.1 - 2026-10-29
4
+ Prerelease of 3.1.0. Not resolved by `~> 3.0`; opt in with `gem "telnyx", "3.1.0.pre.1"`.
5
+ * Add `Telnyx::AccessToken` and `TelephonyCredential#to_jwt`: mint a WebRTC login token locally from the credential's `token_material`, with no request to Telnyx per token.
6
+ * Add `TelephonyCredential#fetch_token_material`, backed by `GET /v2/telephony_credentials/:id/token_material` when the object did not come from `create`.
7
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.6
1
+ 3.1.0.pre.1
data/bin/publish-gem ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+ # Build telnyx.gemspec and push the result to rubygems.org.
3
+ # When run from a GitHub release, refuse to publish unless the release tag is
4
+ # exactly "v<Telnyx::VERSION>", so a mistagged release cannot ship the wrong version.
5
+
6
+ set -Eeuo pipefail
7
+
8
+ cd -- "$(dirname -- "$0")/.."
9
+
10
+ version=$(ruby -Ilib -e 'require "telnyx/version"; print Telnyx::VERSION')
11
+
12
+ if [ -n "${RELEASE_TAG:-}" ] && [ "$RELEASE_TAG" != "v$version" ]; then
13
+ echo "release tag '$RELEASE_TAG' does not match lib/telnyx/version.rb ('v$version')" >&2
14
+ exit 1
15
+ fi
16
+
17
+ find . -maxdepth 1 -type f -name "*.gem" -delete
18
+ gem build telnyx.gemspec
19
+ gem push "telnyx-$version.gem"
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "base64"
4
+ require "json"
5
+ require "openssl"
6
+
7
+ module Telnyx
8
+ # Mints a WebRTC login token for a telephony credential locally, with no
9
+ # request to Telnyx.
10
+ #
11
+ # The token has the same shape as the one `POST /v2/telephony_credentials/:id/token`
12
+ # returns, so it is used the same way: pass it to the WebRTC SDK as
13
+ # `login_token`. Telnyx verifies it on login.
14
+ #
15
+ # The signing material comes from the credential: `token_material` is in the
16
+ # response of `POST /v2/telephony_credentials` and of
17
+ # `GET /v2/telephony_credentials/:id/token_material`. It is as sensitive as
18
+ # the SIP password, so keep it on the server; never ship it to a browser.
19
+ #
20
+ # credential = Telnyx::TelephonyCredential.create(connection_id: "123")
21
+ # credential.to_jwt # 1 hour
22
+ # credential.to_jwt(ttl: 600) # 10 minutes
23
+ #
24
+ # Or from stored values, without a TelephonyCredential object:
25
+ #
26
+ # Telnyx::AccessToken.new(
27
+ # credential_id: "...", user_id: "...", identity: "gencred...",
28
+ # expires_at: "2027-01-01T00:00:00Z",
29
+ # token_material: { kid: "v1", tel_token: "...", signing_secret: "..." }
30
+ # ).to_jwt
31
+ class AccessToken
32
+ DEFAULT_TTL = 3600
33
+ MAX_TTL = 86_400
34
+ CONTENT_TYPE = "telnyx-webrtc;v=1"
35
+ ALGORITHM = "HS256"
36
+
37
+ MATERIAL_FIELDS = %i[kid tel_token signing_secret].freeze
38
+
39
+ attr_reader :credential_id, :user_id, :identity, :expires_at, :ttl
40
+
41
+ # @param credential_id [String] the telephony credential `id`
42
+ # @param user_id [String] the credential's `user_id`
43
+ # @param identity [String] the credential's `sip_username`
44
+ # @param expires_at [String, nil] the credential's `expires_at`, as the API returns it
45
+ # @param token_material [Hash, TelnyxObject] `kid`, `tel_token`, `signing_secret`
46
+ # @param ttl [Integer] token lifetime in seconds, 1..86400; default one hour
47
+ def initialize(credential_id:, user_id:, identity:, token_material:, expires_at: nil, ttl: DEFAULT_TTL)
48
+ @credential_id = required(credential_id, "credential_id")
49
+ @user_id = required(user_id, "user_id")
50
+ @identity = required(identity, "identity")
51
+ @expires_at = expires_at
52
+ @material = normalize_material(token_material)
53
+ @ttl = ttl.to_i.clamp(1, MAX_TTL)
54
+ end
55
+
56
+ # The signed token, valid from now for `ttl` seconds.
57
+ def to_jwt(now: Time.now)
58
+ iat = now.to_i
59
+ header = {
60
+ alg: ALGORITHM,
61
+ typ: "JWT",
62
+ cty: CONTENT_TYPE,
63
+ kid: @material[:kid],
64
+ }
65
+ payload = {
66
+ sub: credential_id,
67
+ user_id: user_id,
68
+ identity: identity,
69
+ cred_exp: expires_at,
70
+ tel_token: @material[:tel_token],
71
+ iat: iat,
72
+ nbf: iat,
73
+ exp: iat + ttl,
74
+ jti: "#{credential_id}-#{iat}",
75
+ }
76
+
77
+ signing_input = "#{encode(JSON.generate(header))}.#{encode(JSON.generate(payload))}"
78
+ "#{signing_input}.#{encode(self.class.sign(signing_input, @material[:signing_secret]))}"
79
+ end
80
+
81
+ alias to_s to_jwt
82
+
83
+ # Decodes a token minted by this class and checks its signature against
84
+ # `signing_secret`. Returns the claims as a Hash with string keys. Meant for
85
+ # tests and debugging: Telnyx does the real verification on login.
86
+ def self.decode(jwt, signing_secret:)
87
+ head, body, sig = jwt.to_s.split(".")
88
+ raise ArgumentError, "not a JWT" if sig.nil?
89
+
90
+ expected = sign("#{head}.#{body}", signing_secret)
91
+ given = Base64.urlsafe_decode64(sig)
92
+ valid = given.bytesize == expected.bytesize && OpenSSL.fixed_length_secure_compare(given, expected)
93
+ raise SignatureVerificationError.new("Signature is invalid and does not match the payload", sig) unless valid
94
+
95
+ JSON.parse(Base64.urlsafe_decode64(body))
96
+ end
97
+
98
+ def self.sign(signing_input, signing_secret)
99
+ key = Base64.urlsafe_decode64(signing_secret)
100
+ OpenSSL::HMAC.digest("SHA256", key, signing_input)
101
+ end
102
+
103
+ private
104
+
105
+ def encode(bytes)
106
+ Base64.urlsafe_encode64(bytes, padding: false)
107
+ end
108
+
109
+ def required(value, name)
110
+ raise ArgumentError, "#{name} is required to mint a token" if value.nil? || value.to_s.empty?
111
+
112
+ value.to_s
113
+ end
114
+
115
+ def normalize_material(material)
116
+ hash = material.respond_to?(:to_hash) ? material.to_hash : material
117
+ raise ArgumentError, "token_material is required to mint a token" unless hash.is_a?(Hash)
118
+
119
+ MATERIAL_FIELDS.each_with_object({}) do |field, acc|
120
+ value = hash[field] || hash[field.to_s]
121
+ raise ArgumentError, "token_material.#{field} is missing" if value.nil? || value.to_s.empty?
122
+
123
+ acc[field] = value.to_s
124
+ end
125
+ end
126
+ end
127
+ end
@@ -23,6 +23,37 @@ module Telnyx
23
23
  Util.convert_to_telnyx_object(resp.data, opts)
24
24
  end
25
25
 
26
+ # A WebRTC login token for this credential, minted locally with no
27
+ # request to Telnyx. Same use as `create_token`: hand it to the WebRTC
28
+ # SDK as `login_token`.
29
+ #
30
+ # The signing material (`kid`, `tel_token`, `signing_secret`) is read from
31
+ # `token_material`, present on objects that came from `create`; an object
32
+ # from `retrieve` or `list` fetches it once (see `fetch_token_material`).
33
+ # Pass `token_material:` to mint from values stored earlier, with no
34
+ # request at all.
35
+ #
36
+ # `ttl` is the token lifetime in seconds, 1..86400, default one hour.
37
+ def to_jwt(ttl: AccessToken::DEFAULT_TTL, token_material: nil, opts: {})
38
+ AccessToken.new(
39
+ credential_id: id,
40
+ user_id: self[:user_id],
41
+ identity: self[:sip_username],
42
+ expires_at: self[:expires_at],
43
+ token_material: token_material || self[:token_material] || fetch_token_material(opts),
44
+ ttl: ttl
45
+ ).to_jwt
46
+ end
47
+
48
+ # `GET /v2/telephony_credentials/:id/token_material`, fetched once and
49
+ # kept on this object. Treat the result like the SIP password.
50
+ def fetch_token_material(opts = {})
51
+ @fetch_token_material ||= begin
52
+ resp, opts = request(:get, "#{resource_url}/token_material", {}, opts)
53
+ Util.convert_to_telnyx_object(resp.data[:data] || resp.data, opts)
54
+ end
55
+ end
56
+
26
57
  # Additional action to list tags
27
58
  def self.tags(params = {}, opts = {})
28
59
  opts = Util.normalize_opts(opts)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Telnyx
4
- VERSION = "3.0.6".freeze
4
+ VERSION = "3.1.0.pre.1".freeze
5
5
  end
data/lib/telnyx.rb CHANGED
@@ -38,6 +38,7 @@ require "telnyx/list_object"
38
38
  require "telnyx/api_resource"
39
39
  require "telnyx/singleton_api_resource"
40
40
  require "telnyx/webhook"
41
+ require "telnyx/access_token"
41
42
 
42
43
  require "telnyx/address"
43
44
  require "telnyx/alphanumeric_sender_id"
data/telnyx.gemspec CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
25
25
  s.add_dependency("faraday", ">= 2.5.0")
26
26
  s.add_dependency("faraday-multipart", "~> 1.0.4")
27
27
  s.add_dependency("faraday-net_http_persistent", "~> 2.1.0")
28
+ s.add_dependency("faraday-retry", "~> 2.0")
28
29
  s.add_dependency("net-http-persistent", ">= 3.0", "< 5.0")
29
30
  s.add_dependency("ed25519", "~> 1")
30
31
 
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../test_helper"
4
+
5
+ module Telnyx
6
+ class AccessTokenTest < Test::Unit::TestCase
7
+ SECRET = Base64.urlsafe_encode64(OpenSSL::Random.random_bytes(32), padding: false)
8
+ MATERIAL = {
9
+ kid: "v1",
10
+ tel_token: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
11
+ signing_secret: SECRET,
12
+ }.freeze
13
+
14
+ def token(**overrides)
15
+ AccessToken.new(
16
+ **{
17
+ credential_id: "c90a3e6d-8c8c-4c5a-a8b1-6b8d0f2f8a31",
18
+ user_id: "191d61ea-1cb5-445a-8dd1-384f45e7cb7a",
19
+ identity: "gencred1234",
20
+ expires_at: "2027-01-01T00:00:00Z",
21
+ token_material: MATERIAL,
22
+ }.merge(overrides)
23
+ )
24
+ end
25
+
26
+ should "mint a three part HS256 JWT with the Telnyx content type" do
27
+ jwt = token.to_jwt
28
+ head, body, sig = jwt.split(".")
29
+ assert_equal 3, jwt.split(".").size
30
+ assert_nil jwt[%r{[+/=]}], "token must be base64url without padding"
31
+
32
+ header = JSON.parse(Base64.urlsafe_decode64(head))
33
+ assert_equal({ "alg" => "HS256", "typ" => "JWT", "cty" => "telnyx-webrtc;v=1", "kid" => "v1" }, header)
34
+
35
+ expected = OpenSSL::HMAC.digest("SHA256", Base64.urlsafe_decode64(SECRET), "#{head}.#{body}")
36
+ assert_equal Base64.urlsafe_encode64(expected, padding: false), sig
37
+ end
38
+
39
+ should "carry the credential and the tel_token in the claims" do
40
+ now = Time.at(1_760_000_000)
41
+ claims = AccessToken.decode(token.to_jwt(now: now), signing_secret: SECRET)
42
+
43
+ assert_equal "c90a3e6d-8c8c-4c5a-a8b1-6b8d0f2f8a31", claims["sub"]
44
+ assert_equal "191d61ea-1cb5-445a-8dd1-384f45e7cb7a", claims["user_id"]
45
+ assert_equal "gencred1234", claims["identity"]
46
+ assert_equal "2027-01-01T00:00:00Z", claims["cred_exp"]
47
+ assert_equal MATERIAL[:tel_token], claims["tel_token"]
48
+ assert_equal now.to_i, claims["iat"]
49
+ assert_equal now.to_i, claims["nbf"]
50
+ assert_equal now.to_i + 3600, claims["exp"]
51
+ assert_equal "c90a3e6d-8c8c-4c5a-a8b1-6b8d0f2f8a31-#{now.to_i}", claims["jti"]
52
+ assert_kind_of Integer, claims["exp"]
53
+ end
54
+
55
+ should "default to one hour and cap the ttl at 24 hours" do
56
+ now = Time.at(1_760_000_000)
57
+ assert_equal now.to_i + 3600, AccessToken.decode(token.to_jwt(now: now), signing_secret: SECRET)["exp"]
58
+ assert_equal now.to_i + 600, AccessToken.decode(token(ttl: 600).to_jwt(now: now), signing_secret: SECRET)["exp"]
59
+ assert_equal now.to_i + 86_400, AccessToken.decode(token(ttl: 10**6).to_jwt(now: now), signing_secret: SECRET)["exp"]
60
+ assert_equal now.to_i + 1, AccessToken.decode(token(ttl: 0).to_jwt(now: now), signing_secret: SECRET)["exp"]
61
+ end
62
+
63
+ should "accept token_material with string keys or as a TelnyxObject" do
64
+ strings = MATERIAL.transform_keys(&:to_s)
65
+ object = TelnyxObject.construct_from(MATERIAL)
66
+ a = token(token_material: strings).to_jwt(now: Time.at(0))
67
+ b = token(token_material: object).to_jwt(now: Time.at(0))
68
+ assert_equal a, b
69
+ end
70
+
71
+ should "refuse to mint without the material or the identity" do
72
+ assert_raise(ArgumentError) { token(token_material: nil) }
73
+ assert_raise(ArgumentError) { token(token_material: MATERIAL.reject { |k, _| k == :signing_secret }) }
74
+ assert_raise(ArgumentError) { token(token_material: MATERIAL.merge(tel_token: "")) }
75
+ assert_raise(ArgumentError) { token(identity: nil) }
76
+ assert_raise(ArgumentError) { token(user_id: "") }
77
+ end
78
+
79
+ should "decode rejects a token signed with another secret" do
80
+ other = Base64.urlsafe_encode64(OpenSSL::Random.random_bytes(32), padding: false)
81
+ jwt = token.to_jwt
82
+ assert_raise(SignatureVerificationError) { AccessToken.decode(jwt, signing_secret: other) }
83
+
84
+ tampered = jwt.sub(/\.[^.]+\./, ".#{Base64.urlsafe_encode64('{"sub":"x"}', padding: false)}.")
85
+ assert_raise(SignatureVerificationError) { AccessToken.decode(tampered, signing_secret: SECRET) }
86
+ end
87
+ end
88
+ end
@@ -61,6 +61,65 @@ module Telnyx
61
61
  assert_requested :get, "#{Telnyx.api_base}/v2/telephony_credentials/tags"
62
62
  end
63
63
  end
64
+
65
+ CREDENTIAL = {
66
+ record_type: "credential",
67
+ id: "c90a3e6d-8c8c-4c5a-a8b1-6b8d0f2f8a31",
68
+ user_id: "191d61ea-1cb5-445a-8dd1-384f45e7cb7a",
69
+ sip_username: "gencred1234",
70
+ sip_password: "secret",
71
+ expires_at: "2027-01-01T00:00:00Z",
72
+ }.freeze
73
+ MATERIAL = {
74
+ kid: "v1",
75
+ tel_token: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
76
+ signing_secret: Base64.urlsafe_encode64("k" * 32, padding: false),
77
+ }.freeze
78
+ URL = "#{PROXY_BASE_URL}/v2/telephony_credentials/#{CREDENTIAL[:id]}".freeze
79
+
80
+ context "local token minting" do
81
+ should "mint from the create response without another request" do
82
+ stub_request(:post, "#{PROXY_BASE_URL}/v2/telephony_credentials")
83
+ .to_return(body: JSON.generate(data: CREDENTIAL.merge(token_material: MATERIAL)))
84
+
85
+ credential = TelephonyCredential.create(connection_id: "1234567890")
86
+ jwt = credential.to_jwt(ttl: 600)
87
+
88
+ claims = AccessToken.decode(jwt, signing_secret: MATERIAL[:signing_secret])
89
+ assert_equal CREDENTIAL[:id], claims["sub"]
90
+ assert_equal CREDENTIAL[:sip_username], claims["identity"]
91
+ assert_equal MATERIAL[:tel_token], claims["tel_token"]
92
+ assert_equal claims["iat"] + 600, claims["exp"]
93
+ assert_not_requested :get, "#{URL}/token_material"
94
+ end
95
+
96
+ should "fetch token_material once for a retrieved credential" do
97
+ stub_request(:get, URL).to_return(body: JSON.generate(data: CREDENTIAL))
98
+ stub_request(:get, "#{URL}/token_material").to_return(body: JSON.generate(data: MATERIAL))
99
+
100
+ credential = TelephonyCredential.retrieve(CREDENTIAL[:id])
101
+ first = credential.to_jwt(ttl: 60)
102
+ second = credential.to_jwt(ttl: 60)
103
+
104
+ assert_requested :get, "#{URL}/token_material", times: 1
105
+ assert_equal MATERIAL[:kid], credential.fetch_token_material[:kid]
106
+ %w[sub user_id identity tel_token].each do |claim|
107
+ assert_equal AccessToken.decode(first, signing_secret: MATERIAL[:signing_secret])[claim],
108
+ AccessToken.decode(second, signing_secret: MATERIAL[:signing_secret])[claim]
109
+ end
110
+ end
111
+
112
+ should "mint from material the caller stored, with no request at all" do
113
+ stub_request(:get, URL).to_return(body: JSON.generate(data: CREDENTIAL))
114
+ credential = TelephonyCredential.retrieve(CREDENTIAL[:id])
115
+
116
+ jwt = credential.to_jwt(token_material: MATERIAL.transform_keys(&:to_s))
117
+
118
+ assert_not_requested :get, "#{URL}/token_material"
119
+ assert_equal CREDENTIAL[:user_id], AccessToken.decode(jwt, signing_secret: MATERIAL[:signing_secret])["user_id"]
120
+ end
121
+ end
122
+
64
123
  # Issue with response(RESPONSE SCHEMA: text/plain)
65
124
  # should "create telephony credential token" do
66
125
  # telephony_credential = TelephonyCredential.retrieve("id")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: telnyx
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.6
4
+ version: 3.1.0.pre.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Telnyx
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-13 00:00:00.000000000 Z
11
+ date: 2026-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 2.1.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: faraday-retry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: net-http-persistent
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -90,13 +104,14 @@ description: Telnyx enables anyone to deliver enterprise-grade real-time communi
90
104
  over the internet. See https://telnyx.com for details.
91
105
  email: support@telnyx.com
92
106
  executables:
107
+ - publish-gem
93
108
  - telnyx-console
94
109
  extensions: []
95
110
  extra_rdoc_files: []
96
111
  files:
97
112
  - ".github/ISSUE_TEMPLATE.md"
98
113
  - ".github/scripts/before_install.sh"
99
- - ".github/workflows/publish-gem-on-release.yml"
114
+ - ".github/workflows/publish-gem.yml"
100
115
  - ".github/workflows/ruby.yml"
101
116
  - ".github/workflows/tweet-release.yml"
102
117
  - ".gitignore"
@@ -112,6 +127,7 @@ files:
112
127
  - Rakefile
113
128
  - Spec3.json
114
129
  - VERSION
130
+ - bin/publish-gem
115
131
  - bin/telnyx-console
116
132
  - examples/fax/Gemfile
117
133
  - examples/fax/config.yaml
@@ -121,6 +137,7 @@ files:
121
137
  - lib/telnyx.rb
122
138
  - lib/telnyx/access_control_ip.rb
123
139
  - lib/telnyx/access_ip_range.rb
140
+ - lib/telnyx/access_token.rb
124
141
  - lib/telnyx/address.rb
125
142
  - lib/telnyx/alphanumeric_sender_id.rb
126
143
  - lib/telnyx/api_operations/create.rb
@@ -261,6 +278,7 @@ files:
261
278
  - telnyx.gemspec
262
279
  - test/api_stub_helpers.rb
263
280
  - test/openapi/README.md
281
+ - test/telnyx/access_token_test.rb
264
282
  - test/telnyx/address_test.rb
265
283
  - test/telnyx/alphanumeric_sender_id_test.rb
266
284
  - test/telnyx/api_operations_test.rb
@@ -391,17 +409,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
391
409
  version: 3.0.0
392
410
  required_rubygems_version: !ruby/object:Gem::Requirement
393
411
  requirements:
394
- - - ">="
412
+ - - ">"
395
413
  - !ruby/object:Gem::Version
396
- version: '0'
414
+ version: 1.3.1
397
415
  requirements: []
398
- rubygems_version: 3.2.15
416
+ rubygems_version: 3.4.19
399
417
  signing_key:
400
418
  specification_version: 4
401
419
  summary: Ruby bindings for the Telnyx API
402
420
  test_files:
403
421
  - test/api_stub_helpers.rb
404
422
  - test/openapi/README.md
423
+ - test/telnyx/access_token_test.rb
405
424
  - test/telnyx/address_test.rb
406
425
  - test/telnyx/alphanumeric_sender_id_test.rb
407
426
  - test/telnyx/api_operations_test.rb
@@ -1,53 +0,0 @@
1
- on:
2
- release:
3
- types: [released]
4
-
5
- jobs:
6
- #Deprecating, incoming replacement for self-hosted mock service
7
- #test:
8
- #env:
9
- # TELNYX_MOCK_OPEN_API_URI: https://raw.githubusercontent.com/team-telnyx/openapi/master/openapi/spec3.json
10
- #runs-on: ubuntu-latest
11
- #strategy:
12
- # matrix:
13
- # ruby: [ '3.0', '3.1', '3.2' ]
14
- #steps:
15
- #- uses: actions/checkout@v4
16
- #- name: Set up Ruby
17
- # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
18
- # change this to (see https://github.com/ruby/setup-ruby#versioning):
19
- # uses: ruby/setup-ruby@v1
20
- # uses: ruby/setup-ruby@v1
21
- # with:
22
- # ruby-version: ${{ matrix.ruby }}
23
- #- name: Run Setup Script to install prism mock
24
- # run: source ./.github/scripts/before_install.sh
25
- # shell: bash
26
- #- name: Install dependencies
27
- # run: bundle install
28
- #- name: Run tests
29
- # run: bundle exec rake
30
-
31
- build_and_publish_gem:
32
- name: Build + Publish Gem
33
- runs-on: ubuntu-latest
34
- permissions:
35
- packages: write
36
- contents: read
37
- steps:
38
- - uses: actions/checkout@v2
39
- - name: Set up Ruby 3.0
40
- uses: ruby/setup-ruby@477b21f02be01bcb8030d50f37cfec92bfa615b6
41
- with:
42
- ruby-version: 3.0
43
- - run: bundle install
44
- - name: Publish to RubyGems
45
- run: |
46
- mkdir -p $HOME/.gem
47
- touch $HOME/.gem/credentials
48
- chmod 0600 $HOME/.gem/credentials
49
- printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
50
- gem build *.gemspec
51
- gem push *.gem
52
- env:
53
- GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_API_KEY}}"