| @@ -0,0 +1,7 @@ | |||
| from core.tools.provider.builtin.email.tools.send_mail import SendMailTool | |||
| from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController | |||
| class SmtpProvider(BuiltinToolProviderController): | |||
| def _validate_credentials(self, credentials: dict) -> None: | |||
| SendMailTool() | |||
| @@ -0,0 +1,83 @@ | |||
| identity: | |||
| author: wakaka6 | |||
| name: email | |||
| label: | |||
| en_US: email | |||
| zh_Hans: 电子邮件 | |||
| description: | |||
| en_US: send email through smtp protocol | |||
| zh_Hans: 通过smtp协议发送电子邮件 | |||
| icon: icon.svg | |||
| tags: | |||
| - utilities | |||
| credentials_for_provider: | |||
| email_account: | |||
| type: text-input | |||
| required: true | |||
| label: | |||
| en_US: email account | |||
| zh_Hans: 邮件账号 | |||
| placeholder: | |||
| en_US: input you email account | |||
| zh_Hans: 输入你的邮箱账号 | |||
| help: | |||
| en_US: email account | |||
| zh_Hans: 邮件账号 | |||
| email_password: | |||
| type: secret-input | |||
| required: true | |||
| label: | |||
| en_US: email password | |||
| zh_Hans: 邮件密码 | |||
| placeholder: | |||
| en_US: email password | |||
| zh_Hans: 邮件密码 | |||
| help: | |||
| en_US: email password | |||
| zh_Hans: 邮件密码 | |||
| smtp_server: | |||
| type: text-input | |||
| required: true | |||
| label: | |||
| en_US: smtp server | |||
| zh_Hans: 发信smtp服务器地址 | |||
| placeholder: | |||
| en_US: smtp server | |||
| zh_Hans: 发信smtp服务器地址 | |||
| help: | |||
| en_US: smtp server | |||
| zh_Hans: 发信smtp服务器地址 | |||
| smtp_port: | |||
| type: text-input | |||
| required: true | |||
| label: | |||
| en_US: smtp server port | |||
| zh_Hans: 发信smtp服务器端口 | |||
| placeholder: | |||
| en_US: smtp server port | |||
| zh_Hans: 发信smtp服务器端口 | |||
| help: | |||
| en_US: smtp server port | |||
| zh_Hans: 发信smtp服务器端口 | |||
| encrypt_method: | |||
| type: select | |||
| required: true | |||
| options: | |||
| - value: NONE | |||
| label: | |||
| en_US: NONE | |||
| zh_Hans: 无加密 | |||
| - value: SSL | |||
| label: | |||
| en_US: SSL | |||
| zh_Hans: SSL加密 | |||
| - value: TLS | |||
| label: | |||
| en_US: START TLS | |||
| zh_Hans: START TLS加密 | |||
| label: | |||
| en_US: encrypt method | |||
| zh_Hans: 加密方式 | |||
| help: | |||
| en_US: smtp server encrypt method | |||
| zh_Hans: 发信smtp服务器加密方式 | |||
| @@ -0,0 +1,53 @@ | |||
| import logging | |||
| import smtplib | |||
| import ssl | |||
| from email.mime.multipart import MIMEMultipart | |||
| from email.mime.text import MIMEText | |||
| from pydantic import BaseModel | |||
| class SendEmailToolParameters(BaseModel): | |||
| smtp_server: str | |||
| smtp_port: int | |||
| email_account: str | |||
| email_password: str | |||
| sender_to: str | |||
| subject: str | |||
| email_content: str | |||
| encrypt_method: str | |||
| def send_mail(parmas: SendEmailToolParameters): | |||
| timeout = 60 | |||
| msg = MIMEMultipart("alternative") | |||
| msg["From"] = parmas.email_account | |||
| msg["To"] = parmas.sender_to | |||
| msg["Subject"] = parmas.subject | |||
| msg.attach(MIMEText(parmas.email_content, "plain")) | |||
| msg.attach(MIMEText(parmas.email_content, "html")) | |||
| ctx = ssl.create_default_context() | |||
| if parmas.encrypt_method.upper() == "SSL": | |||
| try: | |||
| with smtplib.SMTP_SSL(parmas.smtp_server, parmas.smtp_port, context=ctx, timeout=timeout) as server: | |||
| server.login(parmas.email_account, parmas.email_password) | |||
| server.sendmail(parmas.email_account, parmas.sender_to, msg.as_string()) | |||
| return True | |||
| except Exception as e: | |||
| logging.exception("send email failed: %s", e) | |||
| return False | |||
| else: # NONE or TLS | |||
| try: | |||
| with smtplib.SMTP(parmas.smtp_server, parmas.smtp_port, timeout=timeout) as server: | |||
| if parmas.encrypt_method.upper() == "TLS": | |||
| server.starttls(context=ctx) | |||
| server.login(parmas.email_account, parmas.email_password) | |||
| server.sendmail(parmas.email_account, parmas.sender_to, msg.as_string()) | |||
| return True | |||
| except Exception as e: | |||
| logging.exception("send email failed: %s", e) | |||
| return False | |||
| @@ -0,0 +1,66 @@ | |||
| import re | |||
| from typing import Any, Union | |||
| from core.tools.entities.tool_entities import ToolInvokeMessage | |||
| from core.tools.provider.builtin.email.tools.send import ( | |||
| SendEmailToolParameters, | |||
| send_mail, | |||
| ) | |||
| from core.tools.tool.builtin_tool import BuiltinTool | |||
| class SendMailTool(BuiltinTool): | |||
| def _invoke( | |||
| self, user_id: str, tool_parameters: dict[str, Any] | |||
| ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: | |||
| """ | |||
| invoke tools | |||
| """ | |||
| sender = self.runtime.credentials.get("email_account", "") | |||
| email_rgx = re.compile(r"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$") | |||
| password = self.runtime.credentials.get("email_password", "") | |||
| smtp_server = self.runtime.credentials.get("smtp_server", "") | |||
| if not smtp_server: | |||
| return self.create_text_message("please input smtp server") | |||
| smtp_port = self.runtime.credentials.get("smtp_port", "") | |||
| try: | |||
| smtp_port = int(smtp_port) | |||
| except ValueError: | |||
| return self.create_text_message("Invalid parameter smtp_port(should be int)") | |||
| if not sender: | |||
| return self.create_text_message("please input sender") | |||
| if not email_rgx.match(sender): | |||
| return self.create_text_message("Invalid parameter userid, the sender is not a mailbox") | |||
| receiver_email = tool_parameters["send_to"] | |||
| if not receiver_email: | |||
| return self.create_text_message("please input receiver email") | |||
| if not email_rgx.match(receiver_email): | |||
| return self.create_text_message("Invalid parameter receiver email, the receiver email is not a mailbox") | |||
| email_content = tool_parameters.get("email_content", "") | |||
| if not email_content: | |||
| return self.create_text_message("please input email content") | |||
| subject = tool_parameters.get("subject", "") | |||
| if not subject: | |||
| return self.create_text_message("please input email subject") | |||
| encrypt_method = self.runtime.credentials.get("encrypt_method", "") | |||
| if not encrypt_method: | |||
| return self.create_text_message("please input encrypt method") | |||
| send_email_params = SendEmailToolParameters( | |||
| smtp_server=smtp_server, | |||
| smtp_port=smtp_port, | |||
| email_account=sender, | |||
| email_password=password, | |||
| sender_to=receiver_email, | |||
| subject=subject, | |||
| email_content=email_content, | |||
| encrypt_method=encrypt_method, | |||
| ) | |||
| if send_mail(send_email_params): | |||
| return self.create_text_message("send email success") | |||
| return self.create_text_message("send email failed") | |||
| @@ -0,0 +1,46 @@ | |||
| identity: | |||
| name: send_mail | |||
| author: wakaka6 | |||
| label: | |||
| en_US: send email | |||
| zh_Hans: 发送邮件 | |||
| icon: icon.svg | |||
| description: | |||
| human: | |||
| en_US: A tool for sending email | |||
| zh_Hans: 用于发送邮件 | |||
| llm: A tool for sending email | |||
| parameters: | |||
| - name: send_to | |||
| type: string | |||
| required: true | |||
| label: | |||
| en_US: Recipient email account | |||
| zh_Hans: 收件人邮箱账号 | |||
| human_description: | |||
| en_US: Recipient email account | |||
| zh_Hans: 收件人邮箱账号 | |||
| llm_description: Recipient email account | |||
| form: llm | |||
| - name: subject | |||
| type: string | |||
| required: true | |||
| label: | |||
| en_US: email subject | |||
| zh_Hans: 邮件主题 | |||
| human_description: | |||
| en_US: email subject | |||
| zh_Hans: 邮件主题 | |||
| llm_description: email subject | |||
| form: llm | |||
| - name: email_content | |||
| type: string | |||
| required: true | |||
| label: | |||
| en_US: email content | |||
| zh_Hans: 邮件内容 | |||
| human_description: | |||
| en_US: email content | |||
| zh_Hans: 邮件内容 | |||
| llm_description: email content | |||
| form: llm | |||
| @@ -0,0 +1,75 @@ | |||
| import json | |||
| import re | |||
| from typing import Any, Union | |||
| from core.tools.entities.tool_entities import ToolInvokeMessage | |||
| from core.tools.provider.builtin.email.tools.send import ( | |||
| SendEmailToolParameters, | |||
| send_mail, | |||
| ) | |||
| from core.tools.tool.builtin_tool import BuiltinTool | |||
| class SendMailTool(BuiltinTool): | |||
| def _invoke( | |||
| self, user_id: str, tool_parameters: dict[str, Any] | |||
| ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: | |||
| """ | |||
| invoke tools | |||
| """ | |||
| sender = self.runtime.credentials.get("email_account", "") | |||
| email_rgx = re.compile(r"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$") | |||
| password = self.runtime.credentials.get("email_password", "") | |||
| smtp_server = self.runtime.credentials.get("smtp_server", "") | |||
| if not smtp_server: | |||
| return self.create_text_message("please input smtp server") | |||
| smtp_port = self.runtime.credentials.get("smtp_port", "") | |||
| try: | |||
| smtp_port = int(smtp_port) | |||
| except ValueError: | |||
| return self.create_text_message("Invalid parameter smtp_port(should be int)") | |||
| if not sender: | |||
| return self.create_text_message("please input sender") | |||
| if not email_rgx.match(sender): | |||
| return self.create_text_message("Invalid parameter userid, the sender is not a mailbox") | |||
| receivers_email = tool_parameters["send_to"] | |||
| if not receivers_email: | |||
| return self.create_text_message("please input receiver email") | |||
| receivers_email = json.loads(receivers_email) | |||
| for receiver in receivers_email: | |||
| if not email_rgx.match(receiver): | |||
| return self.create_text_message( | |||
| f"Invalid parameter receiver email, the receiver email({receiver}) is not a mailbox" | |||
| ) | |||
| email_content = tool_parameters.get("email_content", "") | |||
| if not email_content: | |||
| return self.create_text_message("please input email content") | |||
| subject = tool_parameters.get("subject", "") | |||
| if not subject: | |||
| return self.create_text_message("please input email subject") | |||
| encrypt_method = self.runtime.credentials.get("encrypt_method", "") | |||
| if not encrypt_method: | |||
| return self.create_text_message("please input encrypt method") | |||
| msg = {} | |||
| for receiver in receivers_email: | |||
| send_email_params = SendEmailToolParameters( | |||
| smtp_server=smtp_server, | |||
| smtp_port=smtp_port, | |||
| email_account=sender, | |||
| email_password=password, | |||
| sender_to=receiver, | |||
| subject=subject, | |||
| email_content=email_content, | |||
| encrypt_method=encrypt_method, | |||
| ) | |||
| if send_mail(send_email_params): | |||
| msg[receiver] = "send email success" | |||
| else: | |||
| msg[receiver] = "send email failed" | |||
| return self.create_text_message(json.dumps(msg)) | |||
| @@ -0,0 +1,46 @@ | |||
| identity: | |||
| name: send_mail_batch | |||
| author: wakaka6 | |||
| label: | |||
| en_US: send email to multiple recipients | |||
| zh_Hans: 发送邮件给多个收件人 | |||
| icon: icon.svg | |||
| description: | |||
| human: | |||
| en_US: A tool for sending email to multiple recipients | |||
| zh_Hans: 用于发送邮件给多个收件人的工具 | |||
| llm: A tool for sending email to multiple recipients | |||
| parameters: | |||
| - name: send_to | |||
| type: string | |||
| required: true | |||
| label: | |||
| en_US: Recipient email account(json list) | |||
| zh_Hans: 收件人邮箱账号(json list) | |||
| human_description: | |||
| en_US: Recipient email account | |||
| zh_Hans: 收件人邮箱账号 | |||
| llm_description: A list of recipient email account(json format) | |||
| form: llm | |||
| - name: subject | |||
| type: string | |||
| required: true | |||
| label: | |||
| en_US: email subject | |||
| zh_Hans: 邮件主题 | |||
| human_description: | |||
| en_US: email subject | |||
| zh_Hans: 邮件主题 | |||
| llm_description: email subject | |||
| form: llm | |||
| - name: email_content | |||
| type: string | |||
| required: true | |||
| label: | |||
| en_US: email content | |||
| zh_Hans: 邮件内容 | |||
| human_description: | |||
| en_US: email content | |||
| zh_Hans: 邮件内容 | |||
| llm_description: email content | |||
| form: llm | |||