waha-ruby 0.1.1 → 0.2.0

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: b6143fc09b5ea2bfb45b55cba490a5b2f4b2527800991e8207f9f838c363998f
4
- data.tar.gz: e740e63e91ffadba7ee5919d36722f973847c86818c244753535f98dca9cd70d
3
+ metadata.gz: 36cfca6cd9f43620fcc84fe54c821262683471a4a56c74f8f757e07044e3cc46
4
+ data.tar.gz: f393af7a3285bfc18fa6684c943d6aae31046c283447f960ba37e571c99dce6f
5
5
  SHA512:
6
- metadata.gz: 63f59ffd2b58f82e9ca8e925b5e8c07958e8e508f12a1df49c73cc9ffaf3311b7be6546632d988b987ac35cd11169bfe9effd2896642763a371501a6e04a2462
7
- data.tar.gz: 4dee276f3bbfbb301a9f4beaa499c92e0bbba61ada941acef1487bcbe041539f21746f071679b8359044bb11d97a8761905ff06d37cc5b64cf3353b8001f39ec
6
+ metadata.gz: 621b3f6e2a63cf06ff933cad60c07e09dafd9b6d3eea473d718604a6ff8f7f580bea029e21e3abc074996b9804141b9c4f16d2afdef2869a38badd12d6985050
7
+ data.tar.gz: 0b3f6c7db0e5c4ec5222021d445334d45bf53af6fbb2b766555633ccdfd560cd15ca167a87287b8ba3e2dae3ddb405afa37181f4848c80c8817fcd2a13eb5900
data/CHANGELOG.md CHANGED
@@ -8,6 +8,39 @@ and this project adheres to
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [0.2.0] - 2026-09-16
12
+
13
+ ### Added
14
+
15
+ - `Waha.configure`, `Waha.configuration`, `Waha.configured?`, and
16
+ `Waha.client(session:, **overrides)` for opt-in process-wide defaults.
17
+ Every call builds a fresh client; instances are never cached.
18
+ - `Waha.valid_chat_id?` for `@c.us`, `@g.us`, and `@lid` ids, plus
19
+ `Waha.group_chat_id` to append the `@g.us` suffix when absent.
20
+ - `Waha::Resources::Chats#list` for `GET /api/{session}/chats`.
21
+ - `Waha::Resources::Groups` (`client.groups`) with `list` and `get`.
22
+ - `Waha::Resources::Sessions#update` (`PUT /api/sessions/{name}`).
23
+ - `Waha::Resources::Sessions#qr_data_url`, returning the QR PNG as a
24
+ browser-ready `data:image/png;base64,` URL.
25
+ - `Waha::Resources::Sessions#ready?`, a WORKING-status predicate.
26
+ - `Waha::ServerError` (>= 500) and `Waha::RateLimitError` (429), plus
27
+ `Waha::Error#retryable?` covering transport failures, 408, and 429.
28
+ - Opt-in Rails adapter `Waha::Rails::SessionState` (aliased as
29
+ `Waha::SessionState`), which memoizes session readiness in `Rails.cache`.
30
+
31
+ ### Changed
32
+
33
+ - `Waha::Resources::Messages#send_image`, `#send_file`, and `#send_voice`
34
+ now accept `mimetype: nil`: the MIME type is read from the data URL prefix
35
+ when omitted, and left out of the payload for remote URLs so WAHA can
36
+ detect it.
37
+ - Text, media, seen, and typing requests accept both `200` and `201`
38
+ responses across WAHA engines.
39
+ - `Waha::Resources::Sessions#qr` treats `format: "image"` as binary, not JSON.
40
+ - `Waha::Client` exposes `session`.
41
+
42
+ ## [0.1.1] - 2026-09-09
43
+
11
44
  ### Fixed
12
45
 
13
46
  - `Waha::Webhook.verify!` fails closed when the secret is nil, empty, or
@@ -44,5 +77,7 @@ and this project adheres to
44
77
  install generator for the `waha.rb` initializer.
45
78
  - Typed `Waha::Error` (operation, status, bounded redacted details) with
46
79
  provider payload redaction.
