AIEmailAutomationUtility 0.0.9__py3-none-any.whl → 0.0.10__py3-none-any.whl

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.
@@ -19,23 +19,23 @@ class EmailReplyAssistant:
19
19
 
20
20
  def on_text_created(self, text):
21
21
  if isinstance(text, str):
22
- print(f"\nAssistant: {text}", end="", flush=True)
22
+ logger.log(f"\nAssistant: {text}", end="", flush=True)
23
23
 
24
24
  def on_text_delta(self, delta, snapshot):
25
25
  self.delta_values.append(delta.value)
26
26
 
27
27
  def on_tool_call_created(self, tool_call):
28
- print(f"\nAssistant: {tool_call.type}\n", flush=True)
28
+ logger.log(f"\nAssistant: {tool_call.type}\n", flush=True)
29
29
 
30
30
  def on_tool_call_delta(self, delta, snapshot):
31
31
  if delta.type == 'code_interpreter':
32
32
  if delta.code_interpreter.input:
33
- print(delta.code_interpreter.input, end="", flush=True)
33
+ logger.log(delta.code_interpreter.input, end="", flush=True)
34
34
  if delta.code_interpreter.outputs:
35
- print(f"\n\nOutput >", flush=True)
35
+ logger.log(f"\n\nOutput >", flush=True)
36
36
  for output in delta.code_interpreter.outputs:
37
37
  if output.type == "logs":
38
- print(output.logs, flush=True)
38
+ logger.log(output.logs, flush=True)
39
39
 
40
40
  openAI_response = ""
41
41
  client = OpenAI(api_key=openAI_key)
@@ -71,13 +71,8 @@ class EmailReplyAssistant:
71
71
  data = ast.literal_eval(m.group(1)).get('error') if m else {}
72
72
  return {"status": "Failed", "message": data.get('message')}
73
73
 
74
- def email_reply_assitant(self):
74
+ def email_reply_assitant(self, data):
75
75
  try:
76
- # while True:
77
- data = request.get_data('jsonData', None)
78
- data = json.loads(data[9:])
79
- logger.log(f"jsondata:: {data}")
80
-
81
76
  openAI_key = data.get("openAI_key")
82
77
  assistant_ID = data.get("assistant_ID")
83
78
  email_content = data.get("email_content")
@@ -93,7 +88,7 @@ class EmailReplyAssistant:
93
88
  subject=subject
94
89
  )
95
90
 
96
- logger.log(f"Reply_Email_Ai_Assistant response: {email_response}")
91
+ # logger.log(f"Reply_Email_Ai_Assistant response: {email_response}")
97
92
  return email_response
98
93
 
99
94
  except Exception as e:
@@ -142,11 +142,8 @@ class Email_Classification:
142
142
  logger.log(f"Error with LocalAI detection/generation: {str(e)}")
143
143
  return {"success": "Failed", "message": f"Error with LocalAI detection/generation: {str(e)}"}
144
144
 
145
- def detect_category(self):
145
+ def detect_category(self, data):
146
146
  try:
147
- data = request.get_data('jsonData', None)
148
- data = json.loads(data[9:])
149
- logger.log(f"jsondata:: {data}")
150
147
  model_type = data.get('model_type', 'OpenAI')
151
148
 
152
149
  required_fields = ['email_body', 'categories']
@@ -5,7 +5,6 @@ import requests
5
5
  import loggerutility as logger
6
6
  from flask import Flask,request
7
7
 
8
-
9
8
  class Email_DocumentUploader:
10
9
  def upload_document(self, upload_config, file_data):
11
10
  # try:
@@ -55,47 +54,32 @@ class Email_DocumentUploader:
55
54
  return str(response.status_code), document_id
56
55
  else:
57
56
  return str(response.status_code), f"Upload failed: {response.text}"
58
-
59
- # except Exception as e:
60
- # logger.log(f"Error uploading document: {str(e)}")
61
- # raise
62
- # finally:
63
- # # Cleanup
64
- # if os.path.exists(temp_dir):
65
- # shutil.rmtree(temp_dir)
66
-
67
- def email_document_upload(self):
68
- try:
69
- if 'file' not in request.files:
70
- return "file not found"
71
-
72
- file = request.files['file']
73
- if file.filename == '':
74
- return "No selected file"
75
57
 
