feat: add builtin tools for send email (#10493)

This commit is contained in:
wakaka6 2024-11-12 21:48:36 +08:00 committed by GitHub
parent 0867821ae7
commit 9c7edb9242
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 377 additions and 0 deletions

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -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()

View File

@ -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服务器加密方式

View File

@ -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

View File

@ -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")

View File

@ -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

View File

@ -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))

View File

@ -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