mirror of https://github.com/docusealco/docuseal
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
64 lines
2.2 KiB
64 lines
2.2 KiB
# frozen_string_literal: true
|
|
|
|
module Sms
|
|
class Error < StandardError; end
|
|
class NotConfiguredError < Error; end
|
|
class ProviderError < Error; end
|
|
class InvalidNumberError < Error; end
|
|
|
|
SUPPORTED_PROVIDERS = %w[bulkvs].freeze
|
|
|
|
module_function
|
|
|
|
# Returns the SMS configuration hash for an account, with the same keys the
|
|
# form posts: { provider, enabled, basic_auth_token, from_number,
|
|
# delivery_webhook_url }. Returns nil if no record exists.
|
|
def configuration_for(account)
|
|
return nil if account.nil?
|
|
|
|
record = EncryptedConfig.find_by(account_id: account.id, key: EncryptedConfig::SMS_CONFIGS_KEY)
|
|
record&.value
|
|
end
|
|
|
|
def enabled_for?(account)
|
|
config = configuration_for(account)
|
|
config.is_a?(Hash) &&
|
|
config['enabled'] &&
|
|
SUPPORTED_PROVIDERS.include?(config['provider'].to_s) &&
|
|
config['basic_auth_token'].to_s.present? &&
|
|
config['from_number'].to_s.present?
|
|
end
|
|
|
|
# Send an SMS via the account's configured provider.
|
|
#
|
|
# account: a WaboSign Account record
|
|
# to: the recipient phone number (E.164 string, leading + tolerated)
|
|
# text: the message body (already variable-substituted)
|
|
# webhook: optional override of the per-message delivery_status_webhook_url
|
|
#
|
|
# Returns the provider's parsed JSON response on success. Raises
|
|
# NotConfiguredError or ProviderError on failure.
|
|
def send_message(account:, to:, text:, webhook: nil)
|
|
config = configuration_for(account)
|
|
raise NotConfiguredError, 'SMS provider is not configured' unless enabled_for?(account)
|
|
|
|
provider = config['provider'].to_s
|
|
case provider
|
|
when 'bulkvs'
|
|
Sms::Providers::Bulkvs.new(config).deliver(to: to, text: text, webhook: webhook)
|
|
else
|
|
raise NotConfiguredError, "Unsupported SMS provider: #{provider.inspect}"
|
|
end
|
|
end
|
|
|
|
# Normalize a phone number to E.164 (digits-only, no '+'). BulkVS expects
|
|
# eleven-digit US numbers like 15551234567; international numbers are passed
|
|
# through as-is once stripped of formatting characters.
|
|
def normalize_phone(raw)
|
|
digits = raw.to_s.gsub(/[^\d]/, '')
|
|
raise InvalidNumberError, "Invalid phone number: #{raw.inspect}" if digits.length < 8
|
|
|
|
digits
|
|
end
|
|
end
|