ishapi 0.1.8.302 → 0.1.8.304

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: 57efdeeb134f2713ceff675afdcd38227765df6cd5769ef9f85423c79d46999e
4
- data.tar.gz: a7ad58a601430d8172229fd66dc9b612a8ca432b7ea1602741c8fd6a54f3f561
3
+ metadata.gz: c2aa5889cc1b26469a45c1177f999974ab3c8d3dead962628024eaf53b22ffdf
4
+ data.tar.gz: ac848af52069580c948d4f9f25b3bb909b9114647bcdb2dd967dd963dc548513
5
5
  SHA512:
6
- metadata.gz: 16c58f71d63bf5b156fe7800f66505b0ec3c7b607d4900b89dcebbd99a7e4b98218c12af11c63b5df9320d546ad212efe1d7a302446a7bbb3763a76a42e7e0f7
7
- data.tar.gz: c68af62bda4af804a79bd8e2a74349507a40579a2c26784496f6c65ffd24c0b869dc27c2b46bb7c79285c17c666a03cb0f3cc011fde56cb970544b99b7f2e95b
6
+ metadata.gz: c3702b34c60967c73931108100513252416ba21dec37e7365276ec2c4eee3b97135d275f19c50b80b0a9611c3cbfdf5eb84d84ac75d30a2ca5842acb948be1a9
7
+ data.tar.gz: e540871e032d8f92633ad726ba51b6e17b14430688ea7af76637f880ec54676fbbb55c4fd0ae6ef8a31dccb883f460143844a5fdefac118586110ce19a0227dd
@@ -9,243 +9,191 @@ class Ishapi::EmailMessageIntakeJob < Ishapi::ApplicationJob
9
9
 
10
10
  queue_as :default
11
11
 
12
- ## For recursive parts of type `related`.
13
- ## Content dispositions:
14
- # "inline; creation-date=\"Tue, 11 Apr 2023 19:39:42 GMT\"; filename=image005.png; modification-date=\"Tue, 11 Apr 2023 19:47:53 GMT\"; size=14916",
15
- #
16
- ## Content Types:
17
- # "application/pdf; name=\"Securities Forward Agreement -- HaulHub Inc -- Victor Pudeyev -- 2021-10-26.docx.pdf\""
18
- # "image/jpeg; name=TX_DL_2.jpg"
19
- # "image/png; name=image005.png"
20
- # "multipart/alternative; boundary=_000_BL0PR10MB2913C560ADE059F0AB3A6D11829A9BL0PR10MB2913namp_",
21
- # "text/html; charset=utf-8"
22
- # "text/plain; charset=UTF-8"
23
- # "text/calendar; charset=utf-8; method=REQUEST"
24
- def churn_subpart message, part
25
- if part.content_disposition&.include?('attachment')
26
- ## @TODO: attachments !
27
- ;
28
- else
29
- if part.content_type.include?("multipart/related") ||
30
- part.content_type.include?("multipart/alternative")
31
-
32
- part.parts.each do |subpart|
33
- churn_subpart( message, subpart )
34
- end
35
- else
36
- attachment = Office::EmailAttachment.new({
37
- content: part.decoded,
38
- content_type: part.content_type,
39
- email_message: message,
40
- })
41
- attachment.save
12
+ =begin
42
13
 
43
- if part.content_type.include?('text/html')
44
- message.part_html = part.decoded
14
+ object_key = 'n0v5mg6q1t4fjjnfh8vj8a96t85rp9la2ud0gdg1'
15
+ MsgStub.where({ object_key: object_key }).delete
45
16
 
46
- elsif part.content_type.include?("text/plain")
47
- message.part_txt = part.decoded
17
+ stub = MsgStub.create!({ object_key: object_key })
18
+ id = stub.id
48
19
 