76
- upload_config = {
77
- 'token_id': request.form.get('TOKEN_ID'),
78
- 'document_type': request.form.get('DOCUMENT_TYPE', ''),
79
- 'obj_name': request.form.get('OBJ_NAME', ''),
80
- 'file_type': request.form.get('FILE_TYPE', ''),
81
- 'app_id': request.form.get('APP_ID', ''),
82
- 'method': request.form.get('Method_Type', 'POST'),
83
- 'url': request.form.get('RestAPI_Url')
84
- }
58
+ def email_document_upload(self, file, parameters_details):
59
+ logger.log(f"file ::: {file}")
60
+ if not file:
61
+ return "file not found"
85
62
 
86
- # Validate required fields
87
- if not upload_config['token_id'] or not upload_config['url']:
88
- return "Missing required fields: TOKEN_ID or RestAPI_Url"
89
-
90
- file_data = {
91
- 'filename': file.filename,
92
- 'content': file.read()
93
- }
63
+ upload_config = {
64
+ 'token_id': parameters_details.get('TOKEN_ID'),
65
+ 'document_type': parameters_details.get('DOCUMENT_TYPE', ''),
66
+ 'obj_name': parameters_details.get('OBJ_NAME', ''),
67
+ 'file_type': parameters_details.get('FILE_TYPE', ''),
68
+ 'app_id': parameters_details.get('APP_ID', ''),
69
+ 'method': parameters_details.get('Method_Type', 'POST'),
70
+ 'url': parameters_details.get('RestAPI_Url')
71
+ }
94
72
 
95
- result = self.upload_document(upload_config, file_data)
96
-
97
- logger.log(f"Upload_Document response result: {result}")
98
- return "success"
73
+ # Validate required fields
74
+ if not upload_config['token_id'] or not upload_config['url']:
75
+ return "Missing required fields: TOKEN_ID or RestAPI_Url"
76
+
77
+ file_data = {
78
+ 'filename': os.path.basename(file.name),
79
+ 'content': file.read()
80
+ }
99
81
 
100
- except Exception as e:
101
- logger.log(f"Error in Upload_Document: {str(e)}")
82
+ response_status, restAPI_Result = self.upload_document(upload_config, file_data)
83
+
84
+ logger.log(f"Upload_Document response result: {restAPI_Result}")
85
+ return response_status, restAPI_Result
@@ -12,7 +12,6 @@ class Email_Draft:
12
12
  try:
13
13
  with imaplib.IMAP4_SSL(host=email_config['host'], port=imaplib.IMAP4_SSL_PORT) as imap_ssl:
14
14
  imap_ssl.login(email_config['email'], email_config['password'])
15
- logger.log(f"login successfully")
16
15
 
17
16
  message = Message()
18
17
  message["From"] = email_config['email']
@@ -28,7 +27,7 @@ class Email_Draft:
28
27
  message.set_payload(f"{response_content}\n\n{mail_details}\n\n{email_details['body']}")
29
28
 
30
29
  utf8_message = str(message).encode("utf-8")
31
- logger.log(f"utf8_message:: {utf8_message}")
30
+ # logger.log(f"utf8_message:: {utf8_message}")
32
31
  imap_ssl.append("[Gmail]/Drafts", '', imaplib.Time2Internaldate(time.time()), utf8_message)
33
32
 
34
33
  return True, utf8_message.decode("utf-8")
@@ -57,11 +56,8 @@ class Email_Draft:
57
56
  logger.log(f"Error creating draft: {str(e)}")
58
57
  return "Failed", None
59
58
 
60
- def draft_mail(self):
59
+ def draft_mail(self, data):
61
60
  try:
62
- data = request.get_data('jsonData', None)
63
- data = json.loads(data[9:])
64
- logger.log(f"jsondata:: {data}")
65
61
 
66
62
  if "reciever_email_addr" in data and data["reciever_email_addr"] != None:
67
63
  reciever_email_addr = data["reciever_email_addr"]
@@ -4,14 +4,21 @@ import os
4
4
  import json
5
5
  import time
6
6
  import loggerutility as logger
7
- from flask import Flask, request
7
+ from flask import request
8
+ import traceback
9
+ from fpdf import FPDF
10
+
8
11
  from .Save_Transaction import Save_Transaction
