mitake 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'mitake/credential'
5
+
6
+ module Mitake
7
+ module API
8
+ # @since 0.1.0
9
+ # @api private
10
+ class Base
11
+ # @param path [String] the api endpoint
12
+ # @param params [Hash] the request body
13
+ #
14
+ # @since 0.1.0
15
+ # @api private
16
+ def initialize(path, params = {})
17
+ @path = path
18
+ @params = params
19
+ end
20
+
21
+ # @since 0.1.0
22
+ # @api private
23
+ def request
24
+ raise NotImplementedError, 'Request not defined!'
25
+ end
26
+
27
+ # Execute HTTP Request
28
+ #
29
+ # @return [Net::HTTPResponse] the request result
30
+ #
31
+ # @since 0.1.0
32
+ # @api private
33
+ def execute
34
+ Net::HTTP.start(uri.host, uri.port, use_ssl: ssl?) do |http|
35
+ http.request request
36
+ end
37
+ end
38
+
39
+ # @return [URI] the request URI
40
+ #
41
+ # @since 0.1.0
42
+ # @api private
43
+ def uri
44
+ @uri ||= URI("#{Mitake.credential.server}#{@path}")
45
+ end
46
+
47
+ # @return [TrueClass|FalseClass] is the SSL request
48
+ #
49
+ # @since 0.1.0
50
+ # @api private
51
+ def ssl?
52
+ @uri.scheme == 'https'
53
+ end
54
+
55
+ # Return the request params
56
+ #
57
+ # @return [Hash] the query params
58
+ #
59
+ # @since 0.1.0
60
+ # @api private
61
+ def params
62
+ @params.merge(
63
+ username: Mitake.credential.username,
64
+ password: Mitake.credential.password
65
+ )
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mitake/api/base'
4
+
5
+ module Mitake
6
+ module API
7
+ # Create HTTP Get Request
8
+ #
9
+ # @since 0.1.0
10
+ # @api private
11
+ class Get < Base
12
+ # Create HTTP Get Request
13
+ #
14
+ # @since 0.1.0
15
+ # @api private
16
+ def request
17
+ return @request unless @request.nil?
18
+
19
+ @request ||= Net::HTTP::Get.new(uri)
20
+ end
21
+
22
+ # @see Mitake::API::Base#uri
23
+ #
24
+ # @since 0.1.0
25
+ # @api private
26
+ def uri
27
+ @uri ||=
28
+ URI("#{Mitake.credential.server}" \
29
+ "#{@path}?#{URI.encode_www_form(params)}")
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mitake/api/base'
4
+
5
+ module Mitake
6
+ module API
7
+ # Create HTTP Get Request
8
+ #
9
+ # @since 0.1.0
10
+ # @api private
11
+ class Post < Base
12
+ # Create HTTP Post Request
13
+ #
14
+ # @since 0.1.0
15
+ # @api private
16
+ def request
17
+ return @request unless @request.nil?
18
+
19
+ @request ||= Net::HTTP::Post.new(uri)
20
+ @request.body = URI.encode_www_form(params)
21
+ @request
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mitake/api'
4
+ require 'mitake/model'
5
+
6
+ module Mitake
7
+ # Get the current balance
8
+ #
9
+ # @since 0.1.0
10
+ class Balance
11
+ class << self
12
+ # Get account point
13
+ #
14
+ # @see Mitake::Balance#amount
15
+ # @return [Integer]
16
+ #
17
+ # @since 0.1.0
18
+ def amount
19
+ execute&.first&.amount
20
+ end
21
+ end
22
+
23
+ include API
24
+ include Model
25
+
26
+ path '/api/mtk/SmQuery'
27
+ map 'AccountPoint', 'amount'
28
+
29
+ # @!attribute [r] amount
30
+ # @return [Integer] the amount of account point
31
+ #
32
+ # @since 0.1.0
33
+ attribute :amount, Integer
34
+ end
35
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mitake
4
+ # The helper object to define boolean value
5
+ #
6
+ # @since 0.1.0
7
+ # @api private
8
+ class Boolean
9
+ TRUE_VALUES = %w[Y 1 yes true].freeze
10
+
11
+ class << self
12
+ # Parse boolean value
13
+ #
14
+ # @since 0.1.0
15
+ # @api private
16
+ def parse(value)
17
+ return true if value == true
18
+ return true if TRUE_VALUES.include?(value)
19
+
20
+ false
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mitake
4
+ # The Mitake SMS Client
5
+ #
6
+ # @since 0.1.
7
+ class Credential
8
+ # @since 0.1.0
9
+ # @api private
10
+ DEFAULT_SERVER = 'https://smsapi.mitake.com.tw'
11
+
12
+ # @since 0.1.0
13
+ attr_reader :username, :password, :server
14
+
15
+ # Return Mitake::Client instance
16
+ #
17
+ # @param username [String] the username, default is `MITAKE_USERNAME`
18
+ # @param password [String] the password, default is `MITAKE_PASSWORD`
19
+ # @param server [String] the API server url
20
+ # @return [Mitake::Client] the api instance
21
+ #
22
+ # @since 0.1.0
23
+ def initialize(username = nil, password = nil, server = nil)
24
+ @username = username || ENV['MITAKE_USERNAME']
25
+ @password = password || ENV['MITAKE_PASSWORD']
26
+ @server = server || ENV['MITAKE_SERVER'] || DEFAULT_SERVER
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mitake/model'
4
+ require 'mitake/recipient'
5
+ require 'mitake/response'
6
+ require 'mitake/boolean'
7
+ require 'mitake/status'
8
+
9
+ module Mitake
10
+ # Create Sort Message
11
+ #
12
+ # @since 0.1.0
13
+ class Message
14
+ include API
15
+ include Model
16
+
17
+ method 'Post'
18
+ path '/api/mtk/SmSend?CharsetURL=UTF8'
19
+ map 'msgid', 'id'
20
+ map 'Duplicate', 'duplicate'
21
+ map 'statuscode', 'status_code'
22
+
23
+ # @!attribute [r] id
24
+ # @return [String] the message id
25
+ attribute :id, String, readonly: true
26
+
27
+ # @!attribute source_id
28
+ # @return [String] the customize identity
29
+ attribute :source_id, String
30
+
31
+ # @!attribute receipient
32
+ # @return [Mitake::Recipient] the message recipient
33
+ attribute :recipient, Recipient
34
+
35
+ # @!attribute body
36
+ # @return [String] the message body
37
+ attribute :body, String
38
+
39
+ # @!attribute schedule_at
40
+ # @return [Time|NilClass] the schedule time to send message
41
+ attribute :schedule_at, Time
42
+
43
+ # @!attribute expired_at
44
+ # @return [Time|NilClass] the valid time for this message
45
+ attribute :expired_at, Time
46
+
47
+ # @!attribute webhook_url
48
+ # @return [String|NilClass] the response callback url
49
+ attribute :webhook_url, String
50
+
51
+ # @!attribute [r] duplicate
52
+ # @return [TrueClass|FalseClass] is the message duplicate
53
+ attribute :duplicate, Boolean, readonly: true
54
+
55
+ # @!attribute [r] status_code
56
+ # @return [Integer] the status code
57
+ attribute :status_code, Integer, readonly: true
58
+
59
+ # Send message
60
+ #
61
+ # @since 0.1.0
62
+ # @api private
63
+ def delivery
64
+ return self if sent?
65
+
66
+ self.class.execute(params) do |items|
67
+ attrs = items&.first&.slice(*self.class.attribute_names)
68
+ assign_attributes(attrs)
69
+ end
70
+
71
+ self
72
+ end
73
+
74
+ # Does message is sent
75
+ #
76
+ # @return [TrueClass|FalseClass] is the message sent
77
+ #
78
+ # @since 0.1.0
79
+ def sent?
80
+ !@id.nil?
81
+ end
82
+
83
+ # Does message is duplicate
84
+ #
85
+ # @return [TrueClass|FalseClass] is the message duplicate
86
+ #
87
+ # @since 0.1.0
88
+ def duplicate?
89
+ @duplicate == true
90
+ end
91
+
92
+ # Readable status code
93
+ #
94
+ # @return [String] the status code description
95
+ #
96
+ # @since 0.1.0
97
+ def status
98
+ Status::CODES[@status_code]
99
+ end
100
+
101
+ private
102
+
103
+ # The request params
104
+ #
105
+ # @since 0.1.0
106
+ # @api private
107
+ def params
108
+ {
109
+ clientid: @source_id,
110
+ smbody: @body,
111
+ dlvtime: @schedule_at&.strftime('%Y%m%d%H%M%S'),
112
+ vldtime: @expired_at&.strftime('%Y%m%d%H%M%S'),
113
+ dstaddr: @recipient.phone_number,
114
+ destname: @recipient.name,
115
+ response: @webhook_url
116
+ }.reject { |_, v| v.nil? }.to_h
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mitake/model/attributes'
4
+ require 'mitake/model/accessor'
5
+
6
+ module Mitake
7
+ # Provide attributes accessor
8
+ #
9
+ # @since 0.1.0
10
+ # @api private
11
+ module Model
12
+ # @since 0.1.0
13
+ # @api private
14
+ def self.included(base)
15
+ base.class_eval do
16
+ include Attributes
17
+ extend Accessor
18
+ end
19
+ end
20
+
21
+ # Get attributes as hash
22
+ #
23
+ # @return [Hash] the object attributes
24
+ #
25
+ # @since 0.1.0
26
+ def attributes
27
+ self
28
+ .class
29
+ .attribute_names
30
+ .map { |attr| [attr, send(attr)] }
31
+ .reject { |_, value| value.nil? }
32
+ .map do |attr, value|
33
+ [attr, value.respond_to?(:attributes) ? value.attributes : value]
34
+ end
35
+ .to_h
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+ require 'date'
5
+
6
+ module Mitake
7
+ module Model
8
+ # @since 0.1.0
9
+ # @api private
10
+ module Accessor
11
+ # Get attributes
12
+ #
13
+ # @return [Hash] the list of attributes and type
14
+ #
15
+ # @since 0.1.0
16
+ def attributes
17
+ @attributes ||= {}
18
+ end
19
+
20
+ # Get attribute names
21
+ #
22
+ # @return [Array] the list of attribute names
23
+ #
24
+ # @since 0.1.0
25
+ def attribute_names
26
+ attributes.keys
27
+ end
28
+
29
+ # Define attribute
30
+ #
31
+ # @param name [String|Symbol] the attribute name
32
+ # @param type [Class] the attribute type
33
+ # @param readonly [TrueClass|FalseClass] is attribute readonly
34
+ #
35
+ # @since 0.1.0
36
+ def attribute(name, type = 'String', readonly: false)
37
+ @attributes ||= {}
38
+ @attributes[name.to_s] = type.to_s
39
+
40
+ define_method name do
41
+ instance_variable_get("@#{name}")
42
+ end
43
+ return if readonly
44
+
45
+ define_method "#{name}=" do |value|
46
+ instance_variable_set("@#{name}", self.class.cast(value, type.to_s))
47
+ end
48
+ end
49
+
50
+ # Casting type
51
+ #
52
+ # @param value [Object] the source value
53
+ # @param type [Class] the cast type
54
+ #
55
+ # @since 0.1.0
56
+ # @api private
57
+ def cast(value, type = 'String')
58
+ case type.to_s
59
+ when 'String', 'Integer', 'Float'
60
+ Kernel.method(type).call(value)
61
+ when 'Time', 'DateTime', 'Date'
62
+ Kernel.const_get(type).parse("#{value}+8")
63
+ else
64
+ klass = Kernel.const_get(type)
65
+ return klass.parse(value) if klass.respond_to?(:parse)
66
+
67
+ value
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end