talktome 0.2.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b12474ba945a8c289bc358c4e654667ac7684618b3c19f3babd74dcd6c4dd2dd
4
- data.tar.gz: e3a4ebaaa0796bae48cc52e978c3aee64aade68cd80c654616171f9bf49da783
3
+ metadata.gz: d6ec4ba471da7a770b79a04a0f30cd58514f0d43b72d66b15074f2fa984887bd
4
+ data.tar.gz: 8a58f1a1e7af3440a8066e11b2fa44e4aa606c595c5b9d9e6952dd0b22d6fb97
5
5
  SHA512:
6
- metadata.gz: a64d48bc5544b99ae7868a10d2435b390526ccf9a95fc0ca323952264cb933749d20aea08365b3d9f995143df7514f7624e40dc69b2398791750149db2abc21e
7
- data.tar.gz: 9253bdbe2c08c1b75a6eeb9bb4a5e0dbfb6402365d9e925fe64282e872e034bd71da900eb235fe8e674ecd6e586b3a73a81a832775267c21b10f4f5ad1365a95
6
+ metadata.gz: 7340d04e04977b3d1a4a5def53d02b141a108e67514886f57d0d22dc87dfe340fe3a52d8f4552e7bd074229ba841256bb8006bfc900485b48cd8f0aa86522b39
7
+ data.tar.gz: 961f6e4931782c5b0f0e732c9ab3a5ea0578efe76e0346bbd8782f3b21a3a8ecd58731b51e3d3dd2e32ccb0c2d9ef48f3081f1e2f810722fbb6320348deef796
data/LICENSE.md CHANGED
@@ -1,22 +1,20 @@
1
- # The MIT Licence
1
+ Copyright (c) 2017-2021 - Enspirit SPRL (Bernard Lambeau)
2
2
 
3
- Copyright (c) 2017 - Enspirit SPRL (Bernard Lambeau)
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
4
10
 
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
12
13
 
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,3 +1,134 @@
1
1
  # Talktome - Talk to users easily
2
2
 
