ffcrm_cloudfuji 0.3.1 → 0.4.1
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.
- data/app/assets/javascripts/event_rules.js.coffee +1 -1
- data/app/assets/stylesheets/ffcrm_cloudfuji.css +1 -0
- data/app/assets/stylesheets/unknown_emails.css.scss +10 -0
- data/app/controllers/unknown_emails_controller.rb +65 -0
- data/app/helpers/unknown_emails_helper.rb +2 -0
- data/app/models/event_rule.rb +3 -3
- data/app/models/ignored_email.rb +2 -0
- data/app/observers/cloudfuji_lead_observer.rb +2 -1
- data/app/views/unknown_emails/_unknown_email.html.haml +14 -0
- data/app/views/unknown_emails/index.html.haml +22 -0
- data/app/views/unknown_emails/index.js.rjs +6 -0
- data/config/routes.rb +7 -0
- data/db/migrate/20120612140812_create_ignored_emails.rb +7 -0
- data/db/migrate/20120612200812_add_extra_email_fields.rb +6 -0
- data/lib/fat_free_crm/cloudfuji.rb +19 -0
- data/lib/fat_free_crm/cloudfuji/event_observers/email_observer.rb +53 -0
- data/lib/ffcrm_cloudfuji/engine.rb +10 -3
- data/lib/ffcrm_cloudfuji/version.rb +1 -1
- metadata +13 -4
@@ -35,7 +35,7 @@
|
|
35
35
|
$(document).ready ->
|
36
36
|
event_rules = new EventRules()
|
37
37
|
# Initialize autocomplete for events
|
38
|
-
event_rules.cloudfuji_event_autocomplete()
|
38
|
+
event_rules.cloudfuji_event_autocomplete() if observed_cloudfuji_events?
|
39
39
|
|
40
40
|
$("button.add_event_rule").live "click", ->
|
41
41
|
event_rules.add_fields this, $(this).data("content")
|
@@ -0,0 +1,65 @@
|
|
1
|
+
class UnknownEmailsController < ApplicationController
|
2
|
+
before_filter :set_current_tab
|
3
|
+
|
4
|
+
def index
|
5
|
+
# Fetch all emails that don't belong to an
|
6
|
+
# entity, and aren't in the 'ignored_emails' table.
|
7
|
+
sql = %Q{SELECT * from emails
|
8
|
+
WHERE mediator_id IS NULL
|
9
|
+
AND NOT EXISTS (
|
10
|
+
SELECT DISTINCT(email) FROM ignored_emails
|
11
|
+
WHERE email = emails.sent_from
|
12
|
+
OR email = emails.sent_to)}
|
13
|
+
@unknown_emails = Email.paginate_by_sql(sql, :page => params[:page])
|
14
|
+
|
15
|
+
respond_with @unknown_emails
|
16
|
+
end
|
17
|
+
|
18
|
+
# Delete email and ignore all emails from this address
|
19
|
+
def ignore
|
20
|
+
@email = Email.find(params[:id])
|
21
|
+
unless address = params[:email]
|
22
|
+
if @email.direction == 'received'
|
23
|
+
address = @email.sent_from
|
24
|
+
elsif @email.direction == 'sent'
|
25
|
+
address = @email.sent_to
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
if address.present?
|
30
|
+
IgnoredEmail.create :email => address
|
31
|
+
@email.destroy
|
32
|
+
flash[:notice] = "All emails from #{address} will be ignored."
|
33
|
+
else
|
34
|
+
flash[:error] = "Could not determine whether this email was sent or received!"
|
35
|
+
end
|
36
|
+
redirect_to unknown_emails_path
|
37
|
+
end
|
38
|
+
|
39
|
+
# Create lead and attach this email to new lead
|
40
|
+
def convert
|
41
|
+
address = params[:email]
|
42
|
+
|
43
|
+
if address.present?
|
44
|
+
# Attach all orphaned emails that are from / to address
|
45
|
+
@emails = Email.all(:conditions => [%Q{
|
46
|
+
mediator_id IS NULL
|
47
|
+
AND (emails.sent_from LIKE ?
|
48
|
+
OR emails.sent_to LIKE ?)
|
49
|
+
}, "%#{address}%", "%#{address}%"])
|
50
|
+
|
51
|
+
lead = Lead.create :email => address,
|
52
|
+
:first_name => address.split("@").first,
|
53
|
+
:last_name => address.split("@").last,
|
54
|
+
:user => current_user,
|
55
|
+
:emails => @emails
|
56
|
+
|
57
|
+
link_to_lead = ActionController::Base.helpers.link_to(lead_url(lead), lead_url(lead))
|
58
|
+
flash[:notice] = "Created lead and attached email(s): #{link_to_lead}".html_safe
|
59
|
+
else
|
60
|
+
flash[:error] = "Must provide :email param!"
|
61
|
+
end
|
62
|
+
redirect_to unknown_emails_path
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
data/app/models/event_rule.rb
CHANGED
@@ -24,7 +24,7 @@ class EventRule < ActiveRecord::Base
|
|
24
24
|
# Don't apply this rule more than limit_per_lead, if set
|
25
25
|
unless limit_per_lead.present? && count.count > limit_per_lead
|
26
26
|
# If :match is present, only apply the rule if data matches string
|
27
|
-
if match.blank? ||
|
27
|
+
if match.blank? || event_matches?(params)
|
28
28
|
if (app_id.blank? && page_name.blank?) || page_and_app_matches?(params)
|
29
29
|
# Run the action method if defined
|
30
30
|
if respond_to?(action)
|
@@ -57,7 +57,7 @@ class EventRule < ActiveRecord::Base
|
|
57
57
|
when 'cloudfuji_event_received'
|
58
58
|
"Cloudfuji event was received - '#{cloudfuji_event}'"
|
59
59
|
when 'lead_attribute_changed'
|
60
|
-
"Lead \"#{lead.full_name}\" was updated - #{lead_attribute} was changed from '#{match_data[
|
60
|
+
"Lead \"#{lead.full_name}\" was updated - #{lead_attribute} was changed from '#{match_data['old_value']}' to '#{match_data['new_value']}'."
|
61
61
|
end
|
62
62
|
|
63
63
|
User.all.each do |user|
|
@@ -109,7 +109,7 @@ class EventRule < ActiveRecord::Base
|
|
109
109
|
match_string.downcase! if case_insensitive_matching
|
110
110
|
match_string.include?(test_string)
|
111
111
|
when 'lead_attribute_changed'
|
112
|
-
match_string = params[
|
112
|
+
match_string = params['new_value'].to_s.dup
|
113
113
|
match_string.downcase! if case_insensitive_matching
|
114
114
|
match_string == test_string.to_s
|
115
115
|
end
|
@@ -21,7 +21,8 @@ class CloudfujiLeadObserver < ActiveRecord::Observer
|
|
21
21
|
def after_update(lead)
|
22
22
|
# Find all event rules where the lead attribute is one of the changed fields
|
23
23
|
EventRule.find_all_by_event_category_and_lead_attribute('lead_attribute_changed', lead.changes.keys).each do |rule|
|
24
|
-
|
24
|
+
old, new = lead.changes[rule.lead_attribute]
|
25
|
+
rule.process(lead, {'old_value' => old, 'new_value' => new}) # Send [old, new] values as matching data
|
25
26
|
end
|
26
27
|
end
|
27
28
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
%tr.highlight[unknown_email]
|
2
|
+
- addresses = (unknown_email.direction == 'received' ? unknown_email.sent_from : unknown_email.sent_to).split(";")
|
3
|
+
%td= unknown_email.direction.to_s.capitalize
|
4
|
+
%td= unknown_email.sent_from
|
5
|
+
%td= unknown_email.sent_to
|
6
|
+
%td= truncate(unknown_email.subject, :length => 150)
|
7
|
+
%td= truncate(unknown_email.body, :length => 150)
|
8
|
+
%td
|
9
|
+
- addresses.each do |address|
|
10
|
+
= address
|
11
|
+
%p
|
12
|
+
= link_to "Convert to Lead?", convert_unknown_email_path(unknown_email, :email => address), :method => :put
|
13
|
+
or
|
14
|
+
= link_to "Ignore?", ignore_unknown_email_path(unknown_email, :email => address), :method => :delete
|
@@ -0,0 +1,22 @@
|
|
1
|
+
= styles_for :unknown_emails
|
2
|
+
|
3
|
+
.title
|
4
|
+
%span#unknown_emails_title Unknown Emails
|
5
|
+
|
6
|
+
.list
|
7
|
+
- if @unknown_emails.any?
|
8
|
+
%table.unknown_emails
|
9
|
+
%thead
|
10
|
+
%tr
|
11
|
+
%th Direction
|
12
|
+
%th From
|
13
|
+
%th To
|
14
|
+
%th Subject
|
15
|
+
%th Body
|
16
|
+
%th Actions
|
17
|
+
%tbody#unknown_emails
|
18
|
+
= render :partial => 'unknown_email', :collection => @unknown_emails
|
19
|
+
- else
|
20
|
+
Could not find any emails for unknown leads.
|
21
|
+
|
22
|
+
#paginate= render "shared/paginate"
|
@@ -0,0 +1,6 @@
|
|
1
|
+
if @unknown_emails.any?
|
2
|
+
page[:unknown_emails].replace_html render(:partial => "unknown_email", :collection => @unknown_emails)
|
3
|
+
else
|
4
|
+
page[:unknown_emails].replace_html render(:text => "Could not find any emails for unknown leads.")
|
5
|
+
end
|
6
|
+
page[:paginate].replace_html render(:partial => "shared/paginate")
|
data/config/routes.rb
CHANGED
@@ -4,6 +4,7 @@ module FatFreeCRM
|
|
4
4
|
def enable_cloudfuji!
|
5
5
|
load_observers!
|
6
6
|
extend_lead!
|
7
|
+
extend_email!
|
7
8
|
# Prevent User class from loading if database is empty
|
8
9
|
if (User.table_exists? rescue false)
|
9
10
|
extend_user!
|
@@ -44,6 +45,24 @@ module FatFreeCRM
|
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
48
|
+
def extend_email!
|
49
|
+
Email.class_eval do
|
50
|
+
# Sent or received
|
51
|
+
def direction
|
52
|
+
attr_direction = super
|
53
|
+
return attr_direction if attr_direction.present?
|
54
|
+
|
55
|
+
# If direction not stored, try to deduce
|
56
|
+
# from from/to email addresses.
|
57
|
+
if sent_from.include?(user.email)
|
58
|
+
'sent'
|
59
|
+
elsif sent_to.include?(user.email)
|
60
|
+
'received'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
47
66
|
def load_observers!
|
48
67
|
require File.expand_path("../cloudfuji/event_observers/base", __FILE__)
|
49
68
|
Dir[File.expand_path("../cloudfuji/event_observers/*.rb", __FILE__)].each { |file| require file }
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'fat_free_crm/mail_processor/base'
|
2
|
+
|
1
3
|
module FatFreeCRM
|
2
4
|
module Cloudfuji
|
3
5
|
module EventObservers
|
@@ -57,6 +59,31 @@ module FatFreeCRM
|
|
57
59
|
note_email_activity("#{email} subscribed to a mailing list")
|
58
60
|
end
|
59
61
|
|
62
|
+
def email_received
|
63
|
+
user = find_user_by_account
|
64
|
+
return unless user
|
65
|
+
lead = Lead.find_by_email(data['from'])
|
66
|
+
create_email_from_data(
|
67
|
+
:direction => 'received',
|
68
|
+
:mediator => lead,
|
69
|
+
:user => user
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
def email_sent
|
74
|
+
user = find_user_by_account
|
75
|
+
return unless user
|
76
|
+
# Find first Lead from 'to' email addresses
|
77
|
+
lead = data['to'].to_s.split(";").detect do |email|
|
78
|
+
lead = Lead.find_by_email(email)
|
79
|
+
end
|
80
|
+
create_email_from_data(
|
81
|
+
:direction => 'sent',
|
82
|
+
:mediator => lead,
|
83
|
+
:user => user
|
84
|
+
)
|
85
|
+
end
|
86
|
+
|
60
87
|
private
|
61
88
|
|
62
89
|
def note_email_activity(message)
|
@@ -86,6 +113,32 @@ module FatFreeCRM
|
|
86
113
|
campaign
|
87
114
|
end
|
88
115
|
|
116
|
+
def find_user_by_account
|
117
|
+
user = User.find_by_email(data['account'])
|
118
|
+
puts "No User found by email #{data['account']}" unless user
|
119
|
+
user
|
120
|
+
end
|
121
|
+
|
122
|
+
def create_email_from_data(options)
|
123
|
+
mail = Mail.new(data['rfc822'])
|
124
|
+
text_body = FatFreeCRM::MailProcessor::Base.new.send(:plain_text_body, mail)
|
125
|
+
|
126
|
+
# Remove ID hashes from emails (e.g. ...+23423fce32d@...)
|
127
|
+
# This is important so that addresses like
|
128
|
+
# reply+****@reply.github.com can be ignored.
|
129
|
+
to_address = data['to'].gsub(/\+[^@]+/, '')
|
130
|
+
from_address = data['from'].gsub(/\+[^@]+/, '')
|
131
|
+
|
132
|
+
Email.create({
|
133
|
+
:imap_message_id => data['uid'],
|
134
|
+
:sent_from => from_address,
|
135
|
+
:sent_to => to_address,
|
136
|
+
:cc => data['cc'],
|
137
|
+
:subject => data['subject'],
|
138
|
+
:body => text_body,
|
139
|
+
:sent_at => data['date']
|
140
|
+
}.merge(options))
|
141
|
+
end
|
89
142
|
end
|
90
143
|
end
|
91
144
|
end
|
@@ -13,9 +13,16 @@ module FatFreeCRM
|
|
13
13
|
begin
|
14
14
|
unless FatFreeCRM::Tabs.admin.any? {|t| t[:text] == "Event Rules" }
|
15
15
|
FatFreeCRM::Tabs.admin << {
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
:text => "Event Rules",
|
17
|
+
:url => { :controller => "admin/event_rules" }
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
unless FatFreeCRM::Tabs.main.any? {|t| t[:text] == "Unknown Emails" }
|
22
|
+
FatFreeCRM::Tabs.main << {
|
23
|
+
:text => "Unknown Emails",
|
24
|
+
:url => { :controller => "unknown_emails" }
|
25
|
+
}
|
19
26
|
end
|
20
27
|
rescue TypeError
|
21
28
|
puts "You must migrate your settings table."
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffcrm_cloudfuji
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-06-
|
13
|
+
date: 2012-06-12 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec-rails
|
@@ -108,9 +108,13 @@ files:
|
|
108
108
|
- app/assets/javascripts/ffcrm_cloudfuji.js
|
109
109
|
- app/assets/stylesheets/event_rules.css.scss
|
110
110
|
- app/assets/stylesheets/ffcrm_cloudfuji.css
|
111
|
+
- app/assets/stylesheets/unknown_emails.css.scss
|
111
112
|
- app/controllers/admin/event_rules_controller.rb
|
113
|
+
- app/controllers/unknown_emails_controller.rb
|
112
114
|
- app/helpers/admin/event_rules_helper.rb
|
115
|
+
- app/helpers/unknown_emails_helper.rb
|
113
116
|
- app/models/event_rule.rb
|
117
|
+
- app/models/ignored_email.rb
|
114
118
|
- app/models/lead_event_rule_count.rb
|
115
119
|
- app/observers/cloudfuji_lead_observer.rb
|
116
120
|
- app/views/admin/event_rules/_errors.html.haml
|
@@ -119,6 +123,9 @@ files:
|
|
119
123
|
- app/views/leads/_lead.html.haml
|
120
124
|
- app/views/leads/_sidebar_show_lead_scoring.html.haml
|
121
125
|
- app/views/leads/_top_section_ido_id.html.haml
|
126
|
+
- app/views/unknown_emails/_unknown_email.html.haml
|
127
|
+
- app/views/unknown_emails/index.html.haml
|
128
|
+
- app/views/unknown_emails/index.js.rjs
|
122
129
|
- config.ru
|
123
130
|
- config/database.yml
|
124
131
|
- config/initializers/cloudfuji.rb
|
@@ -130,6 +137,8 @@ files:
|
|
130
137
|
- db/migrate/20120524031157_extend_lead_scoring_as_event_rules.rb
|
131
138
|
- db/migrate/20120525151511_add_ido_id_to_lead.rb
|
132
139
|
- db/migrate/20120607115701_add_mailing_list_and_page_fields_to_event_rules.rb
|
140
|
+
- db/migrate/20120612140812_create_ignored_emails.rb
|
141
|
+
- db/migrate/20120612200812_add_extra_email_fields.rb
|
133
142
|
- ffcrm_cloudfuji.gemspec
|
134
143
|
- install.rb
|
135
144
|
- lib/fat_free_crm/cloudfuji.rb
|
@@ -169,7 +178,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
169
178
|
version: '0'
|
170
179
|
segments:
|
171
180
|
- 0
|
172
|
-
hash:
|
181
|
+
hash: 2361827458429134483
|
173
182
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
174
183
|
none: false
|
175
184
|
requirements:
|
@@ -178,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
178
187
|
version: '0'
|
179
188
|
segments:
|
180
189
|
- 0
|
181
|
-
hash:
|
190
|
+
hash: 2361827458429134483
|
182
191
|
requirements: []
|
183
192
|
rubyforge_project:
|
184
193
|
rubygems_version: 1.8.24
|