瀏覽代碼

智能邮件客服初版7

lhq 4 年之前
父節點
當前提交
586f997267
共有 5 個文件被更改,包括 902 次插入118 次删除
  1. 132 70
      Utils/NeteaseMail.py
  2. 507 48
      controller/ComprehendController.py
  3. 200 0
      emailtrainfile/emailtrain.csv
  4. 1 0
      model/models.py
  5. 62 0
      readme.md

+ 132 - 70
Utils/NeteaseMail.py

@@ -1,37 +1,68 @@
 import email
+import pathlib
 import smtplib
-from email.header import  Header
+from email.header import Header
+from email.mime.application import MIMEApplication
 from email.mime.text import MIMEText
+from email.mime.image import MIMEImage
+from email.mime.multipart import MIMEMultipart
 from nntplib import decode_header
 from imapclient import IMAPClient
 
 import email.parser
 
+import boto3
+import time
+import chardet
+import sys
+import importlib
+
+importlib.reload(sys)
+import os
+
+
 class NeteaseMail:
+    # aws 账号登录
+    def aws_login(self):
+        client = boto3.client(service_name='comprehend', region_name='us-east-1',
+                              aws_access_key_id='AKIA2E67UIMD45Y3HL53',
+                              aws_secret_access_key='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')
+        return client
+
+    def aws_arn(self):
+        document_classifier = 'arn:aws:comprehend:us-east-1:697864307463:document-classifier/'
+        endpoint = 'arn:aws:comprehend:us-east-1:697864307463:document-classifier-endpoint/'
+        return document_classifier, endpoint
+
+    def s3_login(self):
+        client = boto3.client(service_name='s3', region_name='us-east-1',
+                              aws_access_key_id='AKIA2E67UIMD45Y3HL53',
+                              aws_secret_access_key='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')
+        return client
 
     # 连接邮箱服务器并登录。
     def loginEmail(self, imap_server, from_addr, password, imap_port, isssl=True):
         '''第一部分:收件IMAP4********************************************'''
         '''登录邮箱IMAP4=========================================================='''
         email_server = None
-        #993  465
+        # 993  465
         try:
 
             email_server = IMAPClient(imap_server, ssl=isssl, port=imap_port)
-            #email_server = imaplib.IMAP4_SSL(IMAP_SERVER, 993)  # 网易企业邮箱服务器及SSL端口
+            # email_server = imaplib.IMAP4_SSL(IMAP_SERVER, 993)  # 网易企业邮箱服务器及SSL端口
             print("imap4 服务器连接成功")
 
             email_server.login(from_addr, password)
 
             email_server.id_({"name": "IMAPClient", "version": "2.1.0"})
-            #email_server.login(FROM_ADDR, PASSWORD)
-            print("imap4 账号密码正确,登录成功")
+            # email_server.login(FROM_ADDR, PASSWORD)
+            print("imap4 (%s)账号密码正确,登录成功" % from_addr)
         except:
             print("imap4 服务器连接失败")
         else:
             return email_server
 
-    #关闭邮箱服务器连接
+    # 关闭邮箱服务器连接
     def closeEmail(self, email_server):
         # 关闭select
         email_server.shutdown()
@@ -39,54 +70,86 @@ class NeteaseMail:
         # 关闭连接
         # email_server.logout()
 
-    #获取邮箱内容、标题、发件人
+    # 获取邮箱内容、标题、发件人
     def getEmailContext(self, email_server):
         ''' 邮箱中收到的未读邮件的数量=========================================================='''
-        #email_server.select_folder('INBOX', readonly=True)
+        # email_server.select_folder('INBOX', readonly=True) # readonly=True表明只读并不修改任何信息
 
-        email_server.select_folder('INBOX', readonly=True)  # readonly=True表明只读并不修改任何信息
-        results = email_server.search()
+        global a
+        email_server.select_folder('INBOX')
+        results = email_server.search('UNSEEN')  # 读取未读邮件
+        print("邮箱内获取到未读邮件:", len(results))
         subject_list = []
         bodydata_list = []
         from_list = []
+        uid_list = []
+        email_body = []
+        fujian_list = []
+        image_list = []
         try:
             for uid in results:
-                msgdict = email_server.fetch(uid, ['Body[]','ENVELOPE'], '(RFC822)')
+                msgdict = email_server.fetch(uid, ['Body[]', 'ENVELOPE'], '(RFC822)')
                 mailbody = msgdict[uid][b'BODY[]']
                 envelope = msgdict[uid][b'ENVELOPE']
                 message = email.message_from_bytes(mailbody)
-
-                msgfrom = message['from']
-
                 text = message.as_string()
                 body = email.parser.Parser().parsestr(text)
+                email_body.append(body)
+
+                nowtime = time.asctime(time.localtime(time.time()))
+                nowmonth = nowtime.split()[1]
+                nowday = nowtime.split()[2]
+                emailmonth = body['Date'].split()[2]
+                emailday = body['Date'].split()[1]
+                if emailmonth != nowmonth or emailday != nowday:
+                    email_server.remove_flags(uid, b'\\Seen', silent=False)
+                    continue
+
+                subject_list.append(decode_header(body['Subject']))
+                from_list.append(decode_header(body['from']))
+                uid_list.append(uid)
+
+                attlist = {}
                 for part in body.walk():
-
-                    if part['Subject']:
-                        subject_list.append(decode_header(part['Subject']))
-
-                    if part['from']:
-                        from_list.append(decode_header(part['from']))
-
                     if not part.is_multipart():
