Skip to content

Commit 18d8b9c

Browse files
authored
Merge pull request #1692 from arc53/tool-ntfy
feat: ntfy tool
2 parents 4fd6c52 + 8b9b744 commit 18d8b9c

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed

application/agents/tools/ntfy.py

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import requests
2+
from application.agents.tools.base import Tool
3+
4+
class NtfyTool(Tool):
5+
"""
6+
Ntfy Tool
7+
A tool for sending notifications to ntfy topics on a specified server.
8+
"""
9+
10+
def __init__(self, config):
11+
"""
12+
Initialize the NtfyTool with configuration.
13+
14+
Args:
15+
config (dict): Configuration dictionary containing the access token.
16+
"""
17+
self.config = config
18+
self.token = config.get("token", "")
19+
20+
def execute_action(self, action_name, **kwargs):
21+
"""
22+
Execute the specified action with given parameters.
23+
24+
Args:
25+
action_name (str): Name of the action to execute.
26+
**kwargs: Parameters for the action, including server_url.
27+
28+
Returns:
29+
dict: Result of the action with status code and message.
30+
31+
Raises:
32+
ValueError: If the action name is unknown.
33+
"""
34+
actions = {
35+
"ntfy_send_message": self._send_message,
36+
}
37+
if action_name in actions:
38+
return actions[action_name](**kwargs)
39+
else:
40+
raise ValueError(f"Unknown action: {action_name}")
41+
42+
def _send_message(self, server_url, message, topic, title=None, priority=None):
43+
"""
44+
Send a message to an ntfy topic on the specified server.
45+
46+
Args:
47+
server_url (str): Base URL of the ntfy server (e.g., https://ntfy.sh).
48+
message (str): The message text to send.
49+
topic (str): The topic to send the message to.
50+
title (str, optional): Title of the notification.
51+
priority (int, optional): Priority of the notification (1-5).
52+
53+
Returns:
54+
dict: Response with status code and a confirmation message.
55+
56+
Raises:
57+
ValueError: If priority is not an integer between 1 and 5.
58+
"""
59+
url = f"{server_url.rstrip('/')}/{topic}"
60+
headers = {}
61+
if title:
62+
headers["X-Title"] = title
63+
if priority:
64+
try:
65+
priority = int(priority)
66+
except (ValueError, TypeError):
67+
raise ValueError("Priority must be convertible to an integer")
68+
if priority < 1 or priority > 5:
69+
raise ValueError("Priority must be an integer between 1 and 5")
70+
headers["X-Priority"] = str(priority)
71+
if self.token:
72+
headers["Authorization"] = f"Basic {self.token}"
73+
data = message.encode("utf-8")
74+
response = requests.post(url, headers=headers, data=data)
75+
return {"status_code": response.status_code, "message": "Message sent"}
76+
77+
def get_actions_metadata(self):
78+
"""
79+
Provide metadata about available actions.
80+
81+
Returns:
82+
list: List of dictionaries describing each action.
83+
"""
84+
return [
85+
{
86+
"name": "ntfy_send_message",
87+
"description": "Send a notification to an ntfy topic",
88+
"parameters": {
89+
"type": "object",
90+
"properties": {
91+
"server_url": {
92+
"type": "string",
93+
"description": "Base URL of the ntfy server",
94+
},
95+
"message": {
96+
"type": "string",
97+
"description": "Text to send in the notification",
98+
},
99+
"topic": {
100+
"type": "string",
101+
"description": "Topic to send the notification to",
102+
},
103+
"title": {
104+
"type": "string",
105+
"description": "Title of the notification (optional)",
106+
},
107+
"priority": {
108+
"type": "integer",
109+
"description": "Priority of the notification (1-5, optional)",
110+
},
111+
},
112+
"required": ["server_url", "message", "topic"],
113+
"additionalProperties": False,
114+
},
115+
},
116+
]
117+
118+
def get_config_requirements(self):
119+
"""
120+
Specify the configuration requirements.
121+
122+
Returns:
123+
dict: Dictionary describing required config parameters.
124+
"""
125+
return {
126+
"token": {"type": "string", "description": "Access token for authentication"},
127+
}
Lines changed: 8 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)