47
- [Unreleased]: https://github.com/develoz-com/waha-ruby/compare/v0.1.0...HEAD
80
+ [Unreleased]: https://github.com/develoz-com/waha-ruby/compare/v0.2.0...HEAD
81
+ [0.2.0]: https://github.com/develoz-com/waha-ruby/compare/v0.1.1...v0.2.0
82
+ [0.1.1]: https://github.com/develoz-com/waha-ruby/compare/v0.1.0...v0.1.1
48
83
  [0.1.0]: https://github.com/develoz-com/waha-ruby/releases/tag/v0.1.0
data/README.md CHANGED
@@ -39,6 +39,21 @@ client.messages.send_text(chat_id: "5511999999999@c.us", text: "Olá")
39
39
 
40
40
  Every request uses the client's default session unless a resource method accepts an explicit `session:` override. Keep credentials in environment variables or a secret manager; do not commit them.
41
41
 
42
+ Applications that prefer process-wide defaults can configure the module once and build a fresh client per call:
43
+
44
+ ```ruby
45
+ Waha.configure do |config|
46
+ config.base_url = ENV.fetch("WAHA_BASE_URL")
47
+ config.api_key = ENV["WAHA_API_KEY"]
48
+ config.session = ENV.fetch("WAHA_SESSION", "default")
49
+ end
50
+
51
+ Waha.configured? # => true
52
+ Waha.client(session: "default") # a new Waha::Client, never cached
53
+ ```
54
+
55
+ `Waha.client` never caches instances, so per-call session overrides cannot leak across callers.
56
+
42
57
  ## API guide
43
58
 
44
59
  The complete v0.1 resource map, argument conventions, raw return shapes, file payloads, errors, GOWS helpers, webhook verification, and Rails integration are in [docs/api.md](docs/api.md). For setup and secret handling, see [docs/installation.md](docs/installation.md).
data/lib/waha/client.rb CHANGED
@@ -6,6 +6,7 @@ module Waha
6
6
  sessions: Resources::Sessions,
7
7
  messages: Resources::Messages,
8
8
  chats: Resources::Chats,
9
+ groups: Resources::Groups,
9
10
  contacts: Resources::Contacts,
10
11
  presence: Resources::Presence,
11
12
  webhooks: Resources::Webhooks,
@@ -19,6 +20,8 @@ module Waha
19
20
  @resources = {}
20
21
  end
21
22
 
23
+ attr_reader :session
24
+
22
25
  RESOURCES.each do |name, resource_class|
23
26
  define_method(name) do
24
27
  @resources[name] ||= build_resource(name, resource_class)
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Waha
4
+ DEFAULT_TIMEOUT = 30
5
+ DEFAULT_SESSION = "default"
6
+
7
+ # Process-wide defaults for Waha.client. Rails applications can set these in
8
+ # an initializer; framework-neutral callers can pass keywords to Waha.client.
9
+ # No client instances are cached here.
10
+ Configuration = Struct.new(:base_url, :api_key, :session, :timeout) do
11
+ def initialize(base_url: nil, api_key: nil, session: nil, timeout: nil)
12
+ super(
13
+ base_url || default_base_url,
14
+ api_key || ENV.fetch("WAHA_API_KEY", nil),
15
+ session || default_session,
16
+ timeout || DEFAULT_TIMEOUT
17
+ )
18
+ end
19
+
20
+ alias_method :session_name, :session
21
+ alias_method :session_name=, :session=
22
+
23
+ private
24
+
25
+ def default_base_url
26
+ ENV.fetch("WAHA_BASE_URL", nil) || ENV.fetch("WAHA_API_URL", nil)
27
+ end
28
+
29
+ def default_session
30
+ ENV.fetch("WAHA_SESSION", nil) || ENV.fetch("WAHA_SESSION_NAME", nil) || DEFAULT_SESSION
31
+ end
32
+ end
33
+ end
data/lib/waha/error.rb CHANGED
@@ -5,6 +5,8 @@ module Waha
5
5
  MESSAGE_LIMIT = 600
6
6
  DETAILS_LIMIT = 450
7
7
 
8
+ RETRYABLE_STATUSES = [408, 429].freeze
9
+
8
10
  attr_reader :operation, :status, :details
9
11
 
10
12
  def initialize(operation:, status: nil, details: nil)
@@ -14,6 +16,12 @@ module Waha
14
16
  super(build_message.slice(0, MESSAGE_LIMIT))
15
17
  end
16
18
 