49
- elsif part.content_type.include?("text/calendar")
50
- ;
51
- elsif part.content_type.include?("application/pdf")
52
- ;
53
- elsif part.content_type.include?("image/jpeg")
54
- ;
55
- elsif part.content_type.include?("image/png")
56
- ;
20
+ Ishapi::EmailMessageIntakeJob.perform_now( stub.id.to_s )
57
21
 
58
- else
59
- puts! part.content_type, '444 No action for a part with this content_type'
22
+ =end
23
+ def perform id
24
+ stub = ::Office::EmailMessageStub.find id
25
+ if !Rails.env.test?
26
+ puts "Performing EmailMessageIntakeJob for object_key #{stub.object_key}"
27
+ end
28
+ if stub.state != ::Office::EmailMessageStub::STATE_PENDING
29
+ raise "This stub has already been processed: #{stub.id.to_s}."
30
+ return
31
+ end
60
32
 
61
- end
33
+ client = Aws::S3::Client.new({
34
+ region: ::S3_CREDENTIALS[:region_ses],
35
+ access_key_id: ::S3_CREDENTIALS[:access_key_id_ses],
36
+ secret_access_key: ::S3_CREDENTIALS[:secret_access_key_ses],
37
+ })
38
+
39
+ _mail = client.get_object( bucket: ::S3_CREDENTIALS[:bucket_ses], key: stub.object_key ).body.read
40
+ the_mail = Mail.new(_mail)
41
+ message_id = the_mail.header['message-id'].decoded
42
+ in_reply_to_id = the_mail.header['in-reply-to']&.to_s
43
+ email_inbox_tag_id = WpTag.emailtag(WpTag::INBOX).id
44
+
45
+ if !the_mail.to
46
+ the_mail.to = [ 'NO-RECIPIENT' ]
62
47
  end
63
- end
64
- end
65
48
 
66
- ## From: https://stackoverflow.com/questions/24672834/how-do-i-remove-emoji-from-string/24673322
67
- def strip_emoji(text)
68
- text = text.force_encoding('utf-8').encode
69
- clean = ""
70
49
 
71
- # symbols & pics
72
- regex = /[\u{1f300}-\u{1f5ff}]/
73
- clean = text.gsub regex, ""
50
+ subject = ::Msg.strip_emoji the_mail.subject
51
+ subject ||= '(wco no subject)'
74
52
 