-                        name = part.get_param("name")  # 如果是附件,这里就会取出附件的文件名
-                        if name:
-                           print('附件')
+                        file = part.get_filename()  # 附件名
+                        if file:
+                            a = 1
+                            filename = email.header.decode_header(file)[0][0]  # 附件名
+                            charset = email.header.decode_header(file)[0][1]  # 编码
+                            if part.get_all("Content-ID"):
+                                content_id = part.get_all("Content-ID")[0][1:-1]
+                            else:
+                                content_id = ""  # 附件ID,也就是邮件源码里面的cid
+                            ''' 多个附件时将附件名和ID对应保存到dict里面,后面将正文中的cid替换为本地保存路径 '''
+                            attlist[content_id] = filename
+                            ''' 附件文件名为中文或有编码的时候要进行转码 '''
+                            if str(charset) != "None":
+                                filename = filename.decode(charset)
+                            filedata = part.get_payload(decode=True)  # 附件内容
+                            ''' 把附件写到文件里面,附件一定要用wb打开,二进制 '''
+                            file_path = os.path.join(os.path.dirname(__file__) + '/../emailtrainfile/image/')
+                            image_list.append(file_path + filename)
+                            with open(file_path + filename, "wb") as fw:
+                                fw.write(filedata)
+                                fw.close()
+
                         elif part.get_content_type() == 'text/plain':
                             con3 = part.get_payload(decode=True).strip()
-                            bodydata_list.append(con3.decode('gbk'))
-                            break
-                        else:
-                            con3 = part.get_payload(decode=True).strip()
-                            bodydata_list.append(con3.decode('utf8'))
-                            break
-                        # print '+'*60 # 用来区别各个部分的输出
+                            print(chardet.detect(con3))
+                            if chardet.detect(con3)['encoding'] == 'utf-8':
+                                bodydata_list.append(con3.decode('utf-8'))
+                            else:
+                                bodydata_list.append(con3.decode('gbk'))
+                if a == 1:
+                    fujian_list.append('have')
+                email_server.remove_flags(uid, b'\\Seen', silent=False)
 
-
-        except:
-           print('获取内容出错')
+        except Exception as e:
+            print(e)
+            print('获取内容出错')
         else:
-            return subject_list, from_list, bodydata_list
+            return subject_list, from_list, bodydata_list, uid_list, results, email_body, fujian_list, image_list
         # if subject_list and bodydata_list:
         #     data_unseen = [subject_list, bodydata_list]
         #     data_unseen1 = pd.DataFrame(data_unseen)
@@ -106,9 +169,8 @@ class NeteaseMail:
         #     upload_key = "86YC8Z192VB1VMKU111A/vod1/test"
         #     file_obj = s3.Bucket(bucket).put_object(Key=upload_key, Body=upload_data)
 
-
-    #发送邮箱
-    def faEmail(self,email_server,message,subject,from_addr,to_addr):
+    # 发送邮箱
+    def faEmail(self, email_server, message, subject, from_addr, to_addr):
         if email_server:
             print("邮件开始发送")
 
@@ -127,11 +189,13 @@ class NeteaseMail:
 
         email_server.quit()
 
-    def sentemail(self,message,subject,from_addr,to_addr,iemial, ipassword):
+    def sentemail(self, email_server, uid, message, image, subject, from_addr, to_addr, iemial, ipassword):
         host = 'smtp.163.com'
         # 设置发件服务器地址
         port = 465
         # 设置发件服务器端口号。注意,这里有SSL和非SSL两种形式,现在一般是SSL方式
+        # host = 'smtp.qiye.163.com'
+        # port = 994
         sender = iemial
         # 设置发件邮箱,一定要自己注册的邮箱
         pwd = ipassword
@@ -140,13 +204,33 @@ class NeteaseMail:
         # 设置邮件接收人,可以是QQ邮箱
         body = message
         # 设置邮件正文,这里是支持HTML的
-        msg = MIMEText(body, 'html')
+        msg = MIMEMultipart()
+        # msg = MIMEText(body, 'html')
+        # msg = MIMEText(body, 'plain', 'utf-8')
+        msg.attach(MIMEText(body, 'plain', 'utf-8'))
+        msg.attach(MIMEText(body, 'html', 'utf-8'))
+        if image:
+            for i in image:
+                print(i.split('.')[-1])
+                if i.split('.')[-1] == 'png' and 'jpeg' and 'jpg':
+                    with open(i, 'rb') as f:
+                        msgImage = MIMEImage(f.read())
+                    # 定义图片ID
+                    msgImage.add_header('Content-ID', '<image1>')
+                    msg.attach(msgImage)  # 添加图片
+                else:
+                    part_attach1 = MIMEApplication(open(i, 'rb').read())  # 打开附件
+                    # 构建邮件附件
+                    part_attach1.add_header('Content-Disposition', 'attachment', filename=pathlib.Path(i).name)  # 为附件命名
+                    msg.attach(part_attach1)  # 添加附件
+
+
         # 设置正文为符合邮件格式的HTML内容
         msg['subject'] = subject
         # 设置邮件标题
-        msg['from'] = from_addr
+        msg['from'] = Header(from_addr)
         # 设置发送人
-        msg['to'] = to_addr
+        msg['to'] = Header(to_addr)
         # 设置接收人
         try:
             s = smtplib.SMTP_SSL(host, port)
@@ -155,31 +239,9 @@ class NeteaseMail:
             # 登陆邮箱
             s.sendmail(sender, receiver, msg.as_string())
             # 发送邮件!
