xip-twilio 1.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1f408ff6f6a53eb1a47055d96f0c0a36788c7a5ac9ee1c811ff1ee5530fbd552
4
+ data.tar.gz: 3618f4ad0bd769814e8a2ec3478c55db7b07be11b6617adf8c00423e03896eff
5
+ SHA512:
6
+ metadata.gz: f0525b41729d8e520f7ac6f8164708e4ddfac0a59b0c35f9352f36b8e2e2a4d99d4dab6457ed6b1364149d9d3e26eb796902cdb902e10b31ea021f93db65118a
7
+ data.tar.gz: ea5f502da45cfc7083065c6fb3376925a7a5130b5422a0562308d61707df52ad0b07c942dfc047d4f9590d0b3e378e86068f53422f5678494b48475524293385
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'xip', '~> 2.0.0.beta'
4
+
5
+ gemspec
@@ -0,0 +1,96 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ xip-twilio (1.3.3)
5
+ twilio-ruby (~> 5.5)
6
+ xip (>= 2.0.0.beta)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (6.1.0)
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ i18n (>= 1.6, < 2)
14
+ minitest (>= 5.1)
15
+ tzinfo (~> 2.0)
16
+ zeitwerk (~> 2.3)
17
+ concurrent-ruby (1.1.7)
18
+ connection_pool (2.2.3)
19
+ diff-lcs (1.4.4)
20
+ faraday (1.1.0)
21
+ multipart-post (>= 1.2, < 3)
22
+ ruby2_keywords
23
+ i18n (1.8.5)
24
+ concurrent-ruby (~> 1.0)
25
+ jwt (2.2.2)
26
+ mini_portile2 (2.4.0)
27
+ minitest (5.14.2)
28
+ multi_json (1.15.0)
29
+ multipart-post (2.1.1)
30
+ mustermann (1.1.1)
31
+ ruby2_keywords (~> 0.0.1)
32
+ nio4r (2.5.4)
33
+ nokogiri (1.10.10)
34
+ mini_portile2 (~> 2.4.0)
35
+ puma (4.3.7)
36
+ nio4r (~> 2.0)
37
+ rack (2.2.3)
38
+ rack-protection (2.1.0)
39
+ rack
40
+ rack-test (1.1.0)
41
+ rack (>= 1.0, < 3)
42
+ redis (4.2.5)
43
+ rspec (3.9.0)
44
+ rspec-core (~> 3.9.0)
45
+ rspec-expectations (~> 3.9.0)
46
+ rspec-mocks (~> 3.9.0)
47
+ rspec-core (3.9.2)
48
+ rspec-support (~> 3.9.3)
49
+ rspec-expectations (3.9.2)
50
+ diff-lcs (>= 1.2.0, < 2.0)
51
+ rspec-support (~> 3.9.0)
52
+ rspec-mocks (3.9.1)
53
+ diff-lcs (>= 1.2.0, < 2.0)
54
+ rspec-support (~> 3.9.0)
55
+ rspec-support (3.9.3)
56
+ rspec_junit_formatter (0.4.1)
57
+ rspec-core (>= 2, < 4, != 2.12.0)
58
+ ruby2_keywords (0.0.2)
59
+ sidekiq (6.1.2)
60
+ connection_pool (>= 2.2.2)
61
+ rack (~> 2.0)
62
+ redis (>= 4.2.0)
63
+ sinatra (2.1.0)
64
+ mustermann (~> 1.0)
65
+ rack (~> 2.2)
66
+ rack-protection (= 2.1.0)
67
+ tilt (~> 2.0)
68
+ thor (1.0.1)
69
+ tilt (2.0.10)
70
+ twilio-ruby (5.45.1)
71
+ faraday (>= 0.9, < 2.0)
72
+ jwt (>= 1.5, <= 2.5)
73
+ nokogiri (>= 1.6, < 2.0)
74
+ tzinfo (2.0.4)
75
+ concurrent-ruby (~> 1.0)
76
+ xip (2.0.0.beta2)
77
+ activesupport (~> 6.0)
78
+ multi_json (~> 1.12)
79
+ puma (>= 4.2, < 5.0)
80
+ sidekiq (~> 6.0)
81
+ sinatra (~> 2.0)
82
+ thor (~> 1.0)
83
+ zeitwerk (2.4.2)
84
+
85
+ PLATFORMS
86
+ ruby
87
+
88
+ DEPENDENCIES
89
+ rack-test (~> 1.1)
90
+ rspec (~> 3)
91
+ rspec_junit_formatter (~> 0.3)
92
+ xip (~> 2.0.0.beta)
93
+ xip-twilio!
94
+
95
+ BUNDLED WITH
96
+ 2.1.4
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2017-2020 Mauricio Gomes
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ # Twilio SMS and Whatsapp Xip Kit Component
2
+
3
+ The [Xip Kit](https://github.com/xipkit/xip) Twilio SMS and Whatsapp component adds the ability to connect your bot to the Whatsapp and SMS platforms.
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/xip-twilio.svg)](https://badge.fury.io/rb/xip-twilio)
6
+
7
+ ## Supported Reply Types
8
+
9
+ * Text
10
+ * Image
11
+ * Audio
12
+ * Video
13
+ * File
14
+ * Delay
15
+
16
+ Image, Audio, Video, and File reply types will leverage the MMS protocol. It is recommended by Twilio that
17
+ the content is limited to images, however, this is the full list of supported content types: https://www.twilio.com/docs/api/messaging/accepted-mime-types.
18
+
19
+ If you store your files on S3, please make sure you have set the `content-type` appropriately or Twilio might reject your media.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.3.3
@@ -0,0 +1 @@
1
+ require 'xip/twilio'
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'twilio-ruby'
4
+
5
+ require 'xip/services/twilio/message_handler'
6
+ require 'xip/services/twilio/reply_handler'
7
+ require 'xip/services/twilio/setup'
8
+
9
+ module Xip
10
+ module Services
11
+ module Twilio
12
+ class Client < Xip::Services::BaseClient
13
+
14
+ attr_reader :twilio_client, :reply
15
+
16
+ def initialize(reply:)
17
+ @reply = reply
18
+ account_sid = Xip.config.twilio.account_sid
19
+ api_key = Xip.config.twilio.api_key
20
+ auth_token = Xip.config.twilio.auth_token
21
+
22
+ if api_key.present?
23
+ @twilio_client = ::Twilio::REST::Client.new(
24
+ api_key, auth_token, account_sid
25
+ )
26
+ else
27
+ @twilio_client = ::Twilio::REST::Client.new(account_sid, auth_token)
28
+ end
29
+ end
30
+
31
+ def transmit
32
+ # Don't transmit anything for delays
33
+ return true if reply.blank?
34
+
35
+ begin
36
+ response = twilio_client.messages.create(reply)
37
+ rescue ::Twilio::REST::RestError => e
38
+ case e.message
39
+ when /21610/ # Attempt to send to unsubscribed recipient
40
+ raise Xip::Errors::UserOptOut
41
+ when /21612/ # 'To' phone number is not currently reachable via SMS
42
+ raise Xip::Errors::UserOptOut
43
+ when /21614/ # 'To' number is not a valid mobile number
44
+ raise Xip::Errors::UserOptOut
45
+ when /30004/ # Message blocked
46
+ raise Xip::Errors::UserOptOut
47
+ when /21211/ # Invalid 'To' Phone Number
48
+ raise Xip::Errors::InvalidSessionID
49
+ when /30003/ # Unreachable destination handset
50
+ raise Xip::Errors::InvalidSessionID
51
+ when /30005/ # Unknown destination handset
52
+ raise Xip::Errors::InvalidSessionID
53
+ else
54
+ raise
55
+ end
56
+ end
57
+
58
+ Xip::Logger.l(
59
+ topic: "twilio",
60
+ message: "Transmitting. Response: #{response.status}: #{response.error_message}"
61
+ )
62
+ end
63
+
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Xip
4
+ module Services
5
+ module Twilio
6
+ class MessageHandler < Xip::Services::BaseMessageHandler
7
+ attr_reader :service_message, :params, :headers
8
+
9
+ def initialize(params:, headers:)
10
+ @params = params
11
+ @headers = headers
12
+ end
13
+
14
+ def coordinate
15
+ Xip::Services::HandleMessageJob.perform_async(
16
+ 'twilio',
17
+ params,
18
+ headers
19
+ )
20
+
21
+ # Relay our acceptance
22
+ [204, 'No Content']
23
+ end
24
+
25
+ def process
26
+ @service_message = ServiceMessage.new(service: 'twilio')
27
+ service_message.sender_id = params['From']
28
+ service_message.target_id = params['To']
29
+ service_message.message = params['Body']
30
+
31
+ # Check for media attachments
32
+ attachment_count = params['NumMedia'].to_i
33
+
34
+ attachment_count.times do |i|
35
+ service_message.attachments << {
36
+ type: params["MediaContentType#{i}"],
37
+ url: params["MediaUrl#{i}"]
38
+ }
39
+ end
40
+
41
+ service_message
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Xip
4
+ module Services
5
+ module Twilio
6
+ class ReplyHandler < Xip::Services::BaseReplyHandler
7
+
8
+ ALPHA_ORDINALS = ('A'..'Z').to_a.freeze
9
+
10
+ attr_reader :recipient_id, :reply
11
+
12
+ def initialize(recipient_id: nil, reply: nil)
13
+ @recipient_id = recipient_id
14
+ @reply = reply
15
+ end
16
+
17
+ def text
18
+ check_text_length
19
+
20
+ translated_reply = reply['text']
21
+
22
+ suggestions = generate_suggestions(suggestions: reply['suggestions'])
23
+ buttons = generate_buttons(buttons: reply['buttons'])
24
+
25
+ if suggestions.present?
26
+ translated_reply = [
27
+ translated_reply,
28
+ 'Reply with:'
29
+ ].join("\n\n")
30
+
31
+ suggestions.each_with_index do |suggestion, i|
32
+ translated_reply = [
33
+ translated_reply,
34
+ "\"#{ALPHA_ORDINALS[i]}\" for #{suggestion}"
35
+ ].join("\n")
36
+ end
37
+ end
38
+
39
+ if buttons.present?
40
+ buttons.each do |button|
41
+ translated_reply = [
42
+ translated_reply,
43
+ button
44
+ ].join("\n\n")
45
+ end
46
+ end
47
+
48
+ format_response({ body: translated_reply })
49
+ end
50
+
51
+ def image
52
+ check_text_length
53
+
54
+ format_response({ body: reply['text'], media_url: reply['image_url'] })
55
+ end
56
+
57
+ def audio
58
+ check_text_length
59
+
60
+ format_response({ body: reply['text'], media_url: reply['audio_url'] })
61
+ end
62
+
63
+ def video
64
+ check_text_length
65
+
66
+ format_response({ body: reply['text'], media_url: reply['video_url'] })
67
+ end
68
+
69
+ def file
70
+ check_text_length
71
+
72
+ format_response({ body: reply['text'], media_url: reply['file_url'] })
73
+ end
74
+
75
+ def delay
76
+
77
+ end
78
+
79
+ private
80
+
81
+ def check_text_length
82
+ if reply['text'].present? && reply['text'].size > 1600
83
+ raise(ArgumentError, 'Text messages must be 1600 characters or less.')
84
+ end
85
+ end
86
+
87
+ def format_response(response)
88
+ sender_info = {
89
+ from: Stealth.config.twilio.from_phone,
90
+ to: recipient_id
91
+ }
92
+ response.merge(sender_info)
93
+ end
94
+
95
+ def generate_suggestions(suggestions:)
96
+ return if suggestions.blank?
97
+
98
+ mf = suggestions.collect do |suggestion|
99
+ suggestion['text']
100
+ end.compact
101
+ end
102
+
103
+ def generate_buttons(buttons:)
104
+ return if buttons.blank?
105
+
106
+ sms_buttons = buttons.map do |button|
107
+ case button['type']
108
+ when 'url'
109
+ "#{button['text']}: #{button['url']}"
110
+ when 'payload'
111
+ "To #{button['text'].downcase}: Text #{button['payload'].upcase}"
112
+ when 'call'
113
+ "#{button['text']}: #{button['phone_number']}"
114
+ else # Don't raise for unsupported buttons
115
+ next
116
+ end
117
+ end.compact
118
+
119
+ sms_buttons
120
+ end
121
+
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'xip/services/twilio/client'
4
+
5
+ module Xip
6
+ module Services
7
+ module Twilio
8
+
9
+ class Setup
10
+
11
+ class << self
12
+ def trigger
13
+ Xip::Logger.l(
14
+ topic: "twilio",
15
+ message: "There is no setup needed!"
16
+ )
17
+ end
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Xip
4
+ module Services
5
+ module Twilio
6
+ module Version
7
+ def self.version
8
+ File.read(File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'VERSION')).strip
9
+ end
10
+ end
11
+
12
+ VERSION = Version.version
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,2 @@
1
+ require 'xip/services/twilio/version'
2
+ require 'xip/services/twilio/client'
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+
5
+ require 'xip'
6
+ require 'xip-twilio'
7
+
8
+ # Requires supporting files with custom matchers and macros, etc,
9
+ # in ./support/ and its subdirectories.
10
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
11
+
12
+ RSpec.configure do |config|
13
+
14
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
4
+
5
+ describe "Xip::Services::Twilio::Version" do
6
+
7
+ let(:version_in_file) { File.read(File.join(File.dirname(__FILE__), '..', 'VERSION')).strip }
8
+
9
+ it "should return the current gem version" do
10
+ expect(Xip::Services::Twilio::Version.version).to eq version_in_file
11
+ end
12
+
13
+ it "should return the current gem version via a constant" do
14
+ expect(Xip::Services::Twilio::VERSION).to eq version_in_file
15
+ end
16
+ end
@@ -0,0 +1,26 @@
1
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
+
3
+ version = File.read(File.join(File.dirname(__FILE__), 'VERSION')).strip
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'xip-twilio'
7
+ s.summary = 'Twilio SMS and Whatsapp Xip Kit component'
8
+ s.description = 'Twilio SMS and Whatsapp Xip Kit component.'
9
+ s.homepage = 'https://github.com/xipkit/xip-twilio'
10
+ s.licenses = ['MIT']
11
+ s.version = version
12
+ s.author = 'Mauricio Gomes'
13
+ s.email = 'mauricio@edge14.com'
14
+
15
+ s.add_dependency 'xip', '~> 2.0.0.beta'
16
+ s.add_dependency 'twilio-ruby', '~> 5.5'
17
+
18
+ s.add_development_dependency 'rspec', '~> 3'
19
+ s.add_development_dependency 'rspec_junit_formatter', '~> 0.3'
20
+ s.add_development_dependency 'rack-test', '~> 1.1'
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
25
+ s.require_paths = ['lib']
26
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xip-twilio
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.3.3
5
+ platform: ruby
6
+ authors:
7
+ - Mauricio Gomes
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-12-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: xip
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.0.beta
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.0.beta
27
+ - !ruby/object:Gem::Dependency
28
+ name: twilio-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.5'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec_junit_formatter
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rack-test
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.1'
83
+ description: Twilio SMS and Whatsapp Xip Kit component.
84
+ email: mauricio@edge14.com
85
+ executables: []
86
+ extensions: []
87
+ extra_rdoc_files: []
88
+ files:
89
+ - Gemfile
90
+ - Gemfile.lock
91
+ - LICENSE
92
+ - README.md
93
+ - VERSION
94
+ - lib/xip-twilio.rb
95
+ - lib/xip/services/twilio/client.rb
96
+ - lib/xip/services/twilio/message_handler.rb
97
+ - lib/xip/services/twilio/reply_handler.rb
98
+ - lib/xip/services/twilio/setup.rb
99
+ - lib/xip/services/twilio/version.rb
100
+ - lib/xip/twilio.rb
101
+ - spec/spec_helper.rb
102
+ - spec/version_spec.rb
103
+ - xip-twilio.gemspec
104
+ homepage: https://github.com/xipkit/xip-twilio
105
+ licenses:
106
+ - MIT
107
+ metadata: {}
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubygems_version: 3.1.2
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: Twilio SMS and Whatsapp Xip Kit component
127
+ test_files:
128
+ - spec/spec_helper.rb
129
+ - spec/version_spec.rb