ishapi 0.1.8.301 → 0.1.8.303

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: e6229aa67b706172dea159f73ff6f5e45d9281c8cb64b9de70e384995f1a869c
4
- data.tar.gz: af1216cc0d2d17bcb6a6e6b00e977e7b8ebca3768c6db71c7cd2568a3c21a4cf
3
+ metadata.gz: deb042effc76a3bac981e7d95c5ccbac9c1fe067b5afb6799f273a2fb061ba67
4
+ data.tar.gz: a497b8b725895391c965abe2680adb51d739958ca36172615263aa3fd6b83703
5
5
  SHA512:
6
- metadata.gz: d16c460663a76a261be7a0ad5b29483cd71c800632bc990b5590206c8315aafea77abbb9b2ba65b8916ad3483e250cb019eeb6d3e22762a19389f1b4be775237
7
- data.tar.gz: 9580c4aea9c855f492087492bbc266eb5db78344d6d966fdb929bd45157d5bbfe868d0f473594f579eed7cee33dd47eebd1c04d26a3c025ea75dc6c9ae7f56b2
6
+ metadata.gz: 206d685ea05a79c226a49d888e1ba2ced49e5ff32343999fe1a00e42c65eb8f139e17cc1dcb2bd6d0e7acbb83c257ef55205d75f318631c353a3aef22b6db143
7
+ data.tar.gz: ceebf0b9f54feb97eeac59cc655d65c12fc10957431d4821bf472e18822d97d80be31b0407f914a2a94e63119c62a5cf8a743e9f96556f088c481e90fbad3eff
@@ -9,243 +9,183 @@ 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
13
+ object_key = 'bg57j6u0j38b5ts86635fkqtjlucn5tvrm2hea81'
14
+ MsgStub.where({ object_key: object_key }).delete
42
15
 
43
- if part.content_type.include?('text/html')
44
- message.part_html = part.decoded
16
+ stub = MsgStub.create({ object_key: object_key })
17
+ id = stub.id
18
+ =end
19
+ def perform id
20
+ stub = ::Office::EmailMessageStub.find id
21
+ if !Rails.env.test?
22
+ puts "Performing EmailMessageIntakeJob for object_key #{stub.object_key}"
23
+ end
24
+ if stub.state != ::Office::EmailMessageStub::STATE_PENDING
25
+ raise "This stub has already been processed: #{stub.id.to_s}."
26
+ return
27
+ end
28
+ client = Aws::S3::Client.new({
29
+ region: ::S3_CREDENTIALS[:region_ses],
30
+ access_key_id: ::S3_CREDENTIALS[:access_key_id_ses],
31
+ secret_access_key: ::S3_CREDENTIALS[:secret_access_key_ses],
32
+ })
45
33
 
46
- elsif part.content_type.include?("text/plain")
47
- message.part_txt = part.decoded
34
+ _mail = client.get_object( bucket: ::S3_CREDENTIALS[:bucket_ses], key: stub.object_key ).body.read
35
+ the_mail = Mail.new(_mail)
36
+ message_id = the_mail.header['message-id'].decoded
37
+ in_reply_to_id = the_mail.header['in-reply-to']&.to_s
38
+ email_inbox_tag_id = WpTag.emailtag(WpTag::INBOX).id
48
39
 
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
- ;
40
+ if !the_mail.to
41
+ the_mail.to = [ 'NO-RECIPIENT' ]
42
+ end
57
43
 
58
- else
59
- puts! part.content_type, '444 No action for a part with this content_type'
60
44
 
61
- end
62
- end
63
- end
64
- end
45
+ subject = ::Msg.strip_emoji the_mail.subject
46
+ subject ||= '(wco no subject)'
65
47
 
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 = ""
48
+ @message = ::Office::EmailMessage.where( message_id: message_id ).first
49
+ @message ||= ::Office::EmailMessage.create({
50
+ raw: _mail,
70
51
 
71
- # symbols & pics
72
- regex = /[\u{1f300}-\u{1f5ff}]/
73
- clean = text.gsub regex, ""
52
+ message_id: message_id,
53
+ in_reply_to_id: in_reply_to_id,
74
54
 
75
- # enclosed chars
76
- regex = /[\u{2500}-\u{2BEF}]/ # I changed this to exclude chinese char
77
- clean = clean.gsub regex, ""
55
+ object_key: stub.object_key,
56
+ # object_path: stub.object_path,
78
57
 
79
- # emoticons
80
- regex = /[\u{1f600}-\u{1f64f}]/
81
- clean = clean.gsub regex, ""
58
+ subject: subject,
59
+ date: the_mail.date,
82
60
 
83
- #dingbats
84
- regex = /[\u{2702}-\u{27b0}]/
85
- clean = clean.gsub regex, ""
86
- end
61
+ from: the_mail.from ? the_mail.from[0] : "nobody@unknown-doma.in",
62
+ froms: the_mail.from,
87
63
 
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,
64
+ to: the_mail.to ? the_mail.to[0] : nil,
65
+ tos: the_mail.to,
66
+
67
+ cc: the_mail.cc ? the_mail.cc[0] : nil,
68
+ ccs: the_mail.cc,
69
+
70
+ # bccs: the_mail.bcc,
176
71
  })
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'
72
+ if !@message.persisted?
73
+ puts! @message.errors.full_messages, "Could not create email_message"
74
+ end
75
+ if the_mail.body.preamble.present?
76
+ @message.preamble = the_mail.body.preamble
77
+ end
78
+ if the_mail.body.epilogue.present?
79
+ @message.epilogue = the_mail.body.epilogue
80
+ end
81
+
82
+ ## Parts
83
+ the_mail.parts.each do |part|
84
+ @message.churn_subpart( part )
85
+ end
86
+
87
+ if the_mail.parts.length == 0
88
+ body = the_mail.body.decoded.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?')
89
+ if the_mail.content_type&.include?('text/html')
90
+ @message.part_html = body
91
+ elsif the_mail.content_type&.include?('text/plain')
92
+ @message.part_txt = body
93
+ elsif the_mail.content_type.blank?
94
+ @message.part_txt = body
95
+ else
96
+ throw "mail body of unknown type: #{the_mail.content_type}"
97
+ end
98
+ end
99
+
100
+ ## Attachments
101
+ the_mail.attachments.each do |att|
102
+ photo = Photo.new({
103
+ content_type: att.content_type.split(';')[0],
104
+ original_filename: att.content_type_parameters[:name],
105
+ image_data: att.body.encoded,
106
+ email_message_id: @message.id,
107
+ })
108
+ photo.decode_base64_image
109
+ if photo.save
110
+ ;
111
+ else
112
+ attachment = Office::EmailAttachment.new({
113
+ content: att.decoded,
114
+ content_type: att.content_type,
115
+ email_message: @message,
116
+ filename: att.filename,
117
+ })
118
+ attachment.save
119
+ end
120
+ end
121
+
122
+ ## Leadset, Lead
123
+ domain = @message.from.split('@')[1] rescue 'unknown.domain'
187
124
  leadset = Leadset.find_or_create_by( company_url: domain )
