Gmail API를 활용한 이메일 자동화 RPA 프로그램 Features: - Gmail API 인증 및 연동 - 키워드/발신자 기반 자동 분류 - 조건별 자동 답장 기능 - 통계 리포트 생성 - 커스터마이징 가능한 JSON 설정 Modules: - gmail_automation.py: 메인 프로그램 - gmail_auth.py: Gmail API 인증 - email_classifier.py: 이메일 분류 로직 - auto_reply.py: 자동 답장 로직 - config.json.example: 설정 예시 Documentation: - 상세한 README.md (설치, 사용법, 트러블슈팅) - Google Cloud Console 설정 가이드 - 실제 효과 측정 데이터
196 lines
5.4 KiB
Python
196 lines
5.4 KiB
Python
"""
|
|
자동 답장 모듈
|
|
"""
|
|
|
|
from datetime import datetime
|
|
import base64
|
|
from email.mime.text import MIMEText
|
|
|
|
|
|
class AutoReply:
|
|
"""자동 답장 클래스"""
|
|
|
|
def __init__(self, service, config):
|
|
"""
|
|
초기화
|
|
|
|
Args:
|
|
service: Gmail API 서비스
|
|
config: 자동 답장 규칙 설정
|
|
"""
|
|
self.service = service
|
|
self.rules = config.get('auto_reply_rules', [])
|
|
|
|
def should_reply(self, email_data):
|
|
"""
|
|
자동 답장 필요 여부 판단
|
|
|
|
Args:
|
|
email_data: 이메일 정보
|
|
|
|
Returns:
|
|
True/False
|
|
"""
|
|
# 현재 시간
|
|
current_hour = datetime.now().hour
|
|
|
|
for rule in self.rules:
|
|
condition = rule.get('condition', '')
|
|
|
|
# 업무 시간 외 체크
|
|
if condition == '업무 시간 외':
|
|
hours = rule.get('hours', {})
|
|
end_hour = hours.get('end', 9)
|
|
start_hour = hours.get('start', 18)
|
|
|
|
# 업무 시간 외인 경우
|
|
if current_hour >= start_hour or current_hour < end_hour:
|
|
return True
|
|
|
|
# 특정 키워드 포함 시
|
|
keywords = rule.get('keywords', [])
|
|
if keywords:
|
|
subject = email_data.get('subject', '').lower()
|
|
body = email_data.get('body', '').lower()
|
|
full_text = f"{subject} {body}"
|
|
|
|
if any(keyword.lower() in full_text for keyword in keywords):
|
|
return True
|
|
|
|
return False
|
|
|
|
def get_reply_template(self, email_data):
|
|
"""
|
|
답장 템플릿 가져오기
|
|
|
|
Args:
|
|
email_data: 이메일 정보
|
|
|
|
Returns:
|
|
답장 메시지 템플릿
|
|
"""
|
|
current_hour = datetime.now().hour
|
|
|
|
for rule in self.rules:
|
|
condition = rule.get('condition', '')
|
|
|
|
if condition == '업무 시간 외':
|
|
hours = rule.get('hours', {})
|
|
end_hour = hours.get('end', 9)
|
|
start_hour = hours.get('start', 18)
|
|
|
|
if current_hour >= start_hour or current_hour < end_hour:
|
|
return rule.get('template', '')
|
|
|
|
# 키워드 기반 템플릿
|
|
keywords = rule.get('keywords', [])
|
|
if keywords:
|
|
subject = email_data.get('subject', '').lower()
|
|
body = email_data.get('body', '').lower()
|
|
full_text = f"{subject} {body}"
|
|
|
|
if any(keyword.lower() in full_text for keyword in keywords):
|
|
return rule.get('template', '')
|
|
|
|
return None
|
|
|
|
def create_reply_message(self, to, subject, body, thread_id=None):
|
|
"""
|
|
답장 메시지 생성
|
|
|
|
Args:
|
|
to: 받는 사람
|
|
subject: 제목
|
|
body: 본문
|
|
thread_id: 스레드 ID (답장인 경우)
|
|
|
|
Returns:
|
|
Gmail API용 메시지 객체
|
|
"""
|
|
message = MIMEText(body, 'plain', 'utf-8')
|
|
message['to'] = to
|
|
message['subject'] = f"Re: {subject}" if not subject.startswith('Re:') else subject
|
|
|
|
raw_message = base64.urlsafe_b64encode(message.as_bytes()).decode('utf-8')
|
|
|
|
email_message = {'raw': raw_message}
|
|
|
|
if thread_id:
|
|
email_message['threadId'] = thread_id
|
|
|
|
return email_message
|
|
|
|
def send_reply(self, original_msg_id, email_data):
|
|
"""
|
|
자동 답장 전송
|
|
|
|
Args:
|
|
original_msg_id: 원본 메시지 ID
|
|
email_data: 이메일 정보
|
|
|
|
Returns:
|
|
성공 여부
|
|
"""
|
|
try:
|
|
# 답장 템플릿 가져오기
|
|
template = self.get_reply_template(email_data)
|
|
|
|
if not template:
|
|
return False
|
|
|
|
# 발신자 추출
|
|
sender = email_data.get('sender', '')
|
|
# 이메일 주소만 추출
|
|
import re
|
|
email_match = re.search(r'[\w\.-]+@[\w\.-]+', sender)
|
|
if not email_match:
|
|
return False
|
|
|
|
to_email = email_match.group(0)
|
|
subject = email_data.get('subject', '제목 없음')
|
|
|
|
# 원본 메시지에서 threadId 가져오기
|
|
original_message = self.service.users().messages().get(
|
|
userId='me',
|
|
id=original_msg_id,
|
|
format='metadata'
|
|
).execute()
|
|
|
|
thread_id = original_message.get('threadId')
|
|
|
|
# 답장 메시지 생성
|
|
reply_message = self.create_reply_message(
|
|
to=to_email,
|
|
subject=subject,
|
|
body=template,
|
|
thread_id=thread_id
|
|
)
|
|
|
|
# 메시지 전송
|
|
sent_message = self.service.users().messages().send(
|
|
userId='me',
|
|
body=reply_message
|
|
).execute()
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ 답장 전송 실패: {e}")
|
|
return False
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# 테스트
|
|
config = {
|
|
"auto_reply_rules": [
|
|
{
|
|
"condition": "업무 시간 외",
|
|
"hours": {"start": 18, "end": 9},
|
|
"template": "업무 시간 외 자동 답장입니다."
|
|
}
|
|
]
|
|
}
|
|
|
|
# 테스트는 실제 service 없이는 불가
|
|
print("AutoReply 모듈 로드 완료")
|