-            print('Done.sent email success')
-        except smtplib.SMTPException:
-            print('Error.sent email fail')
-
-    # mailto_list = ['xxxxxx@xx.com]
-    #                mail_host = "smtp.163.com"
-    # mail_user = "xxxxxx"
-    # mail_pass = "xxxxxxxxxx"
-    #
-    # def send_mail(mailto_list, sub, content,mail_user,mail_pass):
-    #     me = "hello" + "<" + mail_user + "@1368035>"
-    #     msg = MIMEText(content, _subtype='plain')
-    #     msg['Subject'] = sub
-    #     msg['From'] = me
-    #     try:
-    #         for mail in mailto_list:
-    #             msg['To'] = mail
-    #             server = smtplib.SMTP()
-    #             server.connect(mail_host)
-    #             server.login(mail_user, mail_pass)
-    #             server.sendmail(me, mail, msg.as_string())
-    #             server.close()
-    #             del msg['To']
-    #         return True
-    #     except Exception, e:
-    #         print
-    #         str(e)
-    #         return False
+            print('邮件转发成功')
+            email_server.set_flags(uid, b'\\Seen', silent=False)
+        except smtplib.SMTPException as e:
+            print(e)
+            print('邮件转发失败')
+            email_server.remove_flags(uid, b'\\Seen', silent=False)

+ 507 - 48
controller/ComprehendController.py

@@ -1,13 +1,20 @@
+import imaplib
+import shutil
+import smtplib
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+
 import boto3
 from boto3 import Session
 from django.views import View
 
-
 from model.models import EmailSortModel, EmailConfigModel
 from Utils.NeteaseMail import NeteaseMail
 from django.views.generic import TemplateView
 
 from object.ResponseObject import ResponseObject
+import os
+import csv
 
 
 class ComprehendView(TemplateView):
@@ -31,10 +38,28 @@ class ComprehendView(TemplateView):
                 return self.createSort(request_dict, response)
             elif operation == 'doStartSortWord':
                 return self.doStartSortWord(request_dict, response)
+            elif operation == 'write_csv':
+                return self.write_csv(request_dict, response)
+            elif operation == 'upload_csv':
+                return self.upload_csv(request_dict, response)
+            elif operation == 'create_document_classifier':
+                return self.create_document_classifier(request_dict, response)
+            elif operation == 'create_endpoint':
+                return self.create_endpoint(request_dict, response)
+            elif operation == 'describe_document_classifier':
+                return self.describe_document_classifier(request_dict, response)
+            elif operation == 'describe_endpoint':
+                return self.describe_endpoint(request_dict, response)
+            elif operation == 'delete_endpoint':
+                return self.delete_endpoint(request_dict, response)
+            elif operation == 'delete_document_classifier':
+                return self.delete_document_classifier(request_dict, response)
             elif operation == 'getDocumentClassifier':
                 return self.get_document_classifier(request_dict, response)
+            elif operation == 'email':
+                return self.email(request_dict, response)
 
-    def createSort(self,request_dict, response):
+    def createSort(self, request_dict, response):
         client = boto3.client('comprehend', region_name='region')
 
         # Create a document classifier
@@ -57,8 +82,7 @@ class ComprehendView(TemplateView):
         list_response = client.list_document_classifiers()
         print("List response: %s\n", list_response)
 