188
- Lead.find_or_create_by( email: cc, m3_leadset_id: leadset.id )
189
- end
125
+ lead = Lead.find_or_create_by( email: @message.from, m3_leadset_id: leadset.id )
126
+ the_mail.cc&.each do |cc|
127
+ domain = cc.split('@')[1] rescue 'unknown.domain'
128
+ leadset = Leadset.find_or_create_by( company_url: domain )
129
+ Lead.find_or_create_by( email: cc, m3_leadset_id: leadset.id )
130
+ end
190
131
 
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
132
+ ## Conversation
133
+ if in_reply_to_id
134
+ in_reply_to_msg = ::Office::EmailMessage.where({ message_id: in_reply_to_id }).first
135
+ if !in_reply_to_msg
136
+ conv = ::Office::EmailConversation.find_or_create_by({
137
+ subject: @message.subject,
138
+ })
139
+ in_reply_to_msg = ::Office::EmailMessage.find_or_create_by({
140
+ message_id: in_reply_to_id,
141
+ email_conversation_id: conv.id,
142
+ })
143
+ end
144
+ conv = in_reply_to_msg.email_conversation
145
+ else
195
146
  conv = ::Office::EmailConversation.find_or_create_by({
196
147
  subject: @message.subject,
197
148
  })
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
149
  end
203
- conv = in_reply_to_msg.email_conversation
204
- else
205
- conv = ::Office::EmailConversation.find_or_create_by({
206
- subject: @message.subject,
150
+ @message.update_attributes({ email_conversation_id: conv.id })
151
+ conv.update_attributes({
152
+ state: Conv::STATE_UNREAD,
153
+ latest_at: the_mail.date || Time.now.to_datetime,
154
+ from_emails: ( conv.from_emails + the_mail.from ).uniq,
207
155
  })
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 )
156
+ conv.add_tag( ::WpTag::INBOX )
157
+ conv_lead_tie = Office::EmailConversationLead.find_or_create_by({
158
+ lead_id: lead.id,
159
+ email_conversation_id: conv.id,
160
+ })
161
+
162
+
163
+ ## Actions & Filters
164
+ email_filters = Office::EmailFilter.active
165
+ email_filters.each do |filter|
166
+ if ( filter.from_regex.blank? || @message.from.match( filter.from_regex ) ) &&
167
+ ( filter.from_exact.blank? || @message.from.downcase.include?( filter.from_exact&.downcase ) ) &&
168
+ ( filter.body_exact.blank? || @message.part_html&.include?( filter.body_exact ) ) &&
169
+ ( filter.subject_regex.blank? || @message.subject.match( filter.subject_regex ) ) &&
170
+ ( filter.subject_exact.blank? || @message.subject.downcase.include?( filter.subject_exact&.downcase ) )
171
+
172
+ # || MiaTagger.analyze( @message.part_html, :is_spammy_recruite ).score > .5
173
+
174
+ puts! "applying filter #{filter} to conv #{conv}" if DEBUG
175
+
176
+ @message.apply_filter( filter )
177
+ end
236
178
  end
237
- end
238
179
 
239
- stub.update_attributes({ state: ::Office::EmailMessageStub::STATE_PROCESSED })
180
+ stub.update_attributes({ state: ::Office::EmailMessageStub::STATE_PROCESSED })
240
181
 
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
182
+ ## Notification
183
+ conv = Conv.find( conv.id )
184
+ if conv.in_emailtag? WpTag::INBOX
185
+ out = ::Ishapi::ApplicationMailer.forwarder_notify( @message.id.to_s )
186
+ Rails.env.production? ? out.deliver_later : out.deliver_now
187
+ end
247
188
 
248
189
  end
249
-
250
190
  end
251
191
  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.301
4
+ version: 0.1.8.303
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-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails