Class: VirtualSMS

Inherits:
Object
  • Object
show all
Defined in:
lib/virtualsms.rb

Overview

VirtualSMS Ruby SDK — SMS verification with real physical SIM cards.

Unlike VoIP services, VirtualSMS uses real SIM cards in hardware modems connected to European and US cellular networks. Near-100% delivery rates on WhatsApp, Telegram, and platforms that block virtual numbers.

Get your API key at virtualsms.io (Settings → API Keys) API Docs: virtualsms.io/api Pricing: virtualsms.io/pricing

Examples:

Quick start

client = VirtualSMS.new('vsms_your_api_key')
activation = client.get_number('wa', country: 22) # WhatsApp, UK
code = client.wait_for_code(activation[:activation_id])
puts "Code: #{code}"
client.done(activation[:activation_id])

Defined Under Namespace

Classes: Error, NoNumbersError

Constant Summary collapse

BASE_URL =
'https://virtualsms.io/stubs/handler_api.php'

Instance Method Summary collapse

Constructor Details

#initialize(api_key, base_url: BASE_URL) ⇒ VirtualSMS

Returns a new instance of VirtualSMS.



27
28
29
30
# File 'lib/virtualsms.rb', line 27

def initialize(api_key, base_url: BASE_URL)
  @api_key = api_key
  @base_url = base_url
end

Instance Method Details

#cancel(activation_id) ⇒ Object

Cancel activation and get refund.



71
72
73
# File 'lib/virtualsms.rb', line 71

def cancel(activation_id)
  request('setStatus', id: activation_id, status: 8)
end

#done(activation_id) ⇒ Object

Mark activation as done.



66
67
68
# File 'lib/virtualsms.rb', line 66

def done(activation_id)
  request('setStatus', id: activation_id, status: 6)
end

#get_balanceObject

Get current account balance in USD.

Raises:



33
34
35
36
37
# File 'lib/virtualsms.rb', line 33

def get_balance
  result = request('getBalance')
  raise Error, result unless result.start_with?('ACCESS_BALANCE:')
  result.split(':')[1].to_f
end

#get_number(service, country: 187) ⇒ Object

Request a phone number for SMS verification.

Parameters:

  • service (String)

    Service code (‘wa’, ‘tg’, ‘go’, etc.)

  • country (Integer) (defaults to: 187)

    Country ID (187=US, 22=UK, 12=Germany)



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/virtualsms.rb', line 42

def get_number(service, country: 187)
  result = request('getNumber', service: service, country: country)
  if result.start_with?('ACCESS_NUMBER:')
    parts = result.split(':')
    { activation_id: parts[1].to_i, phone: parts[2], service: service, country: country }
  elsif result == 'NO_NUMBERS'
    raise NoNumbersError, "No numbers for #{service} in country #{country}"
  else
    raise Error, result
  end
end

#get_status(activation_id) ⇒ Object

Check status of an activation.



55
56
57
58
59
60
61
62
63
# File 'lib/virtualsms.rb', line 55

def get_status(activation_id)
  result = request('getStatus', id: activation_id)
  case result
  when 'STATUS_WAIT_CODE' then { status: 'waiting', code: nil }
  when /^STATUS_OK:/ then { status: 'received', code: result.split(':')[1] }
  when 'STATUS_CANCEL' then { status: 'cancelled', code: nil }
  else { status: result, code: nil }
  end
end

#wait_for_code(activation_id, timeout: 300, poll_interval: 5) ⇒ Object

Wait for SMS code to arrive.

Parameters:

  • timeout (Integer) (defaults to: 300)

    Max wait in seconds (default: 300)

  • poll_interval (Integer) (defaults to: 5)

    Seconds between checks (default: 5)



78
79
80
81
82
83
84
85
86
87
# File 'lib/virtualsms.rb', line 78

def wait_for_code(activation_id, timeout: 300, poll_interval: 5)
  start = Time.now
  while Time.now - start < timeout
    result = get_status(activation_id)
    return result[:code] if result[:code]
    return nil if result[:status] == 'cancelled'
    sleep(poll_interval)
  end
  nil
end