talktome 1.2.0 → 1.3.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c02c611e3628b2f56012103e2c8ae0a5bb600ee9e11a24a7c7acf748475c9380
4
- data.tar.gz: f1dadedcddd3f434298359293ef656be2f14396c7d9dd8c597ea5db2bb7a138b
3
+ metadata.gz: 61b3186927b959dff89432173c8144e50805115dfb2ce270cb82c6612797fd21
4
+ data.tar.gz: 0e2f96a0d4fcbd97e958281d0ee474afdf0dc57483181bc5427eb794c21f47e4
5
5
  SHA512:
6
- metadata.gz: 76e3843b6ec151090b9c88f26180a620d82bb737360fbb43b8f70f6f10d559401bf822f626cfde81c3edd43df253388ded9ca8761ce849c2af55262eb6e66503
7
- data.tar.gz: 5f6558c21f2eeebd114a876232be0eb2c6dfdde84d7862d105c6da2400ee55d367f1428289e572a02c64fb5e8056e4e8999a9bb28de0b2af1199c1dd5613bc73
6
+ metadata.gz: 223de995f0f58b54c09039c63228c1a4ffa581b7dbe82cf3dc2b410b03a599c06c3e88bed88ce6e89a5fbf2e78882eb40a8b55e85a88312639c5279d43a4da04
7
+ data.tar.gz: 83e62ce22e6714376bcef8adaf027ce34e2f490aa88aa80d94e19fe3cd97c47a319ca558679ffc53bf0694825103d84d7a96dc85ec8be4bb3ebeb9451632d49c
data/lib/talktome/app.rb CHANGED
@@ -13,36 +13,49 @@ module Talktome
13
13
 
14
14
  set :raise_errors, true
15
15
  set :show_exceptions, false
16
+ set :talktome, Talktome::Client::Local.new(ROOT_FOLDER/'templates')
16
17
 
17
18
  VALIDATION_SCHEMA = ::Finitio.system(<<~FIO)
18
19
  @import finitio/data
20
+ Attachment = {
21
+ mime_type : String
22
+ content : .Object
23
+ }
19
24
  Email = String(s | s =~ /^[^@]+@[^@]+$/ )
20
25
  {
21
- to :? Email
22
- reply_to :? Email
23
- ... : .Object
26
+ to :? Email
27
+ reply_to :? Email
28
+ in_reply_to :? String
29
+ attachments :? {
30
+ ... : Attachment
31
+ }
32
+ ... : .Object
24
33
  }
25
34
  FIO
26
35
 
27
- TALKTOME = Talktome::Client::Local.new(ROOT_FOLDER/'templates')
28
-
29
- post %r{/([a-z-]+)/} do |action|
36
+ post %r{/([a-z-]+([\/][a-z-]+)*)/} do |action, _|
30
37
  begin
31
38
  as_array = info.map{|k,v| {'key' => k.capitalize, 'value' => v}}
32
39
  subject = Talktome.env('TALKTOME_EMAIL_SUBJECT', 'Someone wants to reach you!')