-
-    def doStartSortWord(self,request_dict, response):
+    def doStartSortWord(self, request_dict, response):
         client = boto3.client('comprehend', region_name='region')
 
         start_response = client.start_document_classification_job(
@@ -84,66 +108,501 @@ class ComprehendView(TemplateView):
         list_response = client.list_document_classification_jobs()
         print("List response: %s\n", list_response)
 
+    def write_csv(self, request_dict, response):
+        file_path = os.path.join(os.path.dirname(__file__) + '/../emailtrainfile/emailtrain.csv')
+        with open(file_path, "w", newline='') as f:
+            sort = EmailSortModel.objects.values('sort', 'clientquestion')
+            for a in sort:
+                text = [a['sort'], a['clientquestion']]
+                csv_writer = csv.writer(f)
+                for i in range(50):
+                    csv_writer.writerow(text)
+        return response.json(0)
 
-    def  get_document_classifier(self,request_dict, response):
-        # aws_key = "AKIA2E67UIMD45Y3HL53"  # 【你的 aws_access_key】
-        # aws_secret = "ckYLg4Lo9ZXJIcJEAKkzf2rWvs8Xth1FCjqiAqUw"  # 【你的 aws_secret_key】
-        # session = Session(aws_access_key_id=aws_key,
-        #                   aws_secret_access_key=aws_secret,
-        #                   region_name="us-east-1")  # 此处根据自己的 s3 地区位置改变
-        # client = session.client("asj-amazon-comprehend")
-        # client = boto3.client(
-        #     'asj-amazon-comprehend',
-        #     aws_access_key_id='AKIA2E67UIMD45Y3HL53',
-        #     aws_secret_access_key='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',
-        #     region_name='us-east-1'
-        # )
-        #client = boto3.client(service_name='comprehend',region_name='us-east-1',aws_access_key_id='AKIA2E67UIMD45Y3HL53',aws_secret_access_key='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')
-
-        # response = client.describe_document_classifier(
-        #     DocumentClassifierArn='arn:aws:comprehend:us-east-1:697864307463:document-classifier/txttwo'
-        # )
-        # print(response)
-        ec_qs =EmailConfigModel.objects.filter(emailtag=1) #获取总邮件
+    def upload_csv(self, request_dict, response):
+        file_path = os.path.join(os.path.dirname(__file__) + '/../emailtrainfile/emailtrain.csv')
+        bucket_name = "asj-amazon-comprehend"
+        upload_key = "location/emailtrain.csv"
+        with open(file_path, "rb") as f:
+            NeteaseMail().s3_login().upload_fileobj(f, bucket_name, Key=upload_key)
+        return response.json(0)
+
+    def create_document_classifier(self, request_dict, response):
+        try:
+            response1 = NeteaseMail().aws_login().create_document_classifier(
+                DocumentClassifierName='lhq',
+                DataAccessRoleArn='arn:aws:iam::697864307463:role/service-role/AmazonComprehendServiceRoleS3FullAccess-admin',
+                # Tags=[{'Key': 'string','Value': 'string'},],
+                InputDataConfig={
+                    'DataFormat': 'COMPREHEND_CSV',
+                    # | 'AUGMENTED_MANIFEST',
+                    'S3Uri': 's3://asj-amazon-comprehend/location/emailtrain.csv',
+                    # 'LabelDelimiter': 'string',
+                    # 'AugmentedManifests': [
+                    #     {
+                    #         'S3Uri': 'string',
+                    #         'AttributeNames': ['string', ]
+                    #     },
+                    # ]
+                },
+                OutputDataConfig={
+                    'S3Uri': 's3://asj-amazon-comprehend/output/lhq/'},
+                # 'KmsKeyId': 'string'},
+                # ClientRequestToken='string',
+                LanguageCode='en',
+                # | 'es' | 'fr' | 'de' | 'it' | 'pt' | 'ar'
+                # | 'hi' | 'ja' | 'ko' | 'zh' | 'zh-TW',
+                # VolumeKmsKeyId='string',
+                # VpcConfig={
+                #     'SecurityGroupIds': ['string', ],
+                #     'Subnets': ['string', ]
+                # },
+                Mode='MULTI_CLASS'  # 'MULTI_LABEL'
+            )
+        except Exception as e:
+            return response.json(404, repr('模型正在训练或已存在'))
+        else:
+            print(response1)
+            return response.json(0)
+
+    def create_endpoint(self, request_dict, response):
+        try:
+            response1 = NeteaseMail().aws_login().create_endpoint(
+                EndpointName='lhq',
+                ModelArn='arn:aws:comprehend:us-east-1:697864307463:document-classifier/lhq',
+                # Document classifier arn
+                DesiredInferenceUnits=1,
+                # ClientRequestToken='string',
+                # Tags=[{'Key': 'string','Value': 'string'},]
+            )
+        except Exception as e:
+            return response.json(404, repr('模型正在训练或不存在,请等待模型训练完再创建端点'))
+        else:
+            print(response1)
+            return response.json(0)
+
+    def describe_document_classifier(self, request_dict, response):
+        try:
+            # classifier_name = request_dict.get('classifier_name', None)
+            a = NeteaseMail().aws_arn()[0]
+            # classifier_arn = a + str(classifier_name)
+            classifier_arn = a + 'lhq'
+            response1 = NeteaseMail().aws_login().describe_document_classifier(
+                DocumentClassifierArn=classifier_arn
+            )
+            a1 = {"Status": response1['DocumentClassifierProperties']['Status']}
+        except Exception as e:
+            return response.json(404, repr('模型不存在'))
+        else:
+            return response.json(0, a1)
+
+    def describe_endpoint(self, request_dict, response):
+        try:
+            # endpoint_name = request_dict.get('endpoint_name', None)
+            a = NeteaseMail().aws_arn()[1]
+            # endpoint_arn = a + str(endpoint_name)
+            endpoint_arn = a + 'lhq'
+            response1 = NeteaseMail().aws_login().describe_endpoint(
+                EndpointArn=endpoint_arn
+            )
+            a1 = {"Status": response1['EndpointProperties']['Status']}
+        except Exception as e:
+            return response.json(404, repr('端点不存在'))
+        else:
+            return response.json(0, a1)
+
+    def delete_endpoint(self, request_dict, response):
+        try:
+            # endpoint_name = request_dict.get('endpoint_name', None)
+            a = NeteaseMail().aws_arn()[1]
+            # endpoint_arn = a + str(endpoint_name)
+            endpoint_arn = a + 'lhq'
+            response1 = NeteaseMail().aws_login().delete_endpoint(
+                EndpointArn=endpoint_arn)
+        except Exception as e:
+            return response.json(404, repr('端点不存在或正在删除中'))
+        else:
+            return response.json(0)
+
+    def delete_document_classifier(self, request_dict, response):
+        try:
+            # classifier_name = request_dict.get('classifier_name', None)
+            a = NeteaseMail().aws_arn()[0]
+            # classifier_arn = a + str(classifier_name)
+            classifier_arn = a + 'lhq'
+            response1 = NeteaseMail().aws_login().delete_document_classifier(
+                DocumentClassifierArn=classifier_arn)
+        except Exception as e:
+            return response.json(404, repr('模型不存在或正在删除中'))
+        else:
+            return response.json(0)
 
+    def get_document_classifier(self, request_dict, response):
+        ec_qs = EmailConfigModel.objects.filter(emailtag=1)  # 获取总邮件
+        emailsum = 0
+        replyemailsum = 0
         for ec in ec_qs:
             email_server = NeteaseMail().loginEmail(ec.emailserver, ec.fromaddr, ec.password, ec.emailserverport)
-            subject_list, from_list, bodydata_list = NeteaseMail().getEmailContext(email_server)
-            print("标题:", subject_list)
-            print("发件人:", from_list)
-            print("邮件内容:", bodydata_list)
-            if subject_list == []:
-                print("邮箱内无邮件")
+            subject_list, from_list, bodydata_list, uid_list, results, email_body, fujian_list, image_list = NeteaseMail().getEmailContext(
+                email_server)
+            emailsum += len(results)
+            print("标题:", len(subject_list), subject_list)
+            print("发件人:", len(from_list), from_list)
+            print("邮件内容:", len(bodydata_list), bodydata_list)
+            print("邮件uid:", len(uid_list), uid_list)
+            print("附件判断:", len(fujian_list), fujian_list)
+            print('图片数量:', len(image_list), image_list)
+            if not bodydata_list:
+                print("邮箱内无未读邮件")
             else:
-                print('成功拿到邮箱数据')
-            # NeteaseMail().closeEmail(email_server)
+                print('成功拿到邮件数据')
+            for i, v in enumerate(subject_list):
+                print('-------------------------------------------------------------------------')
+                print("邮件标题:", subject_list[i])
+                if not bodydata_list[i] or not subject_list[i]:
+                    print("邮件无正文或无标题,不进行回复")
+                    continue
 
-            for i ,v in enumerate(subject_list):
+                if fujian_list[i] == 'have':
+                    reply_model = bodydata_list[i]
+                    image = image_list
+                    shoujianren = 'liehaoquan2021@163.com'
+                    fajianren = from_list[i].split()[1]
+                    NeteaseMail().sentemail(None, uid_list[i],reply_model, image, subject_list[i], fajianren, shoujianren,
+                                            ec.fromaddr, ec.password)
+                    file_path = os.path.join(os.path.dirname(__file__) + '/../emailtrainfile/image/')
+                    shutil.rmtree(file_path)
+                    os.mkdir(file_path)
+                    print('邮件含有图片或附件,已转发到zendesk')
+                    email_server.set_flags(uid_list[i], b'\\Seen', silent=False)
+                    continue
 
-                client = boto3.client(service_name='comprehend', region_name='us-east-1',
-                                      aws_access_key_id='AKIA2E67UIMD45Y3HL53',
-                                      aws_secret_access_key='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')
-                response1 = client.classify_document(
-                    Text=bodydata_list[i],
-                    EndpointArn='arn:aws:comprehend:us-east-1:697864307463:document-classifier-endpoint/test'
+                response1 = NeteaseMail().aws_login().classify_document(
+                    Text=bodydata_list[i].split('\n\n\n\n\n')[0],
+                    EndpointArn='arn:aws:comprehend:us-east-1:697864307463:document-classifier-endpoint/lhq'
+                    # EndpointArn='arn:aws:comprehend:us-east-1:697864307463:document-classifier-endpoint/test'
                 )
-                #print(response.index(max(response['Classes']['Score'])))
+                # print(response.index(max(response['Classes']['Score'])))
                 nums = []
+                print('emailsort:')
                 for cls in response1['Classes']:
                     print(cls['Name'])
                     nums.append(cls['Score'])
+                print("识别种类及命中率:", response1['Classes'][nums.index(max(nums))])
+                if response1['Classes'][nums.index(max(nums))]['Score'] >= 0.95:
+                    reply_sort = EmailSortModel.objects.filter(
+                        sort=response1['Classes'][nums.index(max(nums))]['Name']).values('autoreplymodel')
+                    if reply_sort.exists():
+                        reply_model = reply_sort[0]['autoreplymodel'] + '\n' + '\n' + '\n' + '\n' + '\n' + '\n' + \
+                                      'At' + email_body[i]['Date'] + from_list[i].split()[0] + \
+                                      from_list[i].split()[1] + \
+                                      'wrote:\n ' + bodydata_list[i]
+                        print(reply_model)
+                        shoujianren = from_list[i].split()[1].replace('<', '').replace('>', '')
+                        a = NeteaseMail().sentemail(None, uid_list[i], reply_model, None, subject_list[i], ec.fromaddr, shoujianren,
+                                                    ec.fromaddr, ec.password)
+                        email_server.set_flags(uid_list[i], b'\\Seen', silent=False)
+                        if a == 'fail':
+                            print("此邮件被判定为垃圾邮件,不进行回复")
+                            email_server.remove_flags(uid_list[i], b'\\Seen', silent=False)
+                        else:
+                            replyemailsum += a
+                    else:
+                        print("无此转发分类,不进行回复")
+                else:
+                    reply_model = bodydata_list[i]
+                    shoujianren = 'liehaoquan2021@163.com'
+                    fajianren = from_list[i].split()[1]
+                    NeteaseMail().sentemail(reply_model, None, subject_list[i], fajianren, shoujianren,
+                                            ec.fromaddr, ec.password)
+                    email_server.set_flags(uid_list[i], b'\\Seen', silent=False)
+                    print("命中率低于0.95,已转发到zendesk")
+                # es_qs = EmailSortModel.objects.filter(sort=response1['Classes'][nums.index(max(nums))]['Name'])
+                # if es_qs.exists():
+                #     uemail_qs = EmailConfigModel.objects.filter(userid=es_qs[0]['userid'], langconfig__langcode='en')
+                #     if uemail_qs.exists():
+                #         for uem in uemail_qs:
+                #             NeteaseMail().sentemail(bodydata_list[i], subject_list[i], from_list[i], uem.fromaddr, ec.fromaddr, ec.password)
+            NeteaseMail().closeEmail(email_server)
+        emaildict = {
+            "邮箱内获取到未读邮件数": emailsum,
+            "已自动回复的邮件数": replyemailsum
+        }
+        return response.json(0, emaildict)
+
+    def email(self, request_dict, response):
+        from imapclient import IMAPClient
+        import email
+        import time
+        import email.parser
+        from nntplib import decode_header
+        from email.header import Header
+        import chardet
+
+        ec_qs = EmailConfigModel.objects.filter(emailtag=1)  # 获取总邮件
+        for ec in ec_qs:
+            global a, email_server
+
+            #邮件登录
+            try:
+                email_server = IMAPClient(ec.emailserver, ssl=True, port=ec.emailserverport)
+                # email_server = imaplib.IMAP4_SSL(IMAP_SERVER, 993)  # 网易企业邮箱服务器及SSL端口
+                print("imap4 服务器连接成功")
+                email_server.login(ec.fromaddr, ec.password)
+                email_server.id_({"name": "IMAPClient", "version": "2.1.0"})
+                # email_server.login(FROM_ADDR, PASSWORD)
+                print("imap4 (%s)账号密码正确,登录成功" % ec.fromaddr)
+            except:
+                print("imap4 服务器连接失败")
+
+            email_server.select_folder('INBOX')
+            results = email_server.search('UNSEEN')  # 读取未读邮件
+            print("邮箱内获取到未读邮件:", len(results))
+            subject_list = []
+            from_list = []
+            uid_list = []
+            email_body = []
+            fujian_list = []
+            image_list = []
+            plain_list = []
+            html_list = []
+            a = 0
+
+            # 对每一封邮件进行内容解析
+            for uid in results:
+                msgdict = email_server.fetch(uid, ['Body[]', 'ENVELOPE'], '(RFC822)')
+                mailbody = msgdict[uid][b'BODY[]']
+                envelope = msgdict[uid][b'ENVELOPE']
+                message = email.message_from_bytes(mailbody)
+                text = message.as_string()
+                body = email.parser.Parser().parsestr(text)
+
+                nowtime = time.asctime(time.localtime(time.time()))
+                nowmonth = nowtime.split()[1]
+                nowday = nowtime.split()[2]
+                emailmonth = body['Date'].split()[2]
+                emailday = body['Date'].split()[1]
+                print('email',emailmonth,emailday)
+                print('now', nowmonth, nowday)
+                # if emailmonth != nowmonth or emailday != nowday:
+                #     email_server.remove_flags(uid, b'\\Seen', silent=False)
+                #     continue
+
+                email_body.append(body)
+                subject_list.append(decode_header(body['Subject']))
+                from_list.append(decode_header(body['from']))
+                uid_list.append(uid)
+                print("标题:",  subject_list)
+
+                attlist = {}
+                try:
+                    for part in body.walk():
+                        if not part.is_multipart():
+                            file = part.get_filename()  # 附件名
+                            if file:
+                                a = 1
+                                filename = email.header.decode_header(file)[0][0]  # 附件名
+                                charset = email.header.decode_header(file)[0][1]  # 编码
+                                if part.get_all("Content-ID"):
+                                    content_id = part.get_all("Content-ID")[0][1:-1]
+                                else:
+                                    content_id = ""  # 附件ID,也就是邮件源码里面的cid
+                                ''' 多个附件时将附件名和ID对应保存到dict里面,后面将正文中的cid替换为本地保存路径 '''
+                                attlist[content_id] = filename
+                                ''' 附件文件名为中文或有编码的时候要进行转码 '''
+                                if str(charset) != "None":
+                                    filename = filename.decode(charset)
+                                filedata = part.get_payload(decode=True)  # 附件内容
+                                ''' 把附件写到文件里面,附件一定要用wb打开,二进制 '''
+                                file_path = os.path.join(os.path.dirname(__file__) + '/../emailtrainfile/image/')
+                                image_list.append(file_path + filename)
+                                with open(file_path + filename, "wb") as fw:
+                                    fw.write(filedata)
+                                    fw.close()
+
+                            elif part.get_content_type() == 'text/plain':
+                                con3 = part.get_payload(decode=True).strip()
+                                print('plain:', chardet.detect(con3))
+                                if chardet.detect(con3)['encoding'] == 'utf-8':
+                                    plain_list.append(con3.decode('utf-8'))
+                                    continue
+                                # if chardet.detect(con3)['encoding'] == 'ISO-8859-1':
+                                #     plain_list.append(con3.decode('ISO-8859-1')) # .decode('gbk').encode('utf8')
+                                #     continue
+                                else:
+                                    plain_list.append(con3.decode('gbk'))
+                                    continue
+                            elif part.get_content_type() == 'text/html':
+                                con3 = part.get_payload(decode=True).strip()
+                                print('html', chardet.detect(con3))
+                                if chardet.detect(con3)['encoding'] == 'utf-8':
+                                    html_list.append(con3.decode('utf-8'))
+                                    continue
+                                # if chardet.detect(con3)['encoding'] == 'ISO-8859-1':
+                                #     html_list.append(con3.decode('ISO-8859-1'))
+                                #     continue
+                                else:
+                                    html_list.append(con3.decode('gbk'))
+                                    continue
+                except Exception as e:
+                    print(e)
+                    print('获取邮件内容失败')
+                    email_server.remove_flags(uid, b'\\Seen', silent=False)
+                    subject_list.clear()
+                    from_list.clear()
+                    uid_list.clear()
+                    email_body.clear()
+                    fujian_list.clear()
+                    image_list.clear()
+                    plain_list.clear()
+                    html_list.clear()
+                    print('-------------------------------------------------------------------------')
+                    continue
+
+
+                if a == 1:
+                    fujian_list.append('have')
+                    a = 0
+                else:
+                    fujian_list.append('none')
+                email_server.remove_flags(uid, b'\\Seen', silent=False)
+                print("发件人:", from_list)
+                print("邮件内容:")
+                print("plain形式:",plain_list)
+                print("html形式:",html_list)
+                print("邮件uid:", uid_list)
+                print("邮件是否含有图片或附件:", fujian_list)
+                print('图片或附件名字:', image_list)
+                if not html_list and not plain_list:
+                    print("邮箱内无未读邮件")
+                else:
+                    print('成功拿到邮件数据')
+
+                # 对邮件类型进行判断处理
+                for i, v in enumerate(uid_list):
+                    print("邮件标题:", subject_list[i])
+                    if html_list and not plain_list:
+                        print('此邮件仅含有html')
+                        reply_model = html_list[i]
+                        fajianren = from_list[i]
+                        shoujianren = 'liehaoquan2021@163.com'  # 写zendesk邮箱
+                        NeteaseMail().sentemail(email_server, uid_list[i],reply_model, None, subject_list[i], fajianren, shoujianren,
+                                                ec.fromaddr, ec.password)
+                        print('-------------------------------------------------------------------------')
+                        break
+
+                    if plain_list[i] == '':
+                        print('此邮件无正文')
+                        reply_model = ''
+                        fajianren = from_list[i]
+                        shoujianren = 'liehaoquan2021@163.com'  # 写zendesk邮箱
+                        NeteaseMail().sentemail(email_server, uid_list[i],reply_model, None, subject_list[i], fajianren, shoujianren,
+                                                ec.fromaddr, ec.password)
+                        print('-------------------------------------------------------------------------')
+                        break
+
+                    if not subject_list[i]:
+                        print('此邮件无主题')
+                        if html_list and not plain_list:
+                            print('此邮件无主题且仅含有html')
+                            reply_model = html_list[i]
+                            fajianren = from_list[i]
+                            shoujianren = 'liehaoquan2021@163.com'  # 写zendesk邮箱
+                            biaoti = '(无主题)'
+                            NeteaseMail().sentemail(email_server, uid_list[i],reply_model, None, biaoti, fajianren, shoujianren,
+                                                    ec.fromaddr, ec.password)
+                            print('-------------------------------------------------------------------------')
+                            break
+                        elif plain_list:
+                            print('此邮件无主题且含有正文')
+                            reply_model = plain_list[i]
+                            fajianren = from_list[i]
+                            shoujianren = 'liehaoquan2021@163.com'  # 写zendesk邮箱
+                            biaoti = '(无主题)'
+                            NeteaseMail().sentemail(email_server, uid_list[i], reply_model, None, biaoti, fajianren, shoujianren,
+                                                    ec.fromaddr, ec.password)
+                        print('-------------------------------------------------------------------------')
+                        break
+
+                    # 处理含有图片或附件的邮件
+                    if fujian_list[i] == 'have':
+                        print('此邮件含有图片或附件或视频或压缩包')
+                        reply_model = html_list[i]
+                        image = image_list
+                        fajianren = from_list[i]
+                        shoujianren = 'liehaoquan2021@163.com'  # 写zendesk邮箱
+                        NeteaseMail().sentemail(email_server, uid_list[i], reply_model, image, subject_list[i], fajianren, shoujianren,
+                                                ec.fromaddr, ec.password)
+                        file_path = os.path.join(os.path.dirname(__file__) + '/../emailtrainfile/image/')
+                        shutil.rmtree(file_path)
+                        os.mkdir(file_path)
+                        print('-------------------------------------------------------------------------')
+                        break
 
-                print(response1['Classes'][nums.index(max(nums))])
+                    if fujian_list[i] == 'none':
+                        # 处理无图片或附件的邮件
+                        # 进行种类判断
+                        print("识别内容:", plain_list[i].split('\n\n')[0])  # plain
+                        if len(plain_list[i].split('\n\n\n')[0]) < 1000:
+                            response1 = NeteaseMail().aws_login().classify_document(
+                                Text=plain_list[i].split('\n\n\n')[0],
+                                EndpointArn='arn:aws:comprehend:us-east-1:697864307463:document-classifier-endpoint/lhq'
+                                # EndpointArn='arn:aws:comprehend:us-east-1:697864307463:document-classifier-endpoint/test'
+                            )
+                            # print(response.index(max(response['Classes']['Score'])))
+                            nums = []
+                            print('emailsort:')
+                            for cls in response1['Classes']:
+                                print(cls['Name'])
+                                nums.append(cls['Score'])
+                            print("识别种类及命中率:", response1['Classes'][nums.index(max(nums))])
+                            # 命中率高于0.95时
+                            if response1['Classes'][nums.index(max(nums))]['Score'] >= 0.95:
+                                reply_sort = EmailSortModel.objects.filter(
+                                    sort=response1['Classes'][nums.index(max(nums))]['Name']).values('autoreplymodel')
+                                if reply_sort.exists():
+                                    reply_model = reply_sort[0]['autoreplymodel'] + '\n' + '\n' + '\n' + '\n' + '\n' + '\n' + \
+                                                  'At' + email_body[i]['Date'] + str(from_list[i].split()[0:-1]) + \
+                                                  from_list[i].split()[-1] + \
+                                                  'wrote:\n ' + plain_list[i]
+                                    print(reply_model)
+                                    shoujianren = from_list[i].split()[1].replace('<', '').replace('>', '')
+                                    NeteaseMail().sentemail(email_server, uid_list[i], reply_model, None, subject_list[i], ec.fromaddr, shoujianren,
+                                                            ec.fromaddr, ec.password)
+                                    print('-------------------------------------------------------------------------')
+                                    break
+                            else:
+                                print("此邮件命中率低于0.95")
+                                reply_model = html_list[i]  # html
+                                fajianren = from_list[i]
+                                print(fujian_list)
+                                shoujianren = 'liehaoquan2021@163.com'  # 写zendesk邮箱
+                                NeteaseMail().sentemail(email_server, uid_list[i], reply_model, None, subject_list[i],
+                                                        fajianren, shoujianren,
+                                                        ec.fromaddr, ec.password)
+                                print('-------------------------------------------------------------------------')
+                                break
 
-                es_qs = EmailSortModel.objects.filter(sort=response1['Classes'][nums.index(max(nums))]['Name'])
-                if es_qs.exists():
-                    uemail_qs = EmailConfigModel.objects.filter(userid=es_qs[0]['userid'], langconfig__langcode='en')
-                    if uemail_qs.exists():
-                        for uem in uemail_qs:
-                            NeteaseMail().sentemail(bodydata_list[i], subject_list[i], from_list[i], uem.fromaddr, ec.fromaddr, ec.password)
+                        else:
+                            print("识别内容过长")
+                            reply_model = html_list[i]  # html
+                            fajianren = from_list[i]
+                            print(fujian_list)
+                            shoujianren = 'liehaoquan2021@163.com'  # 写zendesk邮箱
+                            NeteaseMail().sentemail(email_server, uid_list[i], reply_model, None, subject_list[i], fajianren, shoujianren,
+                                                    ec.fromaddr, ec.password)
+                            print('-------------------------------------------------------------------------')
+                            break
+                subject_list.clear()
+                from_list.clear()
+                uid_list.clear()
+                email_body.clear()
+                fujian_list.clear()
+                image_list.clear()
+                plain_list.clear()
+                html_list.clear()
             NeteaseMail().closeEmail(email_server)
         return response.json(0)
-        #print(response)
 
 # if __name__ == '__main__':
 #     ComprehendAction().get_document_classifier()

+ 200 - 0
emailtrainfile/emailtrain.csv

@@ -0,0 +1,200 @@
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+testsort,testquestion
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+NVR system abnormal,What if your NVR system keeps beeping?
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,"Hello, my IPC can't receive the sound"
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter
+IPC cannot receive sound,My IPC device doesn't sound. What's the matter

+ 1 - 0
model/models.py

@@ -272,6 +272,7 @@ class EmailLangConfig(models.Model):
 class EmailSortModel(models.Model):
     emailsortid = models.AutoField(primary_key=True, verbose_name=u'自增ID')
     sort = models.CharField(max_length=200, default='', verbose_name='负责分类')
+    clientquestion = models.CharField(max_length=200, default='', verbose_name='客户问题内容')
     sortcode = models.CharField(max_length=200, default='', verbose_name='分类编号')
     parentsortid = models.CharField(max_length=200, null=True, verbose_name='父节点分类')
     isautoreply = models.SmallIntegerField(default=0, verbose_name='是否自动回复')  # 0:不自动回复 1:自动回复

+ 62 - 0
readme.md

@@ -0,0 +1,62 @@
+# 总项目文件名:langer  
+
+## 项目目录
+1. 智能客服邮件  
+2. 项目2  
+3. 项目3  
+
+### 1.智能客服邮件
+- 项目负责人:列浩铨  
+- 项目日期:2021年2月26日
+
+#### 项目介绍,实际应用及意义
+- 介绍:  
+智能客服邮件是一个基于python语言开发的项目,它是一个类似脚本项目,用于协助客服工作。
+- 实际应用:  
+如今客服以邮件形式处理客户售前售后问题居多,此项目能协助客服工作,对客服从客户接收到的邮件里的一些简单问题进行自动回复。    
+- 意义:  
+减轻客服工作量,提高客服工作效率。
+
+#### 项目具体功能
+1. 获取和解析网易邮箱内邮件的内容,进行转发。  
+2. 对接aws的comprehend的SDK的相关接口,S3存储桶的SDK的相关接口,对训练标签进行存储,对邮件内容进行自然语言分析。
+
+#### 项目运行环境
+- django 2.1 
+- python 3.7  
+
+#### 如何运行及调试  
+本地环境运行在终端输入如下命令:  
+python manage.py runserver 0.0.0.0:8000  
+
+调试:  
+postman软件  
+
+#### 项目相关文件  
+├── controller  
+│ 	├── ComprehendController.py		// comprehend,sdk相关接口,获取,解析,转发邮件功能接口  
+│	├── EmaillangController.py		// 语言配置增删改查接口  
+│ 	├── EmailProjectController.py   // 邮箱项目配置表增删改查接口  
+│ 	├── EmailSortController.py		// 邮箱分类配置表增删改查接口  
+│ 	├── EmailUserController.py		// 邮箱配置表增删改查接口  
+├── emailtrainfile  
+│ 	├── image						// 存放邮件获取的相关附件  
+│ 	├── emailtrain.csv				// 训练标签表  
+├── Utils  
+│ 	├── NeteaseMail.py				// 类  
+
+核心接口或函数:
+- ComprehendController.py下的email接口
+- NeteaseMail.py下的sentmail函数
+
+#### 项目存在问题
+1. 项目前期需求分析不明确,缺少与客服的沟通。  
+2. 转发功能并未完善,存在邮件内容类型问题,内容编码问题。
+
+### 项目2  
+
+### 项目3  
+ 
+
+
+