Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
repos:
- repo: local
hooks:
- id: run-just-test
name: All tests and checks
entry: just test
- id: mypy
name: Type checking
entry: just mypy
language: system
always_run: true
pass_filenames: false
- id: check
name: Formatting and linting
entry: just check
language: system
always_run: true
pass_filenames: false
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,7 @@ See the full documentation at [https://matthewcane.github.io/python-ntfy/](https
- Scheduled delivery
- Tags
- Action buttons

## Future Features

- [Email notifications](https://docs.ntfy.sh/publish/#e-mail-notifications)
- Send to multiple topics at once
- Email notifications

## Contributing

Expand Down
10 changes: 10 additions & 0 deletions python_ntfy/_send_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ def send(
schedule: Optional[datetime] = None,
format_as_markdown: bool = False,
timeout_seconds: int = 5,
email: Optional[str] = None,
) -> dict:
"""Send a text-based message to the server.

Expand All @@ -208,6 +209,7 @@ def send(
format_as_markdown: If true, the message will be formatted as markdown.
additional_topics: A list of additional topics to send the message to.
timeout_seconds: The number of seconds to wait before timing out the reqest to the server.
email: Forward messages to an email address. Only one email address can be specified.

Returns:
dict: The response from the server.
Expand Down Expand Up @@ -236,6 +238,9 @@ def send(
if len(actions) > 0:
headers["Actions"] = " ; ".join([action.to_header() for action in actions])

if email:
headers["Email"] = email

if schedule:
headers["Delay"] = str(int(schedule.timestamp()))

Expand All @@ -259,6 +264,7 @@ def send_file(
actions: Optional[list[Union[ViewAction, BroadcastAction, HttpAction]]] = None,
schedule: Optional[datetime] = None,
timeout_seconds: int = 30,
email: Optional[str] = None,
) -> dict:
"""Sends a file to the server.

Expand All @@ -270,6 +276,7 @@ def send_file(
actions: A list of ActionButton objects to attach to the message.
schedule: The time to schedule the message to be sent. Must be more than 10 seconds away and less than 3 days in the future.
timeout_seconds: The number of seconds to wait before timing out.
email: Forward messages to an email address. Only one email address can be specified.

Returns:
dict: The response from the server.
Expand All @@ -293,6 +300,9 @@ def send_file(
"Actions": " ; ".join([action.to_header() for action in actions]),
}

if email:
headers["Email"] = email

if schedule:
headers["Delay"] = str(int(schedule.timestamp()))

Expand Down
18 changes: 14 additions & 4 deletions tests/assets/test_containers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,28 @@ services:
image: binwiederhier/ntfy:latest
command: serve
healthcheck:
test: ["CMD-SHELL", "curl", "-f", "http://localhost/v1/health"]
test: ['CMD-SHELL', 'curl', '-f', 'http://localhost/v1/health']
interval: 1s
retries: 3
ports:
- "8080:80"
- '8080:80'
environment:
NTFY_BASE_URL: 'http://localhost'
NTFY_ATTACHMENT_CACHE_DIR: /var/lib/ntfy/attachments
NTFY_SMTP_SENDER_ADDR: 'localhost:1025'
NTFY_SMTP_SENDER_USER: 'test'
NTFY_SMTP_SENDER_PASS: 'test'
NTFY_SMTP_SENDER_FROM: '[email protected]'

ntfy-with-auth:
image: binwiederhier/ntfy:latest
command: serve
healthcheck:
test: ["CMD-SHELL", "curl", "-f", "http://localhost/v1/health"]
test: ['CMD-SHELL', 'curl', '-f', 'http://localhost/v1/health']
interval: 1s
retries: 3
ports:
- "8081:80"
- '8081:80'
environment:
NTFY_BASE_URL: 'http://localhost'
NTFY_ATTACHMENT_CACHE_DIR: /var/lib/ntfy/attachments
Expand All @@ -29,3 +33,9 @@ services:
volumes:
- ./auth.db:/var/lib/ntfy/auth.db

mailpit:
image: axllent/mailpit
ports:
- '1025:1025'
environment:
MP_SMTP_AUTH_ACCEPT_ANY: 'true'
8 changes: 8 additions & 0 deletions tests/test_send_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,11 @@ def test_send_scheduled_file(localhost_server_no_auth, no_auth) -> None:
assert response["attachment"]["name"] == "test_text.txt"
assert response["attachment"]["type"] == "text/plain; charset=utf-8"
assert response["time"] == int(ts.timestamp())


def test_send_file_with_email(localhost_server_no_auth, no_auth) -> None:
ntfy = NtfyClient(topic=topic)
response = ntfy.send_file("tests/assets/test_text.txt", email="[email protected]")
print(response)
assert response["attachment"]["name"] == "test_text.txt"
assert response["attachment"]["type"] == "text/plain; charset=utf-8"
8 changes: 8 additions & 0 deletions tests/test_send_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,11 @@ def test_send_message_without_auth(no_server, no_auth) -> None:
print(response)
assert response["event"] == "message"
assert response["topic"] == topic


def test_send_message_with_email(localhost_server_no_auth, no_auth) -> None:
ntfy = NtfyClient(topic=topic)
response = ntfy.send(message="test_send_message_with_email", email="[email protected]")
print(response)
assert response["event"] == "message"
assert response["topic"] == topic