19
+ # Retryable failures: transport problems, WAHA server errors, rate limits, timeouts.
20
+ def retryable?
21
+ is_a?(ServerError) || is_a?(RateLimitError) || is_a?(TransportError) ||
22
+ RETRYABLE_STATUSES.include?(status)
23
+ end
24
+
17
25
  private
18
26
 
19
27
  def sanitize(details)
@@ -30,6 +38,8 @@ module Waha
30
38
  end
31
39
 
32
40
  class ApiError < Error; end
41
+ class ServerError < ApiError; end
42
+ class RateLimitError < ApiError; end
33
43
  class TransportError < Error; end
34
44
  class ValidationError < Error; end
35
45
  class VerificationError < Error; end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Waha
4
+ module Rails
5
+ module SessionState
6
+ CACHE_KEY_PREFIX = "waha:session_active"
7
+ CACHE_TTL = 30
8
+
9
+ module_function
10
+
11
+ def active?(session_name: Waha.configuration.session_name)
12
+ return false unless Waha.configured?
13
+
14
+ ::Rails.cache.fetch(cache_key(session_name), expires_in: CACHE_TTL) do
15
+ Waha.client(session: session_name).sessions.ready?
16
+ end
17
+ end
18
+
19
+ def cache_key(session_name)
20
+ "#{CACHE_KEY_PREFIX}:#{session_name}"
21
+ end
22
+ end
23
+ end
24
+ end
data/lib/waha/rails.rb CHANGED
@@ -4,5 +4,10 @@ require "waha"
4
4
  require "active_support"
5
5
  require "rails/railtie"
6
6
  require_relative "rails/controller_concern"
7
+ require_relative "rails/session_state"
7
8
  require_relative "rails/railtie"
8
9
  require_relative "../generators/waha/install/install_generator"
10
+
11
+ module Waha
12
+ SessionState = Waha::Rails::SessionState
13
+ end
@@ -3,6 +3,17 @@
3
3
  module Waha
4
4
  module Resources
5
5
  class Chats < Resource
6
+ def list(session: nil, **query)
7
+ name = session_name(session, "list_chats")
8
+ transport.request(
9
+ method: :get,
10
+ path: "/api/#{segment(name)}/chats",
11
+ operation: "list_chats",
12
+ expected_status: 200,
13
+ query: Support.query_hash(Support.compact_hash(query))
14
+ )
15
+ end
16
+
6
17
  def overview(ids: nil, limit: nil, offset: nil, session: nil, **query)
7
18
  name = session_name(session, "chats_overview")
8
19
  transport.request(
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Waha
4
+ module Resources
5
+ class Groups < Resource
6
+ def list(session: nil, **query)
7
+ name = session_name(session, "list_groups")
8
+ transport.request(
9
+ method: :get,
10
+ path: "/api/#{segment(name)}/groups",
11
+ operation: "list_groups",
12
+ expected_status: 200,
13
+ query: Support.query_hash(Support.compact_hash(query))
14
+ )
15
+ end
16
+
17
+ def get(group_id:, session: nil)
18
+ name = session_name(session, "get_group")
19
+ transport.request(
20
+ method: :get,
21
+ path: "/api/#{segment(name)}/groups/#{segment(group_id)}",
22
+ operation: "get_group",
23
+ expected_status: 200
24
+ )
25
+ end
26
+ end
27
+ end
28
+ end
@@ -7,6 +7,8 @@ module Waha
7
7
  class Messages < Resource
8
8
  DATA_MEDIA_CHARS = "a-zA-Z0-9!/:[:space:]\u0023$&'()*+,;=?~_-"
9
9
  DATA_URL_PATTERN = Regexp.new("\\Adata:[#{DATA_MEDIA_CHARS}]*;base64,", Regexp::IGNORECASE)
10
+ DATA_URL_MIMETYPE_PATTERN = Regexp.new("\\Adata:([^;,]+);base64,", Regexp::IGNORECASE)
11
+ SUCCESS_STATUSES = [200, 201].freeze
10
12
 
11
13
  def send_text(chat_id:, text:, id: nil, reply_to: nil, session: nil)
12
14
  body = { session: session_name(session, "send_text"), chatId: chat_id, text: }
@@ -16,7 +18,7 @@ module Waha
16
18
  method: :post,
17
19
  path: "/api/sendText",
18
20
  operation: "send_text",
19
- expected_status: 201,
21
+ expected_status: SUCCESS_STATUSES,
20
22
  body:
21
23
  )
