|
| 1 | +# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. ========= |
| 2 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 3 | +# you may not use this file except in compliance with the License. |
| 4 | +# You may obtain a copy of the License at |
| 5 | +# |
| 6 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 7 | +# |
| 8 | +# Unless required by applicable law or agreed to in writing, software |
| 9 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 10 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 11 | +# See the License for the specific language governing permissions and |
| 12 | +# limitations under the License. |
| 13 | +# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. ========= |
| 14 | + |
| 15 | +from typing import Dict, List, Optional, cast |
| 16 | + |
| 17 | +from camel.toolkits.base import BaseToolkit |
| 18 | +from camel.toolkits.function_tool import FunctionTool |
| 19 | +from camel.utils import MCPServer, api_keys_required |
| 20 | + |
| 21 | + |
| 22 | +@MCPServer() |
| 23 | +class ResendToolkit(BaseToolkit): |
| 24 | + r"""A toolkit for sending emails using the Resend API. |
| 25 | +
|
| 26 | + This toolkit provides functionality to send emails using Resend's |
| 27 | + Python SDK.It supports sending both HTML and plain text emails, |
| 28 | + with options for multiple recipients, CC, BCC, reply-to |
| 29 | + addresses, and custom headers. |
| 30 | +
|
| 31 | + Notes: |
| 32 | + To use this toolkit, you need to set the following environment |
| 33 | + variable: |
| 34 | + - RESEND_API_KEY: Your Resend API key. You can get one from |
| 35 | + https://resend.com/api-keys |
| 36 | +
|
| 37 | + Example: |
| 38 | + .. code-block:: python |
| 39 | +
|
| 40 | + from camel.toolkits import ResendToolkit |
| 41 | +
|
| 42 | + # Initialize the toolkit |
| 43 | + toolkit = ResendToolkit() |
| 44 | +
|
| 45 | + # Get tools |
| 46 | + tools = toolkit.get_tools() |
| 47 | + """ |
| 48 | + |
| 49 | + @api_keys_required([(None, "RESEND_API_KEY")]) |
| 50 | + def send_email( |
| 51 | + self, |
| 52 | + to: List[str], |
| 53 | + subject: str, |
| 54 | + from_email: str, |
| 55 | + html: Optional[str] = None, |
| 56 | + text: Optional[str] = None, |
| 57 | + cc: Optional[List[str]] = None, |
| 58 | + bcc: Optional[List[str]] = None, |
| 59 | + reply_to: Optional[str] = None, |
| 60 | + tags: Optional[List[Dict[str, str]]] = None, |
| 61 | + headers: Optional[Dict[str, str]] = None, |
| 62 | + ) -> str: |
| 63 | + r"""Send an email using the Resend API. |
| 64 | +
|
| 65 | + Args: |
| 66 | + to (List[str]): List of recipient email addresses. |
| 67 | + subject (str): The email subject line. |
| 68 | + from_email (str): The sender email address. Must be from a verified |
| 69 | + domain. |
| 70 | + html (Optional[str]): The HTML content of the email. Either html or |
| 71 | + text must be provided. (default: :obj:`None`) |
| 72 | + text (Optional[str]): The plain text content of the email. Either |
| 73 | + html or text must be provided. (default: :obj:`None`) |
| 74 | + cc (Optional[List[str]]): List of CC recipient email addresses. |
| 75 | + (default: :obj:`None`) |
| 76 | + bcc (Optional[List[str]]): List of BCC recipient email addresses. |
| 77 | + (default: :obj:`None`) |
| 78 | + reply_to (Optional[str]): The reply-to email address. |
| 79 | + (default: :obj:`None`) |
| 80 | + tags (Optional[List[Dict[str, str]]]): List of tags to attach to |
| 81 | + the email. Each tag should be a dict with 'name' and |
| 82 | + 'value' keys. (default: :obj:`None`) |
| 83 | + headers (Optional[Dict[str, str]]): Custom headers to include in |
| 84 | + the email.(default: :obj:`None`) |
| 85 | +
|
| 86 | + Returns: |
| 87 | + str: A success message with the email ID if sent successfully, |
| 88 | + or an error message if the send failed. |
| 89 | +
|
| 90 | + Raises: |
| 91 | + ValueError: If neither html nor text content is provided. |
| 92 | +
|
| 93 | + Example: |
| 94 | + .. code-block:: python |
| 95 | +
|
| 96 | + toolkit = ResendToolkit() |
| 97 | + result = toolkit.send_email( |
| 98 | + to=["recipient@example.com"], |
| 99 | + subject="Hello World", |
| 100 | + from_email="sender@yourdomain.com", |
| 101 | + html="<h1>Hello, World!</h1>", |
| 102 | + text="Hello, World!" |
| 103 | + ) |
| 104 | + """ |
| 105 | + import os |
| 106 | + |
| 107 | + if not html and not text: |
| 108 | + raise ValueError( |
| 109 | + "Either 'html' or 'text' content must be provided" |
| 110 | + ) |
| 111 | + |
| 112 | + try: |
| 113 | + import resend |
| 114 | + except ImportError: |
| 115 | + raise ImportError( |
| 116 | + "Please install the resend package first. " |
| 117 | + "You can install it by running `pip install resend`." |
| 118 | + ) |
| 119 | + |
| 120 | + # Set the API key |
| 121 | + resend.api_key = os.getenv("RESEND_API_KEY") |
| 122 | + |
| 123 | + # Prepare email parameters |
| 124 | + params: resend.Emails.SendParams = { |
| 125 | + "from": from_email, |
| 126 | + "to": to, |
| 127 | + "subject": subject, |
| 128 | + } |
| 129 | + |
| 130 | + # Add content |
| 131 | + if html: |
| 132 | + params["html"] = html |
| 133 | + if text: |
| 134 | + params["text"] = text |
| 135 | + |
| 136 | + # Add optional parameters |
| 137 | + if cc: |
| 138 | + params["cc"] = cc |
| 139 | + if bcc: |
| 140 | + params["bcc"] = bcc |
| 141 | + if reply_to: |
| 142 | + params["reply_to"] = reply_to |
| 143 | + if tags: |
| 144 | + params["tags"] = cast('list[resend.emails._tag.Tag]', tags) |
| 145 | + if headers: |
| 146 | + params["headers"] = headers |
| 147 | + |
| 148 | + try: |
| 149 | + # Send the email |
| 150 | + email = resend.Emails.send(params) |
| 151 | + return ( |
| 152 | + f"Email sent successfully. " |
| 153 | + f"Email ID: {email.get('id', 'Unknown')}" |
| 154 | + ) |
| 155 | + except Exception as e: |
| 156 | + return f"Failed to send email: {e!s}" |
| 157 | + |
| 158 | + def get_tools(self) -> List[FunctionTool]: |
| 159 | + r"""Returns a list of FunctionTool objects representing the |
| 160 | + functions in the toolkit. |
| 161 | +
|
| 162 | + Returns: |
| 163 | + List[FunctionTool]: A list of FunctionTool objects |
| 164 | + representing the functions in the toolkit. |
| 165 | + """ |
| 166 | + return [ |
| 167 | + FunctionTool(self.send_email), |
| 168 | + ] |
0 commit comments