Module: Bobot::Buttons

Defined in:
lib/bobot/buttons.rb

Constant Summary collapse

REGEX_PHONE_NUMBER =
/\A(?:\+)(?:\d{1,3}\s*-?)?\(?(?:\d{3})?\)?[- ]?\d{3}[- ]?\d{4}\z/

Class Method Summary collapse

Class Method Details

.call(title:, payload:) ⇒ Object

Raises:



142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/bobot/buttons.rb', line 142

def self.call(title:, payload:)
  raise Bobot::FieldFormat.new('title is required') unless title.present?
  raise Bobot::FieldFormat.new('title size is limited to 20', "#{title} (#{title.size} chars)") if title.size > 20
  raise Bobot::FieldFormat.new('payload is required') unless payload.present?
  raise Bobot::FieldFormat.new('payload has to be only a string', payload.class.to_s) unless payload.is_a?(String)
  raise Bobot::FieldFormat.new('payload has to start with a "+" and be a valid phone number', payload) unless REGEX_PHONE_NUMBER =~ payload
  {
    type: 'phone_number',
    title: title,
    payload: payload,
  }
end

.default_action(url:, options: {}) ⇒ Object

Raises:



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/bobot/buttons.rb', line 100

def self.default_action(url:, options: {})
  raise Bobot::FieldFormat.new('url is required') unless url.present?
  if options.key?(:messenger_extensions) && options[:messenger_extensions] && !url.include?('https')
    raise Bobot::FieldFormat.new('must use url HTTPS protocol if messenger_extensions is true.', url)
  end
  if options.key?(:webview_height_ratio) && !%w[compact tall full].include?(options[:webview_height_ratio])
    raise Bobot::FieldFormat.new('invalid webview_height_ratio, only "compact, tall, full" are permitted.', options[:webview_height_ratio])
  end
  {
    type: 'web_url',
    url: url,
  }.tap do |properties|
    properties[:webview_height_ratio] = options[:webview_height_ratio] if options.key?(:webview_height_ratio)
    properties[:messenger_extensions] = options[:messenger_extensions] if options.key?(:messenger_extensions)
    properties[:fallback_url] = options[:fallback_url] if options.key?(:fallback_url)
    properties[:webview_share_button] = options[:webview_share_button] if options.key?(:webview_share_button)
  end
end

.encode_payload(payload:) ⇒ Object



3
4
5
6
7
8
9
10
11
12
# File 'lib/bobot/buttons.rb', line 3

def self.encode_payload(payload:)
  unless payload.is_a?(String)
    begin
      payload = ActiveSupport::JSON.encode(payload)
    rescue ::ActiveSupport::JSON.parse_error
      raise Bobot::FieldFormat.new('payload is not string and not a valid to be JSONified.')
    end
  end
  payload
end

.generic_element(title:, subtitle: nil, image_url: nil, default_action: nil, buttons: nil) ⇒ Object Also known as: carousel_element

Raises:



27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/bobot/buttons.rb', line 27

def self.generic_element(title:, subtitle: nil, image_url: nil, default_action: nil, buttons: nil)
  raise Bobot::FieldFormat.new('title is required') unless title.present?
  raise Bobot::FieldFormat.new('title size is limited to 80', "#{title} (#{title.size} chars)") if title.size > 80
  raise Bobot::FieldFormat.new('subtitle size is limited to 80', "#{subtitle} (#{subtitle.size} chars)") if subtitle.present? && subtitle.size > 80
  raise Bobot::FieldFormat.new('buttons are limited to 3', buttons.size) if buttons.present? && buttons.size > 3
  {
    title: title,
  }.tap do |properties|
    properties[:image_url] = image_url if image_url.present?
    properties[:subtitle] = subtitle if subtitle.present?
    properties[:default_action] = default_action if default_action.present?
    properties[:buttons] = buttons if buttons.present?
  end
end

.postback(title:, payload:) ⇒ Object

Raises:



14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/bobot/buttons.rb', line 14