22
24
  end
@@ -62,7 +64,7 @@ module Waha
62
64
  method: :post,
63
65
  path: "/api/sendSeen",
64
66
  operation: "send_seen",
65
- expected_status: 201,
67
+ expected_status: SUCCESS_STATUSES,
66
68
  body:
67
69
  )
68
70
  end
@@ -85,36 +87,36 @@ module Waha
85
87
  )
86
88
  end
87
89
 
88
- def send_image(chat_id:, file:, mimetype:, filename: nil, caption: nil, reply_to: nil, session: nil)
90
+ def send_image(chat_id:, file:, mimetype: nil, filename: nil, caption: nil, reply_to: nil, session: nil)
89
91
  body = file_body("send_image", { chat_id:, file:, mimetype:, filename:, caption:, reply_to:, session: })
90
92
  transport.request(
91
93
  method: :post,
92
94
  path: "/api/sendImage",
93
95
  operation: "send_image",
94
- expected_status: 201,
96
+ expected_status: SUCCESS_STATUSES,
95
97
  body:
96
98
  )
97
99
  end
98
100
 
99
- def send_file(chat_id:, file:, mimetype:, filename: nil, caption: nil, reply_to: nil, session: nil)
101
+ def send_file(chat_id:, file:, mimetype: nil, filename: nil, caption: nil, reply_to: nil, session: nil)
100
102
  body = file_body("send_file", { chat_id:, file:, mimetype:, filename:, caption:, reply_to:, session: })
101
103
  transport.request(
102
104
  method: :post,
103
105
  path: "/api/sendFile",
104
106
  operation: "send_file",
105
- expected_status: 201,
107
+ expected_status: SUCCESS_STATUSES,
106
108
  body:
107
109
  )
108
110
  end
109
111
 
110
- def send_voice(chat_id:, file:, mimetype:, filename: nil, reply_to: nil, convert: nil, session: nil)
112
+ def send_voice(chat_id:, file:, mimetype: nil, filename: nil, reply_to: nil, convert: nil, session: nil)
111
113
  body = file_body("send_voice", { chat_id:, file:, mimetype:, filename:, reply_to:, session: })
112
114
  body[:convert] = convert unless convert.nil?
113
115
  transport.request(
114
116
  method: :post,
115
117
  path: "/api/sendVoice",
116
118
  operation: "send_voice",
117
- expected_status: 201,
119
+ expected_status: SUCCESS_STATUSES,
118
120
  body:
119
121
  )
120
122
  end
@@ -139,20 +141,39 @@ module Waha
139
141
 
140
142
  def file_payload(operation, file:, mimetype:, filename:)
141
143
  raise ValidationError.new(operation:, details: "file must be a non-empty string") if file.to_s.empty?
142
- raise ValidationError.new(operation:, details: "mimetype is required") if mimetype.to_s.empty?
143
-
144
- payload = { mimetype: }
145
- payload[:filename] = filename unless filename.nil?
146
144
 
147
145
  if http_url?(file)
148
- payload.merge(url: file)
146
+ remote_file_payload(file, mimetype, filename)
149
147
  elsif data_url?(file)
150
- payload.merge(data: file.split(",", 2).last)
148
+ inline_file_payload(operation, file, mimetype, filename)
151
149
  else
152
150
  raise ValidationError.new(operation:, details: "file must be an http(s) URL or data URL")
153
151
  end
154
152
  end
155
153
 
154
+ # WAHA detects the MIME type of remote URLs; an explicit mimetype wins.
155
+ def remote_file_payload(file, mimetype, filename)
156
+ payload = {}
157
+ payload[:mimetype] = mimetype unless mimetype.to_s.empty?
158
+ payload[:filename] = filename unless filename.nil?
159
+ payload.merge(url: file)
160
+ end
161
+
162
+ # Data URLs carry their MIME type in the prefix when none is supplied.
163
+ def inline_file_payload(operation, file, mimetype, filename)
164
+ resolved_mimetype = mimetype.to_s.empty? ? data_url_mimetype(file) : mimetype
165
+ raise ValidationError.new(operation:, details: "mimetype is required") if resolved_mimetype.to_s.empty?
166
+
167
+ payload = { mimetype: resolved_mimetype }
168
+ payload[:filename] = filename unless filename.nil?
169
+ payload.merge(data: file.split(",", 2).last)
170
+ end
171
+
172
+ def data_url_mimetype(value)
173
+ match = DATA_URL_MIMETYPE_PATTERN.match(value.to_s)
174
+ match && match[1]
175
+ end
176
+
156
177
  def http_url?(value)
