mirror of
https://gitee.com/dify_ai/dify.git
synced 2024-12-02 03:07:59 +08:00
feat: add builtin tools for send email (#10493)
This commit is contained in:
parent
0867821ae7
commit
9c7edb9242
1
api/core/tools/provider/builtin/email/_assets/icon.svg
Normal file
1
api/core/tools/provider/builtin/email/_assets/icon.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 11 KiB |
7
api/core/tools/provider/builtin/email/email.py
Normal file
7
api/core/tools/provider/builtin/email/email.py
Normal 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()
|
83
api/core/tools/provider/builtin/email/email.yaml
Normal file
83
api/core/tools/provider/builtin/email/email.yaml
Normal 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服务器加密方式
|
53
api/core/tools/provider/builtin/email/tools/send.py
Normal file
53
api/core/tools/provider/builtin/email/tools/send.py
Normal 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
|
66
api/core/tools/provider/builtin/email/tools/send_mail.py
Normal file
66
api/core/tools/provider/builtin/email/tools/send_mail.py
Normal 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")
|
46
api/core/tools/provider/builtin/email/tools/send_mail.yaml
Normal file
46
api/core/tools/provider/builtin/email/tools/send_mail.yaml
Normal 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
|
@ -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
|
Loading…
Reference in New Issue
Block a user