9
12
  from .Email_Upload_Document import Email_Upload_Document
13
+ from .Email_Classification import Email_Classification
14
+ from .EmailReplyAssistant import EmailReplyAssistant
15
+ from .Email_Draft import Email_Draft
16
+ from .Email_DocumentUploader import Email_DocumentUploader
10
17
 
11
18
  class Email_Read:
12
19
  def read_email(self, email_config):
13
20
  try:
14
- logger.log("inside function")
21
+ logger.log("inside read_email")
15
22
  mail = imaplib.IMAP4_SSL(email_config['host'], email_config['port'])
16
23
  mail.login(email_config['email'], email_config['password'])
17
24
  logger.log("login successfully")
@@ -26,7 +33,7 @@ class Email_Read:
26
33
 
27
34
  if not email_ids:
28
35
  logger.log("Email not found, going to check new mail")
29
- print("Email not found,\ngoing to check new mail \n")
36
+ logger.log("Email not found,\ngoing to check new mail \n")
30
37
  else:
31
38
 
32
39
  for email_id in email_ids:
@@ -64,23 +71,6 @@ class Email_Read:
64
71
  call_save_transaction = Save_Transaction()
65
72
  save_transaction_response = call_save_transaction.email_save_transaction(email_data)
66
73
  logger.log(f"save_transaction_response:: {save_transaction_response}")
67
-
68
- if save_transaction_response['status'] == "Success":
69
- if msg.is_multipart():
70
- for part in msg.walk():
71
- content_disposition = str(part.get("Content-Disposition"))
72
-
73
- if "attachment" in content_disposition:
74
- attachment_path = self.save_attachment(part, "attachments")
75
- if attachment_path:
76
- logger.log(f"Attachment saved at: {attachment_path}")
77
- attachments.append(attachment_path)
78
- for file_path in attachments:
79
- logger.log(f"file_path:: {file_path}")
80
- email_upload_doc = Email_Upload_Document()
81
- email_file_upload = email_upload_doc.upload_files(file_path)
82
- logger.log(f"file uploaded :: {email_file_upload}")
83
- logger.log(f"emails:: {emails}")
84
74
  time.sleep(10)
85
75
 
86
76
  except Exception as e:
@@ -92,6 +82,181 @@ class Email_Read:
92
82
  except Exception as close_error:
93
83
  logger.log(f"Error during mail close/logout: {str(close_error)}")
94
84
 