75
- # enclosed chars
76
- regex = /[\u{2500}-\u{2BEF}]/ # I changed this to exclude chinese char
77
- clean = clean.gsub regex, ""
53
+ @message = ::Office::EmailMessage.where( message_id: message_id ).first
54
+ @message ||= ::Office::EmailMessage.create({
55
+ raw: _mail,
78
56
 
79
- # emoticons
80
- regex = /[\u{1f600}-\u{1f64f}]/
81
- clean = clean.gsub regex, ""
57
+ message_id: message_id,
58
+ in_reply_to_id: in_reply_to_id,
82
59
 
83
- #dingbats
84
- regex = /[\u{2702}-\u{27b0}]/
85
- clean = clean.gsub regex, ""
86
- end
60
+ object_key: stub.object_key,
61
+ # object_path: stub.object_path,
87
62
 
88
- def perform id
89
- stub = ::Office::EmailMessageStub.find id
90
- if !Rails.env.test?
91
- puts "Performing EmailMessageIntakeJob for object_key #{stub.object_key}"
92
- end
93
- if stub.state != ::Office::EmailMessageStub::STATE_PENDING
94
- raise "This stub has already been processed: #{stub.id.to_s}."
95
- return
96
- end
97
- client = Aws::S3::Client.new({
98
- region: ::S3_CREDENTIALS[:region_ses],
99
- access_key_id: ::S3_CREDENTIALS[:access_key_id_ses],
100
- secret_access_key: ::S3_CREDENTIALS[:secret_access_key_ses],
101
- })
102
-
103
- _mail = client.get_object( bucket: ::S3_CREDENTIALS[:bucket_ses], key: stub.object_key ).body.read
104
- the_mail = Mail.new(_mail)
105
- message_id = the_mail.header['message-id'].decoded
106
- in_reply_to_id = the_mail.header['in-reply-to']&.to_s
107
- email_inbox_tag_id = WpTag.emailtag(WpTag::INBOX).id
108
-
109
- if !the_mail.to
110
- the_mail.to = [ 'NO-RECIPIENT' ]
111
- end
112
-
113
-
114
- subject = strip_emoji the_mail.subject
115
- subject ||= '(wco no subject)'
116
-
117
- @message = ::Office::EmailMessage.where( message_id: message_id ).first
118
- @message ||= ::Office::EmailMessage.create({
119
- raw: _mail,
120
-
121
- message_id: message_id,
122
- in_reply_to_id: in_reply_to_id,
123
-
124
- object_key: stub.object_key,
125
- # object_path: stub.object_path,
126
-
127
- subject: subject,
128
- date: the_mail.date,
129
-
130
- from: the_mail.from ? the_mail.from[0] : "nobody@unknown-doma.in",
131
- froms: the_mail.from,
132
-
133
- to: the_mail.to ? the_mail.to[0] : nil,
134
- tos: the_mail.to,
135
-
136
- cc: the_mail.cc ? the_mail.cc[0] : nil,
137
- ccs: the_mail.cc,
138
-
139
- # bccs: the_mail.bcc,
140
- })
141
- if !@message.persisted?
142
- puts! @message.errors.full_messages, "Could not create email_message"
143
- end
144
- if the_mail.body.preamble.present?
145
- @message.preamble = the_mail.body.preamble
146
- end
147
- if the_mail.body.epilogue.present?
148
- @message.epilogue = the_mail.body.epilogue
149
- end
150
-
151
- ## Parts
152
- the_mail.parts.each do |part|
153
- churn_subpart( @message, part )
154
- end
155
-
156
- if the_mail.parts.length == 0
157
- body = the_mail.body.decoded.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?')
158
- if the_mail.content_type&.include?('text/html')
159
- @message.part_html = body
160
- elsif the_mail.content_type&.include?('text/plain')
161
- @message.part_txt = body
162
- elsif the_mail.content_type.blank?
163
- @message.part_txt = body
164
- else
165
- throw "mail body of unknown type: #{the_mail.content_type}"
166
- end
167
- end
168
-
169
- ## Attachments
170
- the_mail.attachments.each do |att|
171
- photo = Photo.new({
172
- content_type: att.content_type.split(';')[0],
173
- original_filename: att.content_type_parameters[:name],
174
- image_data: att.body.encoded,
175
- email_message_id: @message.id,
63
+ subject: subject,
64
+ date: the_mail.date,
65
+
66
+ from: the_mail.from ? the_mail.from[0] : "nobody@unknown-doma.in",
67
+ froms: the_mail.from,
68
+
69
+ to: the_mail.to ? the_mail.to[0] : nil,
70
+ tos: the_mail.to,
71
+
72
+ cc: the_mail.cc ? the_mail.cc[0] : nil,
73
+ ccs: the_mail.cc,
74
+
75
+ # bccs: the_mail.bcc,
176
76
  })
177
- photo.decode_base64_image
178
- photo.save
179
- end
180
-
181
- ## Leadset, Lead
182
- domain = @message.from.split('@')[1] rescue 'unknown.domain'
183
- leadset = Leadset.find_or_create_by( company_url: domain )
184
- lead = Lead.find_or_create_by( email: @message.from, m3_leadset_id: leadset.id )
185
- the_mail.cc&.each do |cc|
186
- domain = cc.split('@')[1] rescue 'unknown.domain'
77
+ if !@message.persisted?
78
+ puts! @message.errors.full_messages, "Could not create email_message"
79
+ end
80
+ if the_mail.body.preamble.present?
81
+ @message.preamble = the_mail.body.preamble
82
+ end
83
+ if the_mail.body.epilogue.present?
84
+ @message.epilogue = the_mail.body.epilogue
85
+ end
86
+
87
+ ## Parts
88
+ the_mail.parts.each do |part|
89
+ @message.churn_subpart( part )
90
+ end
91
+
92
+ if the_mail.parts.length == 0
93
+ body = the_mail.body.decoded.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?')
94
+ if the_mail.content_type&.include?('text/html')
95
+ @message.part_html = body
96
+ elsif the_mail.content_type&.include?('text/plain')
97
+ @message.part_txt = body
98
+ elsif the_mail.content_type.blank?
99
+ @message.part_txt = body
100
+ else
101
+ @message.logs.push "mail body of unknown type: #{the_mail.content_type}"
102
+ end
103
+ end
104
+
105
+ ## Attachments
106
+ the_mail.attachments.each do |att|
107
+ content_type = att.content_type.split(';')[0]
108
+ if content_type.include? 'image'
109
+ photo = Photo.new({
110
+ content_type: content_type,
111
+ original_filename: att.content_type_parameters[:name],
112
+ image_data: att.body.encoded,
113
+ email_message_id: @message.id,
114
+ })
115
+ photo.decode_base64_image
116
+ photo.save
117
+ elsif att.filename
118
+ attachment = Office::EmailAttachment.new({
119
+ content: att.body.decoded,
120
+ content_type: att.content_type,
121
+ email_message: @message,
122
+ filename: att.filename,
123
+ })
124
+ attachment.save
125
+ else
126
+ @message.logs.push "Could not save an attachment!"
127
+ end
128
+ end
129
+
130
+ ## Leadset, Lead
131
+ domain = @message.from.split('@')[1] rescue 'unknown.domain'
187
132
  leadset = Leadset.find_or_create_by( company_url: domain )
188
- Lead.find_or_create_by( email: cc, m3_leadset_id: leadset.id )
189
- end
133
+ lead = Lead.find_or_create_by( email: @message.from, m3_leadset_id: leadset.id )
134
+ the_mail.cc&.each do |cc|
135
+ domain = cc.split('@')[1] rescue 'unknown.domain'
136
+ leadset = Leadset.find_or_create_by( company_url: domain )
137
+ Lead.find_or_create_by( email: cc, m3_leadset_id: leadset.id )
138
+ end
190
139
 
191
- ## Conversation
192
- if in_reply_to_id
193
- in_reply_to_msg = ::Office::EmailMessage.where({ message_id: in_reply_to_id }).first
194
- if !in_reply_to_msg
140
+ ## Conversation
141
+ if in_reply_to_id
142
+ in_reply_to_msg = ::Office::EmailMessage.where({ message_id: in_reply_to_id }).first
143
+ if !in_reply_to_msg
144
+ conv = ::Office::EmailConversation.find_or_create_by({
145
+ subject: @message.subject,
146
+ })
147
+ in_reply_to_msg = ::Office::EmailMessage.find_or_create_by({
148
+ message_id: in_reply_to_id,
149
+ email_conversation_id: conv.id,
150
+ })
151
+ end
152
+ conv = in_reply_to_msg.email_conversation
153
+ else
195
154
  conv = ::Office::EmailConversation.find_or_create_by({
196
155
  subject: @message.subject,
197
156
  })
198
- in_reply_to_msg = ::Office::EmailMessage.find_or_create_by({
199
- message_id: in_reply_to_id,
200
- email_conversation_id: conv.id,
201
- })
202
157
  end
203
- conv = in_reply_to_msg.email_conversation
204
- else
205
- conv = ::Office::EmailConversation.find_or_create_by({
206
- subject: @message.subject,
158
+ @message.update_attributes({ email_conversation_id: conv.id })
159
+ conv.update_attributes({
160
+ state: Conv::STATE_UNREAD,
161
+ latest_at: the_mail.date || Time.now.to_datetime,
162
+ from_emails: ( conv.from_emails + the_mail.from ).uniq,
163
+ })
164
+ conv.add_tag( ::WpTag::INBOX )
165
+ conv_lead_tie = Office::EmailConversationLead.find_or_create_by({
166
+ lead_id: lead.id,
167
+ email_conversation_id: conv.id,
207
168
  })
208
- end
209
- @message.update_attributes({ email_conversation_id: conv.id })
210
- conv.update_attributes({
211
- state: Conv::STATE_UNREAD,
212
- latest_at: the_mail.date || Time.now.to_datetime,
213
- from_emails: ( conv.from_emails + the_mail.from ).uniq,
214
- })
215
- conv.add_tag( ::WpTag::INBOX )
216
- conv_lead_tie = Office::EmailConversationLead.find_or_create_by({
217
- lead_id: lead.id,
218
- email_conversation_id: conv.id,
219
- })
220
-
221
-
222
- ## Actions & Filters
223
- email_filters = Office::EmailFilter.active
224
- email_filters.each do |filter|
225
- if ( filter.from_regex.blank? || @message.from.match( filter.from_regex ) ) &&
226
- ( filter.from_exact.blank? || @message.from.downcase.include?( filter.from_exact&.downcase ) ) &&
227
- ( filter.body_exact.blank? || @message.part_html&.include?( filter.body_exact ) ) &&
228
- ( filter.subject_regex.blank? || @message.subject.match( filter.subject_regex ) ) &&
229
- ( filter.subject_exact.blank? || @message.subject.downcase.include?( filter.subject_exact&.downcase ) )
230
-
231
- # || MiaTagger.analyze( @message.part_html, :is_spammy_recruite ).score > .5
232
-
233
- puts! "applying filter #{filter} to conv #{conv}" if DEBUG
234
-
235
- @message.apply_filter( filter )
169
+
170
+
171
+ ## Actions & Filters
172
+ email_filters = Office::EmailFilter.active
173
+ email_filters.each do |filter|
174
+ if ( filter.from_regex.blank? || @message.from.match( filter.from_regex ) ) &&
175
+ ( filter.from_exact.blank? || @message.from.downcase.include?( filter.from_exact&.downcase ) ) &&
176
+ ( filter.body_exact.blank? || @message.part_html&.include?( filter.body_exact ) ) &&
177
+ ( filter.subject_regex.blank? || @message.subject.match( filter.subject_regex ) ) &&
178
+ ( filter.subject_exact.blank? || @message.subject.downcase.include?( filter.subject_exact&.downcase ) )
179
+
180
+ # || MiaTagger.analyze( @message.part_html, :is_spammy_recruite ).score > .5
181
+
182
+ puts! "applying filter #{filter} to conv #{conv}" if DEBUG
183
+
184
+ @message.apply_filter( filter )
185
+ end
236
186
  end
237
- end
238
187
 
239
- stub.update_attributes({ state: ::Office::EmailMessageStub::STATE_PROCESSED })
188
+ stub.update_attributes({ state: ::Office::EmailMessageStub::STATE_PROCESSED })
240
189
 
241
- ## Notification
242
- conv = Conv.find( conv.id )
243
- if conv.in_emailtag? WpTag::INBOX
244
- out = ::Ishapi::ApplicationMailer.forwarder_notify( @message.id.to_s )
245
- Rails.env.production? ? out.deliver_later : out.deliver_now
246
- end
190
+ ## Notification
191
+ conv = Conv.find( conv.id )
192
+ if conv.in_emailtag? WpTag::INBOX
193
+ out = ::Ishapi::ApplicationMailer.forwarder_notify( @message.id.to_s )
194
+ Rails.env.production? ? out.deliver_later : out.deliver_now
195
+ end
247
196
 
248
197
  end
249
-
250
198
  end
251
199
  EIJ = Ishapi::EmailMessageIntakeJob
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ishapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8.302
4
+ version: 0.1.8.304
5
5
  platform: ruby
6
6
  authors:
7
7
  - piousbox
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-08 00:00:00.000000000 Z
11
+ date: 2023-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails