notilify 0.1.0 → 0.1.1

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -38
  3. data/lib/notilify.rb +67 -0
  4. metadata +4 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 40b885f623c42c3883eaa84f8123fb924238d92de662d9527b9fe2f4e6acd02c
4
- data.tar.gz: 661e52e86911ce7719f64b4e79c77297c90313cdcb2e023c795a25bd70ac3fd6
3
+ metadata.gz: 98be21736192ebc4eb8d02962290056b07cf25e4553d50fa16f321175de201b2
4
+ data.tar.gz: 8092aebb56fdeeb6102664aea13c7300b3b80c4756cca3ae795ca7f3d3b804b9
5
5
  SHA512:
6
- metadata.gz: 8b8ff7dc6b09f668f9ce4c623b35e1cb7852bd2b6f8395d4588c52b2ed00c4cfa20a0c670e7d4d892dff4ba5ffa50ef4e18572fda82504452cc7d1afaa9922aa
7
- data.tar.gz: e383a5e50f1d31d422e577ba087af0eaf78e1d8dc625ead6ebe5f83d1bd25ffa348b02db1c771da023a9c20cc8ee691e97083bd33ae225953d9ea667f3bf4fbd
6
+ metadata.gz: 2e740930e4192c6d02ba70944bb756a7ff793f0e4a8dbee83f0ef2244d9459d1d1ba1ca9688081d6634382bbe20b5df6996384bd81562969892669e5a1228f08
7
+ data.tar.gz: db78b64c54fbc1e76b707912493f13f0e30ef2b499c26dc659959e5dc0ef6c4d42b65513daa00e78e183e62693f5f3c1df019e5380e32bc6dec742bf035607dd
data/README.md CHANGED
@@ -1,43 +1,18 @@
1
- # Notilify SDKs
1
+ # notilify for Ruby
2
2
 