85
+ def read_email_automation(self, email_config):
86
+ # try:
87
+ logger.log(f"inside read_email_automation")
88
+ # logger.log(f"email_config ::: {email_config}")
89
+ LABEL = "Unprocessed_Email"
90
+ file_JsonArray = []
91
+ templateName = "ai_email_automation.json"
92
+ fileName = ""
93
+
94
+ Model_Name = email_config.get('model_type', 'OpenAI')
95
+ reciever_email_addr = email_config.get('email', '')
96
+ receiver_email_pwd = email_config.get('password', '')
97
+ host = email_config.get('host', '')
98
+ port = email_config.get('port', '')
99
+
100
+ mail = imaplib.IMAP4_SSL(host, port)
101
+ mail.login(reciever_email_addr, receiver_email_pwd)
102
+ logger.log("login successfully")
103
+ mail.select('inbox')
104
+
105
+ file_JsonArray, categories = self.read_JSON_File(templateName)
106
+
107
+ while True:
108
+ status, email_ids = mail.search(None, 'UNSEEN')
109
+ emails = []
110
+
111
+ if status == 'OK':
112
+ email_ids = email_ids[0].split()
113
+
114
+ if not email_ids:
115
+ logger.log("Email not found, going to check new mail")
116
+ logger.log("Email not found,\ngoing to check new mail \n")
117
+ else:
118
+
119
+ for email_id in email_ids:
120
+ email_body = ""
121
+ attachments = []
122
+ status, data = mail.fetch(email_id, '(RFC822)')
123
+
124
+ if status == 'OK':
125
+ raw_email = data[0][1]
126
+ msg = email.message_from_bytes(raw_email)
127
+
128
+ subject = msg['Subject']
129
+ sender_email_addr = msg['From']
130
+ cc_email_addr = msg['CC']
131
+ subject = msg['Subject']
132
+
133
+ if msg.is_multipart():
134
+ for part in msg.walk():
135
+ content_type = part.get_content_type()
136
+ if content_type == "text/plain":
137
+ email_body += part.get_payload(decode=True).decode('utf-8', errors='replace')
138
+ fileName = self.download_attachment(msg)
139
+ else:
140
+ email_body = msg.get_payload(decode=True).decode('utf-8', errors='replace')
141
+
142
+ openai_Process_Input = email_body
143
+ logger.log("\nEmail Subject:::", subject)
144
+ logger.log("\nEmail body:::", openai_Process_Input )
145
+
146
+ openai_api_key = email_config.get('openai_api_key', '')
147
+ geminiAI_APIKey = email_config.get('gemini_api_key', '')
148
+ signature = email_config.get('signature', '')
149
+ localAIURL = email_config.get('local_ai_url', '')
150
+
151
+ if len(str(openai_Process_Input)) > 0 :
152
+ email_cat_data = {
153
+ "model_type" : Model_Name,
154
+ "openai_api_key" : openai_api_key,
155
+ "categories" : categories,
156
+ "email_body" : email_body,
157
+ "gemini_api_key" : geminiAI_APIKey,
158
+ "signature" : signature,
159
+ "local_ai_url" : localAIURL,
160
+ }
161
+ # logger.log(f"\nemail_cat_data ::: {email_cat_data}")
162
+ email_classification = Email_Classification()
163
+ emailCategory = email_classification.detect_category(email_cat_data)
164
+ emailCategory = emailCategory['message']
165
+ logger.log(f"\nDetected Email category ::: {emailCategory}")
166
+
167
+ if emailCategory == 'Others':
168
+ logger.log(f"Marking email as UNREAD. ")
169
+ mail.store(email_id, '-FLAGS', '\\Seen')
170
+
171
+ mail.create(LABEL)
172
+ mail.copy(email_id, LABEL)
173
+ mail.store(email_id, '+FLAGS', '\\Deleted') # Mark for deletion
174
+ mail.expunge()
175
+ logger.log(f"Mail removed from inbox and added to '{LABEL}' label.")
176
+
177
+ elif emailCategory == "Product Enquiry":
178
+
179
+ if Model_Name == "OpenAI":
180
+ responseMethod, parameters = self.get_JsonArray_values(emailCategory, file_JsonArray)
181
+ if responseMethod == "Reply_Email_Ai_Assistant" :
182
+
183
+ emailreplyassistant = EmailReplyAssistant()
184
+ openai_Response = emailreplyassistant.Reply_Email_Ai_Assistant(openai_api_key, parameters["Assistant_Id"], openai_Process_Input, subject)
185
+
186
+ logger.log(f"Process openai_Response ::: {openai_Response['message']}\n")
187
+ email_details = {"sender":sender_email_addr, "cc":cc_email_addr, "subject":subject, "body": email_body}
188
+
189
+ email_draft = Email_Draft()
190
+ status, response = email_draft.draft_email(email_config, email_details, openai_Response['message'])
191
+ logger.log(f"status ::: {status}")
192
+ else :
193
+ message = f"Invalid response method received '{responseMethod}' for category : '{emailCategory}'"
194
+ raise ValueError(message)
195
+ elif Model_Name == "LocalAI":
196
+ logger.log("localAI")
197
+ Detect_Email_category = False
198
+ LocalAI_Response = emailCategory
199
+ logger.log(f"Process LocalAI_Response ::: {LocalAI_Response}\n")
200
+ email_details = {"sender":sender_email_addr, "cc":cc_email_addr, "subject":subject, "body": email_body}
201
+
202
+ email_draft = Email_Draft()
203
+ status, response = email_draft.draft_email(email_config, email_details, LocalAI_Response)
204
+ logger.log(f"status ::: {status}")
205
+ elif Model_Name == "GeminiAI":
206
+ logger.log("GeminiAI")
207
+ Detect_Email_category = False
208
+ GeminiAI_Response = emailCategory
209
+ logger.log(f"Process GeminiAI_Response ::: {GeminiAI_Response}\n")
210
+ email_details = {"sender":sender_email_addr, "cc":cc_email_addr, "subject":subject, "body": email_body}
211
+
212
+ email_draft = Email_Draft()
213
+ status, response = email_draft.draft_email(email_config, email_details, GeminiAI_Response)
214
+ logger.log(f"status ::: {status}")
215
+ else:
216
+ raise ValueError(f"Invalid Model Name provided : '{Model_Name}'")
217
+
218
+ elif emailCategory == "Purchase Order":
219
+ responseMethod, parameters = self.get_JsonArray_values(emailCategory, file_JsonArray)
220
+ logger.log(f"responseMethod ::: {responseMethod}")
221
+ logger.log(f"parameters ::: {parameters}")
222
+ if responseMethod == "Upload_Document" :
223
+
224
+ if len(fileName) != 0 :
225
+
226
+ email_upload_document = Email_DocumentUploader()
227
+ with open(f"temp/{fileName}", "rb") as file:
228
+ response_status, restAPI_Result = email_upload_document.email_document_upload(file, parameters)
229
+ logger.log(f"email_upload_document_response ::: {restAPI_Result}")
230
+ else:
231
+
232
+ new_fileName = self.create_file_from_emailBody(email_body, sender_email_addr, parameters)
233
+ with open(f"temp/{new_fileName}", "rb") as file:
234
+ response_status, restAPI_Result = email_upload_document.email_document_upload(file, parameters)
235
+ logger.log(f"email_upload_document_response ::: {restAPI_Result}")
236
+
237
+ if response_status == "200" :
238
+ logger.log(f"Attachment uploaded sucessfully against Document id: '{restAPI_Result}'.")
239
+ else:
240
+ logger.log(restAPI_Result)
241
+
242
+ else :
243
+ message = f"Invalid response method received '{responseMethod}' for category : '{emailCategory}'"
244
+ raise ValueError(message)
245
+ else:
246
+ message = f"Detected Email category not found : '{emailCategory}'"
247
+ raise ValueError(message)
248
+ time.sleep(10)
249
+
250
+ # except Exception as e:
251
+ # return {"status": "Failed", "message": f"Error reading emails: {str(e)}"}
252
+ # finally:
253
+ # try:
254
+ # mail.close()
255
+ # mail.logout()
256
+ # except Exception as close_error:
257
+ # logger.log(f"Error during mail close/logout: {str(close_error)}")
258
+ # return {"status": "Failed", "message": f"Error reading emails: {str(close_error)}"}
259
+
95
260
  def save_attachment(self, part, download_dir):
