ffcrm_cloudfuji 0.3.1 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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")
@@ -1,3 +1,4 @@
1
1
  /*
2
2
  *= require event_rules
3
+ *= require unknown_emails
3
4
  */
@@ -0,0 +1,10 @@
1
+ table.unknown_emails {
2
+ border-collapse: collapse;
3
+ width: 100%;
4
+ th { text-align: left; }
5
+ td {
6
+ border: 1px solid #ccc;
7
+ padding: 3px;
8
+ }
9
+ }
10
+
@@ -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
@@ -0,0 +1,2 @@
1
+ module UnknownEmailsHelper
2
+ end
@@ -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? || (params['data'] && event_matches?(params))
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[0]}' to '#{match_data[1]}'."
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[1].to_s.dup
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
@@ -0,0 +1,2 @@
1
+ class IgnoredEmail < ActiveRecord::Base
2
+ 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
- rule.process(lead, lead.changes[rule.lead_attribute]) # Send [old, new] values as matching data
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")
@@ -20,4 +20,11 @@ Rails.application.routes.draw do
20
20
  post :update, :on => :collection
21
21
  end
22
22
  end
23
+
24
+ resources :unknown_emails, :only => :index do
25
+ member do
26
+ delete :ignore
27
+ put :convert
28
+ end
29
+ end
23
30
  end
@@ -0,0 +1,7 @@
1
+ class CreateIgnoredEmails < ActiveRecord::Migration
2
+ def change
3
+ create_table :ignored_emails do |t|
4
+ t.string :email
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ class AddExtraEmailFields < ActiveRecord::Migration
2
+ def change
3
+ add_column :emails, :direction, :string
4
+ add_column :emails, :imap_folder, :string
5
+ end
6
+ end
@@ -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
- :text => "Event Rules",
17
- :url => { :controller => "admin/event_rules" }
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."
@@ -1,5 +1,5 @@
1
1
  module FatFreeCRM
2
2
  module Cloudfuji
3
- VERSION = '0.3.1'
3
+ VERSION = '0.4.1'
4
4
  end
5
5
  end
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.3.1
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-07 00:00:00.000000000 Z
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: 1944626669401206856
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: 1944626669401206856
190
+ hash: 2361827458429134483
182
191
  requirements: []
183
192
  rubyforge_project:
184
193
  rubygems_version: 1.8.24