3
- Official, dependency-light clients for the [Notilify API](https://docs.notilify.com). Every package is named `notilify` in its language ecosystem and shares the same first-release contract.
4
-
5
- This repository is open source under the [MIT License](LICENSE). Contributions and security reports are welcome; review [CONTRIBUTING.md](CONTRIBUTING.md), [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md), and [SECURITY.md](SECURITY.md) before participating.
6
-
7
- ## SDKs
8
-
9
- | Language | Package | Status | Directory |
10
- | --- | --- | --- | --- |
11
- | Node.js | [`notilify`](https://www.npmjs.com/package/notilify) | Published | [`sdks/node`](sdks/node) |
12
- | Python | `notilify` | Registry release pending | [`sdks/python`](sdks/python) |
13
- | PHP | `notilify/notilify` | Registry release pending | [`sdks/php`](sdks/php) |
14
- | Go | `github.com/codelinglabs/notilify-sdks/sdks/go` | Module tag pending | [`sdks/go`](sdks/go) |
15
- | Ruby | `notilify` | Registry release pending | [`sdks/ruby`](sdks/ruby) |
16
- | Java | `com.notilify:notilify` | Registry release pending | [`sdks/java`](sdks/java) |
17
- | .NET | `Notilify` | Registry release pending | [`sdks/dotnet`](sdks/dotnet) |
18
-
19
- ## Shared contract
20
-
21
- Each client:
22
-
23
- - authenticates with `Authorization: Bearer <api-key>`
24
- - sends one SMS through `POST /v1/message`
25
- - accepts `from`, `to`, `message`, and an optional idempotency key
26
- - defaults to `https://api.notilify.com`
27
- - supports a custom base URL and timeout for testing and controlled environments
28
- - throws a structured Notilify error for non-2xx responses
29
-
30
- ```text
31
- Client(apiKey, options)
32
- .sendMessage({ from, to, message, idempotencyKey })
3
+ ```bash
4
+ gem install notilify
33
5
  ```
34
6
 
35
- API keys must remain on a trusted server. Do not embed them in browser or mobile application bundles.
36
-
37
- ## Versioning
7
+ ```ruby
8
+ require "notilify"
38
9
 
39
- SDKs begin at `0.1.0` while the common API and packaging are validated. Language packages can be released independently, but behavior changes should remain aligned across every implementation.
40
-
41
- ## Validation
10
+ client = Notilify::Client.new(ENV.fetch("NOTILIFY_API_KEY"))
11
+ response = client.send_message(
12
+ from: "NOTILIFY", to: "+14155552671",
13
+ message: "Your verification code is 482913",
14
+ idempotency_key: "verification-482913"
15
+ )
16
+ ```
42
17
 
43
- Run `./scripts/check-sdks.sh` locally. It exercises each language's request, authentication, idempotency, response, and error checks, then validates or builds the npm, Python, Composer, RubyGems, Maven, and NuGet packages using free local toolchains. It does not require hosted CI or an organization billing plan.
18
+ Requires Ruby 3.0 or newer.
data/lib/notilify.rb ADDED
@@ -0,0 +1,67 @@
1
+ require "json"
2
+ require "net/http"
3
+ require "uri"
4
+
5
+ module Notilify
6
+ class Error < StandardError
7
+ attr_reader :status_code, :data
8
+
9
+ def initialize(message, status_code: nil, data: nil)
10
+ super(message)
11
+ @status_code = status_code
12
+ @data = data
13
+ end
14
+ end
15
+
16
+ class Client
17
+ def initialize(api_key, base_url: "https://api.notilify.com", timeout: 10, transport: nil)
18
+ raise ArgumentError, "A Notilify API key is required" if api_key.to_s.strip.empty?
19
+ @api_key = api_key
20
+ @base_url = base_url.sub(%r{/$}, "")
21
+ @timeout = timeout
22
+ @transport = transport
23
+ end
24
+
25
+ def send_message(from:, to:, message:, idempotency_key: nil)
26
+ validate_message(from, to, message)
27
+ uri = URI("#{@base_url}/v1/message")
28
+ request = Net::HTTP::Post.new(uri)
29
+ request["Authorization"] = "Bearer #{@api_key}"
30
+ request["Content-Type"] = "application/json"
31
+ request["Idempotency-Key"] = idempotency_key if idempotency_key && !idempotency_key.empty?
32
+ request.body = { from: from, to: to, message: message }.to_json
33
+ response = @transport ? @transport.call(uri, request) : perform(uri, request)
34
+ body = parse_body(response.body)
35
+ unless response.code.to_i.between?(200, 299)
36
+ api_message = body.is_a?(Hash) ? body["message"] : nil
37
+ data = body.is_a?(Hash) ? body["data"] : body
38
+ raise Error.new(api_message || "Notilify request failed with HTTP #{response.code}", status_code: response.code.to_i, data: data)
39
+ end
40
+ body
41
+ rescue ArgumentError, Error
42
+ raise
43
+ rescue StandardError => error
44
+ raise Error, "Notilify request failed: #{error.message}"
45
+ end
46
+
47
+ private
48
+
49
+ def perform(uri, request)
50
+ Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https", open_timeout: @timeout, read_timeout: @timeout) { |http| http.request(request) }
51
+ end
52
+
53
+ def validate_message(from, to, message)
54
+ { "from" => from, "to" => to, "message" => message }.each do |name, value|
55
+ raise ArgumentError, "#{name} is required" unless value.is_a?(String) && !value.strip.empty?
56
+ end
57
+ raise ArgumentError, "message must be 160 characters or fewer" if message.length > 160
58
+ end
59
+
60
+ def parse_body(raw)
61
+ return nil if raw.nil? || raw.empty?
62
+ JSON.parse(raw)
63
+ rescue JSON::ParserError
64
+ raw
65
+ end
66
+ end
67
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: notilify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Notilify
@@ -17,12 +17,13 @@ extra_rdoc_files: []
17
17
  files:
18
18
  - LICENSE
19
19
  - README.md
20
+ - lib/notilify.rb
20
21
  homepage: https://notilify.com
21
22
  licenses:
22
23
  - MIT
23
24
  metadata:
24
- source_code_uri: https://github.com/codelinglabs/notilify-sdks/tree/main/sdks/ruby
25
- bug_tracker_uri: https://github.com/codelinglabs/notilify-sdks/issues
25
+ source_code_uri: https://github.com/notilify/notilify-sdks/tree/main/sdks/ruby
26
+ bug_tracker_uri: https://github.com/notilify/notilify-sdks/issues
26
27
  rubygems_mfa_required: 'true'
27
28
  rdoc_options: []
28
29
  require_paths: