kwtsms 0.1.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 +7 -0
- data/CHANGELOG.md +37 -0
- data/LICENSE +21 -0
- data/README.md +386 -0
- data/exe/kwtsms +222 -0
- data/lib/kwtsms/client.rb +395 -0
- data/lib/kwtsms/env_loader.rb +34 -0
- data/lib/kwtsms/errors.rb +51 -0
- data/lib/kwtsms/logger.rb +19 -0
- data/lib/kwtsms/message.rb +86 -0
- data/lib/kwtsms/phone.rb +64 -0
- data/lib/kwtsms/request.rb +80 -0
- data/lib/kwtsms/version.rb +5 -0
- data/lib/kwtsms.rb +30 -0
- metadata +65 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "net/http"
|
|
4
|
+
require "uri"
|
|
5
|
+
require "json"
|
|
6
|
+
require "time"
|
|
7
|
+
|
|
8
|
+
module KwtSMS
|
|
9
|
+
BASE_URL = "https://www.kwtsms.com/API/"
|
|
10
|
+
|
|
11
|
+
# kwtSMS server runs at GMT+3 (Asia/Kuwait).
|
|
12
|
+
# unix-timestamp values in API responses are server time, not UTC.
|
|
13
|
+
SERVER_TIMEZONE = "Asia/Kuwait (GMT+3)"
|
|
14
|
+
|
|
15
|
+
# POST to a kwtSMS REST/JSON API endpoint.
|
|
16
|
+
#
|
|
17
|
+
# Always sets Content-Type and Accept: application/json.
|
|
18
|
+
# Strips password from log entry.
|
|
19
|
+
# Returns parsed JSON hash.
|
|
20
|
+
# Raises RuntimeError on network / HTTP / parse failure.
|
|
21
|
+
def self.api_request(endpoint, payload, log_file = "")
|
|
22
|
+
url = URI.parse("#{BASE_URL}#{endpoint}/")
|
|
23
|
+
|
|
24
|
+
safe_payload = payload.transform_keys(&:to_s).each_with_object({}) do |(k, v), h|
|
|
25
|
+
h[k] = k == "password" ? "***" : v
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
log_entry = {
|
|
29
|
+
"ts" => Time.now.utc.iso8601,
|
|
30
|
+
"endpoint" => endpoint,
|
|
31
|
+
"request" => safe_payload,
|
|
32
|
+
"response" => nil,
|
|
33
|
+
"ok" => false,
|
|
34
|
+
"error" => nil
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
begin
|
|
38
|
+
http = Net::HTTP.new(url.host, url.port)
|
|
39
|
+
http.use_ssl = true
|
|
40
|
+
http.open_timeout = 15
|
|
41
|
+
http.read_timeout = 15
|
|
42
|
+
|
|
43
|
+
request = Net::HTTP::Post.new(url.path)
|
|
44
|
+
request["Content-Type"] = "application/json"
|
|
45
|
+
request["Accept"] = "application/json"
|
|
46
|
+
request.body = JSON.generate(payload)
|
|
47
|
+
|
|
48
|
+
response = http.request(request)
|
|
49
|
+
body = response.body.to_s
|
|
50
|
+
|
|
51
|
+
begin
|
|
52
|
+
data = JSON.parse(body)
|
|
53
|
+
rescue JSON::ParserError => e
|
|
54
|
+
log_entry["error"] = "Invalid JSON response: #{e.message}"
|
|
55
|
+
write_log(log_file, log_entry)
|
|
56
|
+
raise RuntimeError, "Invalid JSON response: #{e.message}"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
log_entry["response"] = data
|
|
60
|
+
log_entry["ok"] = data["result"] == "OK"
|
|
61
|
+
write_log(log_file, log_entry)
|
|
62
|
+
|
|
63
|
+
# For HTTP errors (4xx/5xx), kwtSMS returns JSON error details in the body.
|
|
64
|
+
# If we successfully parsed the JSON, return it like a normal response.
|
|
65
|
+
return data
|
|
66
|
+
|
|
67
|
+
rescue Net::OpenTimeout, Net::ReadTimeout => e
|
|
68
|
+
err = "Network error: connection timed out"
|
|
69
|
+
log_entry["error"] = err
|
|
70
|
+
write_log(log_file, log_entry)
|
|
71
|
+
raise RuntimeError, err
|
|
72
|
+
|
|
73
|
+
rescue SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, IOError => e
|
|
74
|
+
err = "Network error: #{e.message}"
|
|
75
|
+
log_entry["error"] = err
|
|
76
|
+
write_log(log_file, log_entry)
|
|
77
|
+
raise RuntimeError, err
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
data/lib/kwtsms.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# kwtsms: Ruby client for the kwtSMS API (kwtsms.com)
|
|
4
|
+
#
|
|
5
|
+
# Quick start:
|
|
6
|
+
# require "kwtsms"
|
|
7
|
+
#
|
|
8
|
+
# sms = KwtSMS::Client.from_env # reads .env / env vars
|
|
9
|
+
# ok, balance, err = sms.verify
|
|
10
|
+
# result = sms.send_sms("96598765432", "Your OTP is: 123456")
|
|
11
|
+
# result = sms.send_sms("96598765432", "Hello", sender: "MY-APP")
|
|
12
|
+
# report = sms.validate(["96598765432", "+96512345678"])
|
|
13
|
+
# balance = sms.balance
|
|
14
|
+
# delivery = sms.status(result["msg-id"])
|
|
15
|
+
#
|
|
16
|
+
# Utility functions:
|
|
17
|
+
# KwtSMS.normalize_phone("+965 9876 5432")
|
|
18
|
+
# KwtSMS.validate_phone_input("user@email.com")
|
|
19
|
+
# KwtSMS.clean_message("Hello \u{1F600} world")
|
|
20
|
+
|
|
21
|
+
require "set"
|
|
22
|
+
|
|
23
|
+
require_relative "kwtsms/version"
|
|
24
|
+
require_relative "kwtsms/errors"
|
|
25
|
+
require_relative "kwtsms/phone"
|
|
26
|
+
require_relative "kwtsms/message"
|
|
27
|
+
require_relative "kwtsms/env_loader"
|
|
28
|
+
require_relative "kwtsms/logger"
|
|
29
|
+
require_relative "kwtsms/request"
|
|
30
|
+
require_relative "kwtsms/client"
|
metadata
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: kwtsms
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- boxlink
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-03-06 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Official Ruby client library for the kwtSMS SMS gateway. Send SMS, check
|
|
14
|
+
balance, validate phone numbers, check delivery status, and manage sender IDs. Zero
|
|
15
|
+
external dependencies.
|
|
16
|
+
email:
|
|
17
|
+
- info@boxlink.net
|
|
18
|
+
executables:
|
|
19
|
+
- kwtsms
|
|
20
|
+
extensions: []
|
|
21
|
+
extra_rdoc_files: []
|
|
22
|
+
files:
|
|
23
|
+
- CHANGELOG.md
|
|
24
|
+
- LICENSE
|
|
25
|
+
- README.md
|
|
26
|
+
- exe/kwtsms
|
|
27
|
+
- lib/kwtsms.rb
|
|
28
|
+
- lib/kwtsms/client.rb
|
|
29
|
+
- lib/kwtsms/env_loader.rb
|
|
30
|
+
- lib/kwtsms/errors.rb
|
|
31
|
+
- lib/kwtsms/logger.rb
|
|
32
|
+
- lib/kwtsms/message.rb
|
|
33
|
+
- lib/kwtsms/phone.rb
|
|
34
|
+
- lib/kwtsms/request.rb
|
|
35
|
+
- lib/kwtsms/version.rb
|
|
36
|
+
homepage: https://github.com/boxlinknet/kwtsms-ruby
|
|
37
|
+
licenses:
|
|
38
|
+
- MIT
|
|
39
|
+
metadata:
|
|
40
|
+
homepage_uri: https://github.com/boxlinknet/kwtsms-ruby
|
|
41
|
+
source_code_uri: https://github.com/boxlinknet/kwtsms-ruby
|
|
42
|
+
changelog_uri: https://github.com/boxlinknet/kwtsms-ruby/blob/main/CHANGELOG.md
|
|
43
|
+
bug_tracker_uri: https://github.com/boxlinknet/kwtsms-ruby/issues
|
|
44
|
+
documentation_uri: https://github.com/boxlinknet/kwtsms-ruby#readme
|
|
45
|
+
rubygems_mfa_required: 'true'
|
|
46
|
+
post_install_message:
|
|
47
|
+
rdoc_options: []
|
|
48
|
+
require_paths:
|
|
49
|
+
- lib
|
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: 2.7.0
|
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
56
|
+
requirements:
|
|
57
|
+
- - ">="
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: '0'
|
|
60
|
+
requirements: []
|
|
61
|
+
rubygems_version: 3.5.22
|
|
62
|
+
signing_key:
|
|
63
|
+
specification_version: 4
|
|
64
|
+
summary: Ruby client for the kwtSMS API (kwtsms.com)
|
|
65
|
+
test_files: []
|