96
261
  try:
97
262
  filename = part.get_filename()
@@ -109,11 +274,8 @@ class Email_Read:
109
274
  except Exception as e:
110
275
  return {"success": "Failed", "message": f"Error saving attachment: {str(e)}"}
111
276
 
112
- def Read_Email(self):
277
+ def Read_Email(self, data):
113
278
  try:
114
- data = request.get_data('jsonData', None)
115
- data = json.loads(data[9:])
116
- logger.log(f"jsondata:: {data}")
117
279
 
118
280
  reciever_email_addr = data.get("reciever_email_addr")
119
281
  receiver_email_pwd = data.get("receiver_email_pwd")
@@ -141,5 +303,101 @@ class Email_Read:
141
303
  except Exception as e:
142
304
  logger.log(f"Error in Read_Email: {str(e)}")
143
305
 
306
+ def download_attachment(self, msg):
307
+ filepath = ""
308
+ filename = ""
309
+ ATTACHMENT_SAVE_PATH = "temp"
310
+
311
+ for part in msg.walk():
312
+ if part.get_content_maintype() == 'multipart':
313
+ continue
314
+ if part.get('Content-Disposition') is None:
315
+ continue
316
+ filename = part.get_filename()
317
+ if filename:
318
+ if not os.path.exists(ATTACHMENT_SAVE_PATH):
319
+ os.mkdir(ATTACHMENT_SAVE_PATH)
320
+ filepath = os.path.join(ATTACHMENT_SAVE_PATH, filename)
321
+ else:
322
+ filepath = os.path.join(ATTACHMENT_SAVE_PATH, filename)
323
+ with open(filepath, 'wb') as f:
324
+ f.write(part.get_payload(decode=True))
325
+ logger.log(f"\nAttachment saved: '{filepath}'")
326
+ else:
327
+ logger.log("\nNo Attachment found.")
328
+ return filename
329
+
330
+ def read_JSON_File(self, json_fileName):
331
+ category_list = []
332
+ categories = ""
333
+ try:
334
+ if os.path.exists(json_fileName):
335
+ with open(json_fileName, "r") as fileObj:
336
+ file_JsonArray = json.load(fileObj)
337
+
338
+ for eachJson in file_JsonArray :
339
+ for key, value in eachJson.items():
340
+ if key == "Category" and value:
341
+ category_list.append(value)
342
+ # categories = ", ".join(category_list)
343
+
344
+ return file_JsonArray, category_list
345
+
346
+ else:
347
+ message = f"{json_fileName} file not found."
348
+ raise Exception(message)
349
+ except Exception as e:
350
+ msg = f"'{json_fileName}' file is empty. Please provide JSON parameters in the filename."
351
+ trace = traceback.format_exc()
352
+ logger.log(f"Exception in writeJsonFile: {msg} \n {trace} \n DataType ::: {type(msg)}")
353
+ raise Exception(msg)
354
+
355
+ def get_JsonArray_values(self, category, jsonArray):
356
+ responseMethod = ""
357
+ parameters = ""
358
+
359
+ for eachJson in jsonArray :
360
+ for key, value in eachJson.items():
361
+ if value == category:
362
+ responseMethod = eachJson["Response_Method"]
363
+ parameters = eachJson["Parameters"]
364
+
365
+ return responseMethod, parameters
366
+
367
+ def create_file_from_emailBody(self, text, sender_email_addr, parameters):
368
+
369
+ dir = "temp/"
370
+ if not os.path.exists(dir):
371
+ os.mkdir(dir)
372
+ fileName = sender_email_addr[sender_email_addr.find("<")+1:sender_email_addr.find("@")].strip().replace(".","_")
373
+ logger.log(f"{fileName = }")
374
+
375
+ if parameters["FILE_TYPE"] == "pdf":
376
+ fileName = fileName + ".pdf"
377
+ filePath = dir + fileName
378
+
379
+ pdf = FPDF()
380
+ pdf.add_page()
381
+ pdf.set_font("Arial", size=12)
382
+ pdf.multi_cell(0, 10, text)
383
+ pdf.output(filePath)
384
+ logger.log(f"New PDF file created from email body and stored in '{filePath}'")
385
+
386
+ elif parameters["FILE_TYPE"] == "txt":
387
+ fileName = fileName + ".txt"
388
+ filePath = dir + fileName
389
+
390
+ with open(filePath, "w") as file:
391
+ file.write(text)
392
+ logger.log(f"New TXT file created from email body and stored in '{filePath}'")
393
+ else:
394
+ message = f"Invalid File Type received. "
395
+ self.send_response(200)
396
+ self.send_header('Content-type', 'text/html')
397
+ self.end_headers()
398
+ self.wfile.write(message.encode('utf-8'))
399
+
400
+ return fileName
401
+
144
402
 