3
- ...
3
+ [![Build Status](https://travis-ci.com/enspirit/talktome.svg?branch=master)](https://travis-ci.com/enspirit/talktome)
4
+
5
+ Talktome helps talking to users (by email for now, but later we aim to add support
6
+ for various notification systems) easily. As a ruby gem to be used programmatically,
7
+ or as a docker container exposing web services (different use cases, see below).
8
+
9
+ ## Using Talktome programmatically
10
+
11
+ Using Talktome programmatically is useful to send transactional emails to users.
12
+
13
+ ```
14
+ require 'talktome'
15
+ CLIENT = Talktome::Client::Local.new(path_to_templates)
16
+
17
+ # later on
18
+ CLIENT.talktome(template_name, user, template_info, strategies)
19
+
20
+ # typically, the will send an email to foo@bar.com instantiating
21
+ # the email found in path_to_templates/hello/email.md and
22
+ # instantiated using mustache and markdown
23
+ CLIENT.talktome("hello", {email: 'foo@bar.com'}, {}, [:email])
24
+ ```
25
+
26
+ ## Using Talktome using the docker image
27
+
28
+ The docker image aims at supporting another category of use cases, such as providing
29
+ a reusable backend for contact forms.
30
+
31
+ ```
32
+ docker run \
33
+ -p4567:4567 \
34
+ -e TALKTOME_EMAIL_DEFAULT_FROM=info@mydomain.com
35
+ -e TALKTOME_EMAIL_DEFAULT_TO=support@mydomain.com
36
+ enspirit/talktome
37
+ ```
38
+
39
+ Send an contact-us email through the web api using curl, as follows:
40
+
41
+ ```
42
+ curl -XPOST \
43
+ -H'Content-Type: application/json' \
44
+ -d'{"reply_to": "someone@foo.bar", "message": "Hello"}' \
45
+ http://127.0.0.1:4567/contact-us/
46
+ ```
47
+
48
+ This web API does not allow specifying `from` and `to` as input data to avoid
49
+ exposing a way to send SPAM easily.
50
+
51
+ ### Overriding templates (and having more than one endpoint)
52
+
53
+ The default image comes with a single contact-us email template used by Enspirit.
54
+ Feel free to override it by providing one or more email templates.
55
+
56
+ You can mount a volume with email templates into `/app/templates/`, which will
57
+ be used for the available endpoints. For instance, the following `templates/`
58
+ folder will expose two endpoints with possibly different behaviors (according
59
+ to the templates themselves):
60
+
61
+ ```
62
+ templates/
63
+ contact-us/
64
+ email.md
65
+ report-issue/
66
+ email.md
67
+ ```
68
+
69
+ Two usual ways to do so in docker: commandline or Dockerfile. On commandline,
70
+ use the following option:
71
+
72
+ ```
73
+ -v ${PWD}/my-templates:/app/templates
74
+ ```
75
+
76
+ In a Dockerfile, add your templates:
77
+
78
+ ```
79
+ FROM enspirit/talktome
80
+
81
+ COPY ./templates /app/templates
82
+ ```
83
+
84
+ ## Configuring Talktome
85
+
86
+ The easiest way to configure Talktome is through environment variables. The following
87
+ ones are supported:
88
+
89
+ ```
90
+ TALKTOME_DEBUG when set enables the dumping of sent messages to ./tmp folder
91
+
92
+ TALKTOME_EMAIL_DELIVERY smtp, file or test (see ruby Mail library)
93
+ TALKTOME_EMAIL_DEFAULT_FROM default From: to use for email sending
94
+ TALKTOME_EMAIL_DEFAULT_REPLYTO default Reply-To: to use for email sending
95
+ TALKTOME_EMAIL_DEFAULT_TO default To: to use for email sending
96
+
97
+ TALKTOME_SMTP_ADDRESS host address for smtp sending
98
+ TALKTOME_SMTP_PORT port of smtp server to use
99
+ TALKTOME_SMTP_DOMAIN sending domain
100
+ TALKTOME_SMTP_USER user for smtp authentication
101
+ TALKTOME_SMTP_PASSWORD password for smtp authentication
102
+ TALKTOME_SMTP_STARTTLS_AUTO true or false (see ruby Mail library)
103
+ ```
104
+
105
+ ## Hacking Talktome
106
+
107
+ In pure Ruby:
108
+
109
+ ```
110
+ bundle install
111
+ bundle exec rake test
112
+ ```
113
+
114
+ Or using docker, please then use the `make` targets initially cooked for Jenkins:
115
+
116
+ ```
117
+ make image
118
+ make test
119
+ ```
120
+
121
+ ## Contributing
122
+
123
+ Please use github issues for questions and bugs, and pull requests for
124
+ submitting improvement proposals and new features.
125
+
126
+ ## Contributors
127
+
128
+ Enspirit (https://enspirit.be) and Klaro App (https://klaro.cards) are
129
+ both actively using, contributing and funding work on this library.
130
+ Please contact Bernard Lambeau for any question.
131
+
132
+ ## Licence
133
+
134
+ Webspicy is distributed under a MIT Licence, by Enspirit SRL.
data/lib/talktome.rb CHANGED
@@ -4,25 +4,39 @@ require 'mustache'
4
4
  require 'redcarpet'
5
5
  module Talktome
6
6
 
7
+ # Root folder of the project structure
8
+ ROOT_FOLDER = Path.backfind('.[Gemfile]') or raise("Missing Gemfile")
9
+
10
+ def env(which, default = nil)
11
+ if ENV.has_key?(which)
12
+ got = ENV[which].to_s.strip
13
+ return got unless got.empty?
14
+ end
15
+ default
16
+ end
17
+ module_function :env
18
+
19
+ def with_env(which, &bl)
20
+ env(which).tap{|x|
21
+ bl.call(x) unless x.nil?
22
+ }
23
+ end
24
+ module_function :with_env
25
+
26
+ def set_env(which, value, &bl)
27
+ old, ENV[which] = ENV[which], value
28
+ bl.call.tap{
29
+ ENV[which] = old unless old.nil?
30
+ }
31
+ end
32
+ module_function :set_env
33
+
7
34
  def redcarpet
8
35
  @redcarpet ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML, extensions = {})
9
36
  end
10
37
  module_function :redcarpet
11
38
 
12
- #
13
39
  # Infer all client and strategy options from environment variables.
14
- # The following ones are recognized:
15
- #
16
- # - TALKTOME_DEBUG: when set (to anything) enables the dumping of sent
17
- # messages to the debug folder
18
- # - TALKTOME_EMAIL_DELIVERY: "smtp", "file" or "test"
19
- # - TALKTOME_EMAIL_DEFAULT_FROM: default from address to use for email sending
20
- # - TALKTOME_SMTP_ADDRESS: host address for smtp sending
21
- # - TALKTOME_SMTP_PORT: port of smtp server to use
22
- # - TALKTOME_SMTP_DOMAIN: sending domain
23
- # - TALKTOME_SMTP_USER: user for smtp authentication
24
- # - TALKTOME_SMTP_PASSWORD: user for smtp authentication
25
- #
26
40
  def auto_options(folder)
27
41
  options = {}
28
42
  debug_folder = folder/"tmp"
@@ -40,10 +54,11 @@ module Talktome
40
54
 
41
55
  email_config.merge!({
42
56
  address: ENV['TALKTOME_SMTP_ADDRESS'],
43
- port: ENV['TALKTOME_SMTP_PORT'],
57
+ port: ENV['TALKTOME_SMTP_PORT'].to_i,
44
58
  domain: ENV['TALKTOME_SMTP_DOMAIN'],
45
59
  user_name: ENV['TALKTOME_SMTP_USER'],
46
- password: ENV['TALKTOME_SMTP_PASSWORD']
60
+ password: ENV['TALKTOME_SMTP_PASSWORD'],
61
+ enable_starttls_auto: (ENV['TALKTOME_SMTP_STARTTLS_AUTO'] != 'false')
47
62
  }) if email_delivery == :smtp
48
63
 
49
64
  email_config.merge!({
@@ -52,7 +67,15 @@ module Talktome
52
67
 
53
68
  options[:strategies][:email] = ::Talktome::Strategy::Email.new{|email|
54
69
  email.delivery_method(email_delivery, email_config)
55
- email.from(ENV['TALKTOME_EMAIL_DEFAULT_FROM']) if ENV['TALKTOME_EMAIL_DEFAULT_FROM']
70
+ with_env('TALKTOME_EMAIL_DEFAULT_FROM'){|default|
71
+ email.from(default)
72
+ }
73
+ with_env('TALKTOME_EMAIL_DEFAULT_TO'){|default|
74
+ email.to(default)
75
+ }
76
+ with_env('TALKTOME_EMAIL_DEFAULT_REPLYTO'){|default|
77
+ email.reply_to(default)
78
+ }
56
79
  }
57
80
 
58
81
  options
@@ -0,0 +1,61 @@
1
+ require 'sinatra'
2
+ require 'finitio'
3
+ require 'rack/robustness'
4
+ module Talktome
5
+ class App < Sinatra::Application
6
+
7
+ use Rack::Robustness do |g|
8
+ g.catch_all
9
+ g.status 500
10
+ g.content_type 'text/plain'
11
+ g.body{ "An error occured." }
12
+ end
13
+
14
+ set :raise_errors, true
15
+ set :show_exceptions, false
16
+
17
+ VALIDATION_SCHEMA = ::Finitio.system(<<~FIO)
18
+ @import finitio/data
19
+ Email = String(s | s =~ /^[^@]+@[^@]+$/ )
20
+ {
21
+ reply_to :? Email
22
+ ... : .Object
23
+ }
24
+ FIO
25
+
26
+ TALKTOME = Talktome::Client::Local.new(ROOT_FOLDER/'templates')
27
+
28
+ post %r{/([a-z-]+)/} do |action|
29
+ begin
30
+ TALKTOME.talktome(action, {}, info, [:email]){|email|
31
+ email.reply_to = info[:reply_to] if info.has_key?(:reply_to)
32
+ }
33
+ [ 200, { "Content-Type" => "text/plain"}, ["Ok"] ]
34
+ rescue JSON::ParserError
35
+ fail!("Invalid data")
36
+ rescue Finitio::Error => ex
37
+ fail!(ex.message)
38
+ rescue ::Talktome::InvalidEmailError => ex
39
+ fail!("Invalid email address")
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def info
46
+ @info ||= VALIDATION_SCHEMA.dress(JSON.parse(request.body.read)).tap{|info|
47
+ not_a_robot!(info)
48
+ }
49
+ end
50
+
51
+ def fail!(message)
52
+ [ 400, { "Content-Type" => "text/plain"}, [message] ]
53
+ end
54
+
55
+ def not_a_robot!(info)
56
+ # `reply_to_confirm` is a honeypot field, if it's filled it means it's a bot and an error is thrown
57
+ raise ::Talktome::InvalidEmailError if info[:reply_to_confirm] && info[:reply_to_confirm] =~ /^[^@]+@[^@]+$/
58
+ end
59
+
60
+ end # class App
61
+ end # module Talktome
@@ -1,4 +1,5 @@
1
1
  module Talktome
2
2
  class Error < StandardError; end
3
3
  class InvalidMessageError < Error; end
4
+ class InvalidEmailError < Error; end
4
5
  end
@@ -9,10 +9,23 @@ module Talktome
9
9
  end
10
10
 
11
11
  def send_message(message, user)
12
+ # Take a base email, with all info coming from the environment (if set)
12
13
  mail = base_email
13
- mail.to = users(user).map{|u| u[:email] }
14
- mail.reply_to = message.metadata["reply_to"] if message.metadata.has_key?("reply_to")
15
- mail.subject = message.metadata["subject"]
14
+
15
+ # Override environment defaults with template behavior, for flexibility
16
+ [
17
+ :to,
18
+ :reply_to,
19
+ :subject
20
+ ].each do |which|
21
+ if arg = message.metadata[which.to_s]
22
+ mail.send(:"#{which}=", arg)
23
+ end
24
+ end
25
+
26
+ # If the user is actually known from source code behavior, override the
27
+ # `mail.to` to send the email to that particular person.
28
+ mail.to = user[:email] if user.has_key?(:email)
16
29
 
17
30
  case message.extension
18
31
  when 'md', 'html', 'htm'
@@ -37,10 +50,6 @@ module Talktome
37
50
 
38
51
  private
39
52
 
40
- def users(user)
41
- user.is_a?(Array) ? user : [user]
42
- end
43
-
44
53
  def base_email
45
54
  default_email = Mail.new
46
55
  @defaulter.call(default_email) if @defaulter
@@ -1,8 +1,8 @@
1
1
  module Talktome
2
2
  module Version
3
- MAJOR = 0
4
- MINOR = 2
5
- TINY = 1
3
+ MAJOR = 1
4
+ MINOR = 0
5
+ TINY = 0
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
8
8
  end
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+
3
+ module Talktome
4
+ describe App do
5
+ include Rack::Test::Methods
6
+
7
+ let(:app) {
8
+ Talktome::App.new
9
+ }
10
+
11
+ before(:each) do
12
+ ENV['TALKTOME_EMAIL_DEFAULT_TO'] = "to@talktome.com"
13
+ ENV['TALKTOME_EMAIL_DEFAULT_FROM'] = "from@talktome.com"
14
+ Mail::TestMailer.deliveries.clear
15
+ end
16
+
17
+ context 'POST /contact-us/, the basic contract' do
18
+
19
+ it 'works' do
20
+ post "/contact-us/", {
21
+ reply_to: 'hello@visitor.com',
22
+ message: 'Hello from visitor'
23
+ }.to_json, { "CONTENT_TYPE" => "application/json" }
24
+ expect(last_response).to be_ok
25
+ expect(Mail::TestMailer.deliveries.length).to eql(1)
26
+ expect(Mail::TestMailer.deliveries.first.to).to eql(["to@talktome.com"])
27
+ expect(Mail::TestMailer.deliveries.first.from).to eql(["from@talktome.com"])
28
+ expect(Mail::TestMailer.deliveries.first.subject).to eql("Someone wants to reach you!")
29
+ end
30
+
31
+ it 'detects invalid emails' do
32
+ post "/contact-us/", {
33
+ reply_to: 'helloatvisitor.com',
34
+ message: 'Hello from visitor'
35
+ }.to_json, { "CONTENT_TYPE" => "application/json" }
36
+ expect(last_response.status).to eql(400)
37
+ expect(Mail::TestMailer.deliveries.length).to eql(0)
38
+ end
39
+
40
+ it "detects invalid bodies" do
41
+ post "/contact-us/", body: "foobar"
42
+ expect(last_response.status).to eql(400)
43
+ expect(Mail::TestMailer.deliveries.length).to eql(0)
44
+ end
45
+
46
+ it "detects stupid bots at least" do
47
+ post "/contact-us/", {
48
+ reply_to: 'hello@visitor.com',
49
+ message: 'Hello from visitor',
50
+ reply_to_confirm: 'hello@visitor.com'
51
+ }.to_json, { "CONTENT_TYPE" => "application/json" }
52
+ expect(last_response.status).to eql(400)
53
+ expect(Mail::TestMailer.deliveries.length).to eql(0)
54
+ end
55
+
56
+ end
57
+
58
+ context 'POST /contact-us/, regarding the Reply-To' do
59
+ class ::Talktome::Message::Template
60
+ def raise_on_context_miss?
61
+ false
62
+ end
63
+ end
64
+
65
+ around(:each) do |bl|
66
+ Talktome.set_env('TALKTOME_EMAIL_DEFAULT_REPLYTO', "replyto@talktome.com", &bl)
67
+ end
68
+
69
+ it 'takes the default value from environment if set' do
70
+ post "/contact-us/", {
71
+ message: 'Hello from visitor'
72
+ }.to_json, { "CONTENT_TYPE" => "application/json" }
73
+ expect(last_response).to be_ok
74
+ expect(Mail::TestMailer.deliveries.length).to eql(1)
75
+ expect(Mail::TestMailer.deliveries.first.reply_to).to eql(["replyto@talktome.com"])
76
+ end
77
+
78
+ it "lets override it by passing a replyTo field" do
79
+ post "/contact-us/", {
80
+ reply_to: 'hello@visitor.com',
81
+ message: 'Hello from visitor'
82
+ }.to_json, { "CONTENT_TYPE" => "application/json" }
83
+ expect(last_response).to be_ok
84
+ expect(Mail::TestMailer.deliveries.length).to eql(1)
85
+ expect(Mail::TestMailer.deliveries.first.reply_to).to eql(["hello@visitor.com"])
86
+ end
87
+ end
88
+
89
+ end
90
+ end
@@ -3,16 +3,8 @@ module Talktome
3
3
  class Client
4
4
  describe Local do
5
5
 
6
- let(:user) {
7
- { email: "user@test.com" }
8
- }
9
-
10
- let(:tpldata) {
11
- { who: "Test user" }
12
- }
13
-
14
- let(:folder) {
15
- Path.dir/"../fixtures"
6
+ let(:strategy) {
7
+ Strategy::Debug.new
16
8
  }
17
9
 
18
10
  let(:client){
@@ -21,92 +13,53 @@ module Talktome
21
13
  end
22
14
  }
23
15
 
24
- context 'with a debug strategy' do
25
- let(:strategy) {
26
- Strategy::Debug.new
27
- }
28
-
29
- before(:each) {
30
- strategy.clear!
31
- }
32
-
33
- context "without templates" do
34
- let(:options) {
35
- {}
36
- }
16
+ let(:folder) {
17
+ Path.dir/"../fixtures"
18
+ }
37
19
 
38
- it 'sends email when requested' do
39
- client.talktome("welcome", user, tpldata, [:email])
40
- expect(strategy.last.message).not_to be_nil
41
- expect(strategy.last.message.to_html).to eql("<h1>Hello Test user</h1>\n\n<p>Welcome to this email example!</p>\n\n<h3>Test user</h3>\n")
42
- end
20
+ let(:user) {
21
+ { email: "user@test.com" }
22
+ }
43
23
 
44
- it 'lets send the same email to multiple users' do
45
- client.talktome("welcome", [user], tpldata, [:email])
46
- expect(strategy.last.message).not_to be_nil
47
- expect(strategy.last.message.to_html).to eql("<h1>Hello Test user</h1>\n\n<p>Welcome to this email example!</p>\n\n<h3>Test user</h3>\n")
48
- end
49
- end
24
+ let(:tpldata) {
25
+ { who: "Test user" }
26
+ }
50
27
 
51
- context "with templates" do
52
- let(:options) {
53
- {
54
- templates: Path.dir/"../fixtures/templates"
55
- }
56
- }
28
+ before(:each) {
29
+ strategy.clear!
30
+ }
57
31
 
58
- it 'sends email when requested' do
59
- client.talktome("welcome", user, tpldata, [:email])
60
- expect(strategy.last.message).not_to be_nil
61
- 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")
62
- end
32
+ context "without templates" do
33
+ let(:options) {
34
+ {}
35
+ }
63
36
 
64
- it 'yields the callback with the email' do
65
- seen = nil
66
- client.talktome("welcome", user, tpldata, [:email]){|m|
67
- seen = m
68
- }
69
- expect(seen).not_to be_nil
70
- end
37
+ it 'sends email when requested' do
38
+ client.talktome("welcome", user, tpldata, [:email])
39
+ expect(strategy.last.message).not_to be_nil
40
+ expect(strategy.last.message.to_html).to eql("<h1>Hello Test user</h1>\n\n<p>Welcome to this email example!</p>\n\n<h3>Test user</h3>\n")
71
41
  end
72
42
  end
73
43
 
74
- context 'with an email strategy' do
75
- before do
76
- Mail.defaults do
77
- delivery_method :test
78
- end
79
- Mail::TestMailer.deliveries = []
80
- end
81
-
44
+ context "with templates" do
82
45
  let(:options) {
83
- {}
84
- }
85
-
86
- let(:strategy) {
87
- Strategy::Email.new({}){|m|
88
- m.from "hello@test.com"
46
+ {
47
+ templates: Path.dir/"../fixtures/templates"
89
48
  }
90
49
  }
91
50
 
92
51
  it 'sends email when requested' do
93
52
  client.talktome("welcome", user, tpldata, [:email])
94
- mail = Mail::TestMailer.deliveries.first
95
- expect(mail).not_to be_nil
96
- expect(mail.from).to eql(["hello@test.com"])
97
- expect(mail.to).to eql(["user@test.com"])
53
+ expect(strategy.last.message).not_to be_nil
54
+ 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")
98
55
  end
99
56
 
100
- it 'allows sending email to multiple users' do
101
- client.talktome("welcome", [
102
- { email: "user1@test.com" },
103
- { email: "user2@test.com" }
104
- ], tpldata, [:email])
105
- expect(Mail::TestMailer.deliveries.length).to eql(1)
106
- mail = Mail::TestMailer.deliveries.first
107
- expect(mail).not_to be_nil
108
- expect(mail.from).to eql(["hello@test.com"])
109
- expect(mail.to).to eql(["user1@test.com", "user2@test.com"])
57
+ it 'yields the callback with the email' do
58
+ seen = nil
59
+ client.talktome("welcome", user, tpldata, [:email]){|m|
60
+ seen = m
61
+ }
62
+ expect(seen).not_to be_nil
110
63
  end
111
64
  end
112
65
 
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
2
  require 'talktome'
3
+ require 'talktome/app'
4
+ require 'rack/test'
3
5
 
4
6
  module SpecHelpers
5
7
  end
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: 0.2.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-19 00:00:00.000000000 Z
11
+ date: 2021-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -16,42 +16,56 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '10'
19
+ version: '13'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '10'
26
+ version: '13'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '3.6'
33
+ version: '3.10'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '3.6'
40
+ version: '3.10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rack-test
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 0.6.3
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 0.6.3
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: path
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - ">="
46
60
  - !ruby/object:Gem::Version
47
- version: '1.3'
61
+ version: '2.0'
48
62
  type: :runtime
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - ">="
53
67
  - !ruby/object:Gem::Version
54
- version: '1.3'
68
+ version: '2.0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: mail
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -100,6 +114,54 @@ dependencies:
100
114
  - - "~>"
101
115
  - !ruby/object:Gem::Version
102
116
  version: '3'
117
+ - !ruby/object:Gem::Dependency
118
+ name: sinatra
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '2.0'
124
+ - - "<"
125
+ - !ruby/object:Gem::Version
126
+ version: '3.0'
127
+ type: :runtime
128
+ prerelease: false
129
+ version_requirements: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '2.0'
134
+ - - "<"
135
+ - !ruby/object:Gem::Version
136
+ version: '3.0'
137
+ - !ruby/object:Gem::Dependency
138
+ name: finitio
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - "~>"
142
+ - !ruby/object:Gem::Version
143
+ version: 0.8.0
144
+ type: :runtime
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - "~>"
149
+ - !ruby/object:Gem::Version
150
+ version: 0.8.0
151
+ - !ruby/object:Gem::Dependency
152
+ name: rack-robustness
153
+ requirement: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - "~>"
156
+ - !ruby/object:Gem::Version
157
+ version: '1.1'
158
+ type: :runtime
159
+ prerelease: false
160
+ version_requirements: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - "~>"
163
+ - !ruby/object:Gem::Version
164
+ version: '1.1'
103
165
  description: Talktome helps you talk to users by email, messaging, sms, etc. It abstracts
104
166
  the messaging mechanisms and lets you manage message templates easily.
105
167
  email: blambeau@gmail.com
@@ -112,6 +174,7 @@ files:
112
174
  - README.md
113
175
  - Rakefile
114
176
  - lib/talktome.rb
177
+ - lib/talktome/app.rb
115
178
  - lib/talktome/client.rb
116
179
  - lib/talktome/client/local.rb
117
180
  - lib/talktome/error.rb
@@ -120,6 +183,7 @@ files:
120
183
  - lib/talktome/strategy/debug.rb
121
184
  - lib/talktome/strategy/email.rb
122
185
  - lib/talktome/version.rb
186
+ - spec/app/test_app.rb
123
187
  - spec/client/test_local.rb
124
188
  - spec/fixtures/templates/email.html
125
189
  - spec/fixtures/welcome/email.md
@@ -150,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
214
  - !ruby/object:Gem::Version
151
215
  version: '0'
152
216
  requirements: []
153
- rubygems_version: 3.1.2
217
+ rubygems_version: 3.0.8
154
218
  signing_key:
155
219
  specification_version: 4
156
220
  summary: Talktome helps you talk to users by email, messaging, sms, etc.