33
40
  footer = Talktome.env('TALKTOME_EMAIL_FOOTER', "Truly yours,\n
34
41
  Sent by [Enspirit.be](https://enspirit.be/), contact us if you need help with any IT task.")
35
42
  user = load_user_from_info!
36
- TALKTOME.talktome(action, user, info.merge(allvars: as_array, subject: subject, footer: footer), [:email]){|email|
43
+ settings.talktome.talktome(action, user, info.merge(allvars: as_array, subject: subject, footer: footer), [:email]){|email|
37
44
  email.reply_to = info[:reply_to] if info.has_key?(:reply_to)
45
+ email.in_reply_to = info[:in_reply_to] if info.has_key?(:in_reply_to)
46
+ (info[:attachments] || {}).each do |name, att|
47
+ email.attachments[name.to_s] = att
48
+ end
38
49
  }
39
50
  [ 200, { "Content-Type" => "text/plain"}, ["Ok"] ]
40
51
  rescue JSON::ParserError
41
52
  fail!("Invalid data")
42
53
  rescue Finitio::Error => ex
43
54
  fail!(ex.message)
44
- rescue ::Talktome::InvalidEmailError => ex
55
+ rescue ::Talktome::InvalidEmailError
45
56
  fail!("Invalid email address")
57
+ rescue ::Talktome::TemplateNotFoundError
58
+ fail!("No such template", 404)
46
59
  end
47
60
  end
48
61
 
@@ -55,7 +68,8 @@ module Talktome
55
68
  end
56
69
 
57
70
  def load_user_from_info!
58
- if to = info[:to]
71
+ protected_fields = [:to, :in_reply_to, :attachments]
72
+ if (info.keys & protected_fields).any?
59
73
  secret = Talktome.env('TALKTOME_BEARER_SECRET')
60
74
  fail!("Missing secret", 400) unless secret
61
75
  fail!("Invalid secret", 401) unless "Bearer #{secret}" == env["HTTP_AUTHORIZATION"]
@@ -17,7 +17,7 @@ module Talktome
17
17
 
18
18
  def load_message!(identifier, strategies)
19
19
  folder = self.folder/identifier
20
- raise InvalidMessageError, "No such message `#{identifier}`" unless folder.exists?
20
+ raise TemplateNotFoundError, "No such message `#{identifier}`" unless folder.exists?
21
21
  raise InvalidMessageError, "Message `#{identifier}` should be a folder" unless folder.directory?
22
22
  strategies.each do |s|
23
23
  if (file = folder.glob("#{s}.*").first) && file.file?
@@ -2,4 +2,5 @@ module Talktome
2
2
  class Error < StandardError; end
3
3
  class InvalidMessageError < Error; end
4
4
  class InvalidEmailError < Error; end
5
+ class TemplateNotFoundError < Error; end
5
6
  end
@@ -16,6 +16,8 @@ module Talktome
16
16
  [
17
17
  :to,
18
18
  :reply_to,
19
+ :in_reply_to,
20
+ :attachments,
19
21
  :subject
20
22
  ].each do |which|
21
23
  if arg = message.metadata[which.to_s]
@@ -1,8 +1,8 @@
1
1
  module Talktome
2
2
  module Version
3
3
  MAJOR = 1
4
- MINOR = 2
5
- TINY = 0
4
+ MINOR = 3
5
+ TINY = 3
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
8
8
  end
data/spec/app/test_app.rb CHANGED
@@ -9,6 +9,7 @@ module Talktome
9
9
  }
10
10
 
11
11
  before(:each) do
12
+ Talktome::App.set :talktome, Talktome::Client::Local.new(Path.dir.parent/'fixtures')
12
13
  ENV['TALKTOME_EMAIL_DEFAULT_TO'] = "to@talktome.com"
13
14
  ENV['TALKTOME_EMAIL_DEFAULT_FROM'] = "from@talktome.com"
14
15
  Mail::TestMailer.deliveries.clear
@@ -162,5 +163,136 @@ module Talktome
162
163
  end
163
164
  end
164
165
 
166
+ context 'POST /support/, regarding the In-Reply-To' do
167
+ class ::Talktome::Message::Template
168
+ def raise_on_context_miss?
169
+ false
170
+ end
171
+ end
172
+
173
+ it 'forbids the usage of :in_reply_to unless a secret is provided' do
174
+ post "/support/", {
175
+ in_reply_to: '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@company.com>',
176
+ }.to_json, { "CONTENT_TYPE" => "application/json" }
177
+ expect(last_response.status).to eql(400)
178
+ expect(Mail::TestMailer.deliveries.length).to eql(0)
179
+ end
180
+
181
+ it 'does not allow setting the :in_reply_to without a valid AUTH token' do
182
+ Talktome.set_env('TALKTOME_BEARER_SECRET', "Invalid secret") do
183
+ post "/support/", {
184
+ in_reply_to: '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@company.com>',
185
+ }.to_json, { "CONTENT_TYPE" => "application/json" }
186
+ expect(last_response.status).to eql(401)
187
+ expect(Mail::TestMailer.deliveries.length).to eql(0)
188
+ end
189
+ end
190
+
191
+ it "lets override it by passing a inReplyTo field" do
192
+ Talktome.set_env('TALKTOME_BEARER_SECRET', "Some secret") do
193
+ header 'Authorization', 'Bearer Some secret'
194
+ post "/support/", {
195
+ to: 'client@company.com',
196
+ in_reply_to: '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@company.com>',
197
+ }.to_json, { "CONTENT_TYPE" => "application/json" }
198
+ expect(last_response).to be_ok
199
+ expect(Mail::TestMailer.deliveries.length).to eql(1)
200
+ expect(Mail::TestMailer.deliveries.first.in_reply_to).to eql('F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@company.com')
201
+ end
202
+ end
203
+ end
204
+
205
+ context 'POST /support/, regarding the attachments' do
206
+ class ::Talktome::Message::Template
207
+ def raise_on_context_miss?
208
+ false
209
+ end
210
+ end
211
+
212
+ it 'forbids the usage of :attachments unless a secret is provided' do
213
+ post "/support/", {
214
+ :to => 'client@company.com',
215
+ :attachments => {
216
+ "plain.txt" => {
217
+ "mime_type" => "plain/text",
218
+ "content" => Base64.encode64('Some plain/text attachment')
219
+ }
220
+ }
221
+ }.to_json, { "CONTENT_TYPE" => "application/json" }
222
+ expect(last_response.status).to eql(400)
223
+ expect(Mail::TestMailer.deliveries.length).to eql(0)
224
+ end
225
+
226
+ it 'does not allow setting the :attachments without a valid AUTH token' do
227
+ Talktome.set_env('TALKTOME_BEARER_SECRET', "Invalid secret") do
228
+ post "/support/", {
229
+ :to => 'client@company.com',
230
+ :attachments => {
231
+ "plain.txt" => {
232
+ "mime_type" => "plain/text",
233
+ "content" => Base64.encode64('Some plain/text attachment')
234
+ }
235
+ }
236
+ }.to_json, { "CONTENT_TYPE" => "application/json" }
237
+ expect(last_response.status).to eql(401)
238
+ expect(Mail::TestMailer.deliveries.length).to eql(0)
239
+ end
240
+ end
241
+
242
+ it "lets customize attachments by passing an array" do
243
+ Talktome.set_env('TALKTOME_BEARER_SECRET', "Some secret") do
244
+ header 'Authorization', 'Bearer Some secret'
245
+ post "/support/", {
246
+ :to => 'client@company.com',
247
+ :attachments => {
248
+ "plain.txt" => {
249
+ "mime_type" => "plain/text",
250
+ "content" => Base64.encode64('Some plain/text attachment')
251
+ }
252
+ }
253
+ }.to_json, { "CONTENT_TYPE" => "application/json" }
254
+ expect(last_response).to be_ok
255
+ expect(Mail::TestMailer.deliveries.length).to eql(1)
256
+ mail = Mail::TestMailer.deliveries.first
257
+ expect(mail.attachments['plain.txt']).to be_a_kind_of(Mail::Part)
258
+ file = mail.attachments['plain.txt']
259
+ expect(file).to be_a_kind_of(Mail::Part)
260
+ end
261
+ end
262
+ end
263
+
264
+ context 'POST /multi-lingual/en/' do
265
+
266
+ it 'works' do
267
+ post "/multi-lingual/en/", {
268
+ reply_to: 'hello@visitor.com',
269
+ message: 'Hello from visitor',
270
+ key: 'value',
271
+ }.to_json, { "CONTENT_TYPE" => "application/json" }
272
+ expect(last_response.status).to eql(200)
273
+ expect(last_response).to be_ok
274
+ expect(Mail::TestMailer.deliveries.length).to eql(1)
275
+ expect(Mail::TestMailer.deliveries.first.to).to eql(["to@talktome.com"])
276
+ expect(Mail::TestMailer.deliveries.first.from).to eql(["from@talktome.com"])
277
+ expect(Mail::TestMailer.deliveries.first.subject).to eql("Someone wants to reach you!")
278
+ expect(Mail::TestMailer.deliveries.first.html_part.body).to include("<li>Key: value</li>")
279
+ expect(Mail::TestMailer.deliveries.first.html_part.body).to include("Truly yours")
280
+ end
281
+ end
282
+
283
+ context 'POST /xxx when the template does not exist' do
284
+
285
+ it 'return a 404 error when the template doesn\'t exist' do
286
+ post "/multi-lingual/fr/", {
287
+ reply_to: 'hello@visitor.com',
288
+ message: 'Hello from visitor',
289
+ key: 'value',
290
+ }.to_json, { "CONTENT_TYPE" => "application/json" }
291
+
292
+ expect(last_response.status).to eql(404)
293
+ expect(last_response.body).to match(/No such template/)
294
+ end
295
+ end
296
+
165
297
  end
166
298
  end
@@ -74,6 +74,7 @@ module Talktome
74
74
  client.talktome("welcome", user, tpldata, [:email])
75
75
  expect(strategy.last.message.to_html).to eql("<html><title>Hello Test user</title><body><h1>Hello Test user</h1>\n\n<p>Welcome to this email example!</p>\n\n<h3>Test user</h3>\n</body></html>\n")
76
76
  end
77
+
77
78
  end
78
79
 
79
80
  end
@@ -0,0 +1,13 @@
1
+ ---
2
+ subject: |-
3
+ {{subject}}
4
+ ---
5
+ Hello,
6
+
7
+ This person is trying to reach you:
8
+
9
+ {{#allvars}}
10
+ * {{key}}: {{value}}
11
+ {{/allvars}}
12
+
13
+ {{footer}}
@@ -0,0 +1,13 @@
1
+ ---
2
+ subject: |-
3
+ {{subject}}
4
+ ---
5
+ Hello,
6
+
7
+ This person is trying to reach you:
8
+
9
+ {{#allvars}}
10
+ * {{key}}: {{value}}
11
+ {{/allvars}}
12
+
13
+ {{footer}}
@@ -0,0 +1,6 @@
1
+ ---
2
+ subject: Regarding your support request
3
+ ---
4
+ Our support team will get back to you ASAP regarding your request.
5
+
6
+ Best regards
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: talktome
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-05 00:00:00.000000000 Z
11
+ date: 2021-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -191,7 +191,10 @@ files:
191
191
  - lib/talktome/version.rb
192
192
  - spec/app/test_app.rb
193
193
  - spec/client/test_local.rb
194
+ - spec/fixtures/contact-us/email.md
194
195
  - spec/fixtures/layouts/email.html
196
+ - spec/fixtures/multi-lingual/en/email.md
197
+ - spec/fixtures/support/email.md
195
198
  - spec/fixtures/welcome/email.md
196
199
  - spec/fixtures/welcome/footer.mustache
197
200
  - spec/message/test_initialize.rb
@@ -220,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
220
223
  - !ruby/object:Gem::Version
221
224
  version: '0'
222
225
  requirements: []
223
- rubygems_version: 3.2.15
226
+ rubygems_version: 3.2.32
224
227
  signing_key:
225
228
  specification_version: 4
226
229
  summary: Talktome helps you talk to users by email, messaging, sms, etc.