145
403
 
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: AIEmailAutomationUtility
3
- Version: 0.0.9
4
- Summary: Change the logic of return exception value
3
+ Version: 0.0.10
4
+ Summary: Create 2 different methods in read_email for different client
5
5
  Author: Proteus Technology PVT. LTD.
6
6
  Author-email: <apps@baseinformation.com>
7
7
  Keywords: python,first package
@@ -13,4 +13,4 @@ Classifier: Operating System :: MacOS :: MacOS X
13
13
  Classifier: Operating System :: Microsoft :: Windows
14
14
  License-File: LICENCE.txt
15
15
 
16
- Change the logic of return exception value
16
+ Create 2 different methods in read_email for different client
@@ -0,0 +1,14 @@
1
+ AIEmailAutomationUtility/EmailReplyAssistant.py,sha256=NQlBPugGdEvNwGFOoaiJNb4JDQB_DYvCy_hWLgAVLns,3938
2
+ AIEmailAutomationUtility/Email_Classification.py,sha256=eL52Td50zo7V0QTIqjN4Khhg-5HKvf2RUITIcKz5yZ0,9343
3
+ AIEmailAutomationUtility/Email_DocumentUploader.py,sha256=ImTmMz_JeU6Xynt9kyu7lFv7vqrxzqAtBF-A7014fYc,3055
4
+ AIEmailAutomationUtility/Email_Draft.py,sha256=BfseewnnlwNl1moodq3kZiUPXDUE9a_nQjuFQsUp3fY,5244
5
+ AIEmailAutomationUtility/Email_Read.py,sha256=bmRS_jt_v0BxsOWQZcH12VKhcWUbc9dNuw3qkvbGCN4,20516
6
+ AIEmailAutomationUtility/Email_Upload_Document.py,sha256=3bdkxfDlwoeRp-46KPw2Gs1dqBhEIoA1yE5GCudpdV8,1320
7
+ AIEmailAutomationUtility/Save_Draft.py,sha256=yzLgFN14I_lXE6qL0I3tKNduvcnWdbsY9i2mKdTtio4,5348
8
+ AIEmailAutomationUtility/Save_Transaction.py,sha256=Gg1w6hhzHmEFjsuzYvkq-3-EsWReetjLHsYSv5YIGgM,3816
9
+ AIEmailAutomationUtility/__init__.py,sha256=bB7N-qQD85RdMaXHg_ZU5oPtHtx9zgeG6-ue4rhcfYI,379
10
+ AIEmailAutomationUtility-0.0.10.dist-info/LICENCE.txt,sha256=2qX9IkEUBx0VJp1Vh9O2dsRwE-IpYId0lXDyn7OVsJ8,1073
11
+ AIEmailAutomationUtility-0.0.10.dist-info/METADATA,sha256=iG4GkrRFAa5-1rXSU-nXQmnMbSqkIso7QKXPF7j4S78,623
12
+ AIEmailAutomationUtility-0.0.10.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
13
+ AIEmailAutomationUtility-0.0.10.dist-info/top_level.txt,sha256=3jTWrTUblVkaP7mpwY2UBSnrlfot5Ykpfsehyke-Uzw,25
14
+ AIEmailAutomationUtility-0.0.10.dist-info/RECORD,,
@@ -1,14 +0,0 @@
1
- AIEmailAutomationUtility/EmailReplyAssistant.py,sha256=jFkOA0yfxRybICjeKsq4xDetTr6vPjkprkrXATsUpH8,4071
2
- AIEmailAutomationUtility/Email_Classification.py,sha256=NhJwKFGVjLd4BsIFPAWs9qKAUYTxRTYyWd-BvjONXF0,9476
3
- AIEmailAutomationUtility/Email_DocumentUploader.py,sha256=0AWcwAx7x4WiZwFBxHwdFpUfE9wjvLGcaxT_95bqRcY,3496
4
- AIEmailAutomationUtility/Email_Draft.py,sha256=WUdaSLk4xTwMs1wSOUXE2xiDUehsZQ2wGqvWtXbjeo0,5427
5
- AIEmailAutomationUtility/Email_Read.py,sha256=ScuF5zFimkiIUX91-WhgNL18RbhHrcWe7fbbRwDGB7w,6717
6
- AIEmailAutomationUtility/Email_Upload_Document.py,sha256=3bdkxfDlwoeRp-46KPw2Gs1dqBhEIoA1yE5GCudpdV8,1320
7
- AIEmailAutomationUtility/Save_Draft.py,sha256=yzLgFN14I_lXE6qL0I3tKNduvcnWdbsY9i2mKdTtio4,5348
8
- AIEmailAutomationUtility/Save_Transaction.py,sha256=Gg1w6hhzHmEFjsuzYvkq-3-EsWReetjLHsYSv5YIGgM,3816
9
- AIEmailAutomationUtility/__init__.py,sha256=bB7N-qQD85RdMaXHg_ZU5oPtHtx9zgeG6-ue4rhcfYI,379
10
- AIEmailAutomationUtility-0.0.9.dist-info/LICENCE.txt,sha256=2qX9IkEUBx0VJp1Vh9O2dsRwE-IpYId0lXDyn7OVsJ8,1073
11
- AIEmailAutomationUtility-0.0.9.dist-info/METADATA,sha256=mkiZRpGQHUuxEyDs1rK4af1Zte1vzUNdvUrH-wlPnLo,584
12
- AIEmailAutomationUtility-0.0.9.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
13
- AIEmailAutomationUtility-0.0.9.dist-info/top_level.txt,sha256=3jTWrTUblVkaP7mpwY2UBSnrlfot5Ykpfsehyke-Uzw,25
14
- AIEmailAutomationUtility-0.0.9.dist-info/RECORD,,