Class: WhatsAppNotifier::WebAdapter
- Inherits:
-
Object
- Object
- WhatsAppNotifier::WebAdapter
- Defined in:
- lib/whatsapp_notifier/web_adapter.rb
Constant Summary collapse
- DEFAULT_OPEN_TIMEOUT =
5- DEFAULT_READ_TIMEOUT =
30- MEDIA_OPEN_TIMEOUT =
Media bytes can be tens of MB over a slow link — give the binary fetch a longer read window than the JSON control plane.
5- MEDIA_READ_TIMEOUT =
60- HTTP_CLASSES =
{ post: Net::HTTP::Post, get: Net::HTTP::Get, delete: Net::HTTP::Delete }.freeze
- INBOUND_OPTIONAL_KEYS =
Optional inbound keys introduced by the 0.7.0 service (media verdict + sender display name). Mapped ONLY when the wire payload carries them, so hosts can key-gate on has_media presence: a missing key means “0.6.0 service, no media support”, while has_media: false means “text message”.
{ has_media: %w[hasMedia has_media], media_status: %w[mediaStatus media_status], media_error: %w[mediaError media_error], media_mime: %w[mediaMime media_mime], media_filename: %w[mediaFilename media_filename], media_size: %w[mediaSize media_size], sender_name: %w[senderName sender_name] }.freeze
Class Method Summary collapse
Instance Method Summary collapse
- #connection_status(metadata: {}) ⇒ Object
-
#delete_media(message_id:, metadata: {}) ⇒ Object
Removes the service’s copy after the host has attached the bytes.
-
#fetch_inbound(metadata: {}) ⇒ Object
Drains the service’s pending inbound queue for this user.
-
#fetch_media(message_id:, metadata: {}) ⇒ Object
Fetches the raw bytes of a downloaded inbound media file.
- #fetch_qr_code(metadata: {}) ⇒ Object
-
#initialize(base_url: self.class.default_base_url, open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT) ⇒ WebAdapter
constructor
A new instance of WebAdapter.
-
#logout(metadata: {}) ⇒ Object
Logs the user out of WhatsApp and clears their saved session on the service.
- #send_message(payload:, session: {}) ⇒ Object
Constructor Details
#initialize(base_url: self.class.default_base_url, open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT) ⇒ WebAdapter
Returns a new instance of WebAdapter.
38 39 40 41 42 43 44 |
# File 'lib/whatsapp_notifier/web_adapter.rb', line 38 def initialize(base_url: self.class.default_base_url, open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT) @base_url = base_url @open_timeout = open_timeout @read_timeout = read_timeout end |
Class Method Details
.default_base_url ⇒ Object
34 35 36 |
# File 'lib/whatsapp_notifier/web_adapter.rb', line 34 def self.default_base_url ENV["WHATSAPP_NOTIFIER_SERVICE_URL"] || ENV["WHATSAPP_SERVICE_URL"] || "http://127.0.0.1:3001" end |
Instance Method Details
#connection_status(metadata: {}) ⇒ Object
69 70 71 72 73 74 75 76 77 |
# File 'lib/whatsapp_notifier/web_adapter.rb', line 69 def connection_status(metadata: {}) user_id = user_id_from() response = request(:get, "/status/#{user_id}") { state: response["state"], authenticated: response["authenticated"], has_qr: response["hasQR"] } end |
#delete_media(message_id:, metadata: {}) ⇒ Object
Removes the service’s copy after the host has attached the bytes. Idempotent on the service side: deleting absent media still succeeds. A 0.6.0 service mid-rollout has no /media routes and answers 404 —degrade to { success: false } instead of raising, mirroring fetch_media’s nil-on-404.
117 118 119 120 121 |
# File 'lib/whatsapp_notifier/web_adapter.rb', line 117 def delete_media(message_id:, metadata: {}) user_id = user_id_from() response = request(:delete, "/media/#{user_id}/#{path_id()}", allow_404: true) { success: response.fetch("success", false) } end |
#fetch_inbound(metadata: {}) ⇒ Object
Drains the service’s pending inbound queue for this user. The service returns the messages once, then clears them (at-least-once handoff —callers must dedupe on message_id). Accepts either a bare array or a { “messages” => […] } envelope so the wire format can evolve.
83 84 85 86 87 88 |
# File 'lib/whatsapp_notifier/web_adapter.rb', line 83 def fetch_inbound(metadata: {}) user_id = user_id_from() response = request(:get, "/inbound/#{user_id}") raw = response.is_a?(Hash) ? response["messages"] : response Array(raw).map { |m| (m) } end |
#fetch_media(message_id:, metadata: {}) ⇒ Object
Fetches the raw bytes of a downloaded inbound media file. Returns { body:, mime:, filename:, size: } or nil when the service has no copy (never downloaded, swept by TTL, or already deleted).
Deliberately NOT routed through #request: that path JSON-parses the response body (and host apps are known to patch it further), which would corrupt binary payloads.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/whatsapp_notifier/web_adapter.rb', line 97 def fetch_media(message_id:, metadata: {}) user_id = user_id_from() res = binary_get("/media/#{user_id}/#{path_id()}") return nil if res.code.to_s == "404" raise "service request failed (#{res.code}): #{res.body}" unless res.is_a?(Net::HTTPSuccess) body = res.body.to_s { body: body, mime: res["Content-Type"], filename: filename_from(res["Content-Disposition"]), size: body.bytesize } end |
#fetch_qr_code(metadata: {}) ⇒ Object
63 64 65 66 67 |
# File 'lib/whatsapp_notifier/web_adapter.rb', line 63 def fetch_qr_code(metadata: {}) user_id = user_id_from() response = request(:get, "/qr/#{user_id}") response["qr"] end |
#logout(metadata: {}) ⇒ Object
Logs the user out of WhatsApp and clears their saved session on the service.
124 125 126 127 128 |
# File 'lib/whatsapp_notifier/web_adapter.rb', line 124 def logout(metadata: {}) user_id = user_id_from() response = request(:post, "/logout/#{user_id}") { success: response.fetch("success", false) } end |
#send_message(payload:, session: {}) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/whatsapp_notifier/web_adapter.rb', line 46 def (payload:, session: {}) user_id = user_id_from(payload[:metadata] || {}) body = { to: payload[:to], message: payload[:body], mediaUrl: payload.dig(:metadata, :media_url) }.compact response = request(:post, "/send/#{user_id}", body: body) { success: response.fetch("success"), message_id: payload[:idempotency_key] || "local-#{Time.now.to_i}", session: session, error_message: response["error"] } end |