def self.postback(title:, payload:)
  raise Bobot::FieldFormat.new('title is required') unless title.present?
  raise Bobot::FieldFormat.new('title size is limited to 20', "#{title} (#{title.size} chars)") if title.size > 20
  raise Bobot::FieldFormat.new('payload is required') unless payload.present?
  payload = Bobot::Buttons.encode_payload(payload: payload)
  raise Bobot::FieldFormat.new('payload size is limited to 1000', "#{payload.size} chars") if payload.size > 1000
  {
    type: 'postback',
    title: title,
    payload: payload,
  }
end

.quick_reply_location(image_url: nil) ⇒ Object



45
46
47
48
49
50
51
# File 'lib/bobot/buttons.rb', line 45

def self.quick_reply_location(image_url: nil)
  {
    content_type: 'location',
  }.tap do |properties|
    properties[:image_url] = image_url if image_url.present?
  end
end

.quick_reply_text(title:, payload:, image_url: nil) ⇒ Object

Raises:



53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/bobot/buttons.rb', line 53

def self.quick_reply_text(title:, payload:, image_url: nil)
  raise Bobot::FieldFormat.new('title is required') unless title.present?
  raise Bobot::FieldFormat.new('title size is limited to 20', "#{title} (#{title.size} chars)") if title.size > 20
  raise Bobot::FieldFormat.new('payload is required') unless payload.present?
  payload = Bobot::Buttons.encode_payload(payload: payload)
  raise Bobot::FieldFormat.new('payload size is limited to 1000', "#{payload.size} chars") if payload.size > 1000
  {
    content_type: 'text',
    title: title,
    payload: payload,
  }.tap do |properties|
    properties[:image_url] = image_url if image_url.present?
  end
end

.share_basicObject



68
69
70
71
72
# File 'lib/bobot/buttons.rb', line 68

def self.share_basic
  {
    type: 'element_share',
  }
end

.share_custom(title:, subtitle:, image_url:, web_url:, button_title:, image_aspect_ratio: "square") ⇒ Object

Raises:



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/bobot/buttons.rb', line 74

def self.share_custom(title:, subtitle:, image_url:, web_url:, button_title:, image_aspect_ratio: "square")
  raise Bobot::FieldFormat.new('button_title is required') unless button_title.present?
  raise Bobot::FieldFormat.new('button_title size is limited to 20', "#{button_title} (#{button_title.size} chars)") if button_title.size > 20
  {
    type: 'element_share',
    share_contents: {
      attachment: {
        type: 'template',
        payload: {
          template_type: 'generic',
          image_aspect_ratio: image_aspect_ratio,
          elements: [
            self.generic_element(
              title: title,
              subtitle: subtitle,
              image_url: image_url,
              default_action: self.default_action(url: web_url),
              buttons: [ self.url(title: button_title, url: web_url) ]
            )
          ],
        },
      },
    },
  }
end

.url(title:, url:, options: {}) ⇒ Object

Raises:



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/bobot/buttons.rb', line 119

def self.url(title:, url:, options: {})
  raise Bobot::FieldFormat.new('title is required') unless title.present?
  raise Bobot::FieldFormat.new('title size is limited to 20', "#{title} (#{title.size} chars)") if title.size > 20
  raise Bobot::FieldFormat.new('url is required') unless url.present?
  if options.key?(:messenger_extensions) && options[:messenger_extensions] && !url.include?('https')
    raise Bobot::FieldFormat.new('must use url HTTPS protocol if messenger_extensions is true.', url)
  end
  if options.key?(:webview_height_ratio) && !%w[compact tall full].include?(options[:webview_height_ratio])
    raise Bobot::FieldFormat.new('invalid webview_height_ratio, only "compact, tall, full" are permitted.', options[:webview_height_ratio])
  end
  {
    type: 'web_url',
    url: url,
    title: title,
  }.tap do |properties|
    properties[:webview_height_ratio] = options[:webview_height_ratio] if options.key?(:webview_height_ratio)
    properties[:messenger_extensions] = options[:messenger_extensions] if options.key?(:messenger_extensions)
    properties[:fallback_url] = options[:fallback_url] if options.key?(:fallback_url)
    properties[:webview_share_button] = options[:webview_share_button] if options.key?(:webview_share_button)
  end
end