157
178
  uri = URI.parse(value.to_s)
158
179
  uri.is_a?(URI::HTTP) && !uri.host.to_s.empty?
@@ -169,7 +190,7 @@ module Waha
169
190
  method: :post,
170
191
  path: "/api/#{endpoint}",
171
192
  operation:,
172
- expected_status: 201,
193
+ expected_status: SUCCESS_STATUSES,
173
194
  body: { session: session_name(session, operation), chatId: chat_id }
174
195
  )
175
196
  end
@@ -1,8 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "base64"
4
+
3
5
  module Waha
4
6
  module Resources
5
7
  class Sessions < Resource
8
+ WORKING_STATUS = "WORKING"
9
+
6
10
  def list(all: nil)
7
11
  transport.request(
8
12
  method: :get,
@@ -24,13 +28,13 @@ module Waha
24
28
  end
25
29
 
26
30
  def create(name:, start: nil, config: nil)
27
- transport.request(
28
- method: :post,
29
- path: "/api/sessions",
30
- operation: "create_session",
31
- expected_status: [200, 201],
32
- body: Support.compact_hash(name:, start:, config:)
33
- )
31
+ write_session("create_session", :post, "/api/sessions", { name:, start:, config: })
32
+ end
33
+
34
+ def update(session: nil, name: nil, config: nil)
35
+ session_key = session_name(session, "update_session")
36
+ write_session("update_session", :put, "/api/sessions/#{segment(session_key)}",
37
+ { name: name || session_key, config: })
34
38
  end
35
39
 
36
40
  def start(session: nil)
@@ -61,17 +65,29 @@ module Waha
61
65
 
62
66
  def qr(format: nil, session: nil)
63
67
  name = session_name(session, "session_qr")
64
- response_format = format.nil? ? :binary : :json
65
68
  transport.request(
66
69
  method: :get,
67
70
  path: "/api/#{segment(name)}/auth/qr",
68
71
  operation: "session_qr",
69
72
  expected_status: 200,
70
73
  query: Support.compact_hash(format: format),
71
- response: response_format
74
+ response: qr_response_format(format)
72
75
  )
73
76
  end
74
77
 
78
+ # PNG bytes rendered as a browser-ready data URL.
79
+ def qr_data_url(session: nil)
80
+ png = qr(format: "image", session:)
81
+ "data:image/png;base64,#{Base64.strict_encode64(png.to_s)}"
82
+ end
83
+
84
+ # WAHA reports WORKING for an authenticated, usable session.
85
+ def ready?(session: nil)
86
+ Support.value(get(session:), "status") == WORKING_STATUS
87
+ rescue Waha::Error
88
+ false
89
+ end
90
+
75
91
  def request_code(phone_number:, method: nil, session: nil)
76
92
  name = session_name(session, "request_code")
77
93
  transport.request(
@@ -85,6 +101,14 @@ module Waha
85
101
 
86
102
  private
87
103
 
104
+ def write_session(operation, method, path, body)
105
+ transport.request(method:, path:, operation:, expected_status: [200, 201], body: Support.compact_hash(body))
106
+ end
107
+
108
+ def qr_response_format(format)
109
+ format.to_s == "image" || format.nil? ? :binary : :json
110
+ end
111
+
88
112
  def action(operation, action, session:, body: nil)
89
113
  name = session_name(session, operation)
90
114
  transport.request(
@@ -101,7 +101,14 @@ module Waha
101
101
  return if Array(expected_status).include?(response.status)
102
102
 
103
103
  details = response.body.to_s.empty? ? "empty provider error response" : "[REDACTED]"
104
- raise ApiError.new(operation:, status: response.status, details:)
104
+ raise error_for(response.status).new(operation:, status: response.status, details:)
105
+ end
106
+
107
+ def error_for(status)
108
+ return RateLimitError if status == 429
109
+ return ServerError if status.to_i >= 500
110
+
111
+ ApiError
105
112
  end
106
113
 
107
114
  def parse_response(response, format, operation)
data/lib/waha/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Waha
4
- VERSION = "0.1.1"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/waha.rb CHANGED
@@ -3,11 +3,13 @@
3
3
  require "waha/version"
4
4
  require "waha/error"
5
5
  require "waha/support"
6
+ require "waha/configuration"
6
7
  require "waha/transport/faraday"
7
8
  require "waha/resource"
8
9
  require "waha/resources/sessions"
9
10
  require "waha/resources/messages"
10
11
  require "waha/resources/chats"
12
+ require "waha/resources/groups"
11
13
  require "waha/resources/contacts"
12
14
  require "waha/resources/presence"
13
15
  require "waha/resources/webhooks"
@@ -15,3 +17,49 @@ require "waha/resources/media"
15
17
  require "waha/gows"
16
18
  require "waha/webhook"
17
19
  require "waha/client"
20
+
21
+ module Waha
22
+ CHAT_ID_PATTERN = /\A[\d-]+@(?:[cg]\.us|lid)\z/
23
+ GROUP_CHAT_ID_SUFFIX = "@g.us"
24
+
25
+ class << self
26
+ def configuration
27
+ @configuration ||= Configuration.new
28
+ end
29
+
30
+ def configure
31
+ yield(configuration)
32
+ end
33
+
34
+ # Resets configuration; primarily useful for tests and forked workers.
35
+ def reset_configuration!
36
+ @configuration = Configuration.new
37
+ end
38
+
39
+ def configured?
40
+ !configuration.base_url.to_s.strip.empty?
41
+ end
42
+
43
+ # Builds a fresh client per call. Client instances are never cached so
44
+ # per-request session overrides can never leak across callers.
45
+ def client(session: nil, **overrides)
46
+ Waha::Client.new(
47
+ base_url: overrides.fetch(:base_url, configuration.base_url),
48
+ api_key: overrides.fetch(:api_key, configuration.api_key),
49
+ session: session || overrides.fetch(:session, configuration.session),
50
+ timeout: overrides.fetch(:timeout, configuration.timeout)
51
+ )
52
+ end
53
+
54
+ # True for contact (@c.us), group (@g.us), and lid (@lid) chat IDs.
55
+ def valid_chat_id?(chat_id)
56
+ !chat_id.to_s.strip.empty? && CHAT_ID_PATTERN.match?(chat_id.to_s)
57
+ end
58
+
59
+ # Appends the @g.us suffix when absent so bare numeric group IDs are usable.
60
+ def group_chat_id(id)
61
+ text = id.to_s
62
+ text.end_with?(GROUP_CHAT_ID_SUFFIX) ? text : "#{text}#{GROUP_CHAT_ID_SUFFIX}"
63
+ end
64
+ end
65
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: waha-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mauricio Zaffari
@@ -229,14 +229,17 @@ files:
229
229
  - lib/generators/waha/install/templates/waha.rb
230
230
  - lib/waha.rb
231
231
  - lib/waha/client.rb
232
+ - lib/waha/configuration.rb
232
233
  - lib/waha/error.rb
233
234
  - lib/waha/gows.rb
234
235
  - lib/waha/rails.rb
235
236
  - lib/waha/rails/controller_concern.rb
236
237
  - lib/waha/rails/railtie.rb
238
+ - lib/waha/rails/session_state.rb
237
239
  - lib/waha/resource.rb
238
240
  - lib/waha/resources/chats.rb
239
241
  - lib/waha/resources/contacts.rb
242
+ - lib/waha/resources/groups.rb
240
243
  - lib/waha/resources/media.rb
241
244
  - lib/waha/resources/messages.rb
242
245
  - lib/waha/resources/presence.rb
@@ -251,7 +254,7 @@ licenses:
251
254
  - MIT
252
255
  metadata:
253
256
  homepage_uri: https://github.com/develoz-com/waha-ruby
254
- source_code_uri: https://github.com/develoz-com/waha-ruby/tree/v0.1.1
257
+ source_code_uri: https://github.com/develoz-com/waha-ruby/tree/v0.2.0
255
258
  changelog_uri: https://github.com/develoz-com/waha-ruby/blob/main/CHANGELOG.md
256
259
  rubygems_mfa_required: 'true'
257
260
  rdoc_options: []