Skip to content

Commit

Permalink
[webhooks] initial changes, WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
capcom6 committed Jan 20, 2025
1 parent cc7dc2e commit fb18eed
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ VERSION=$(shell grep '__version__' $(PACKAGE_NAME)/__init__.py | cut -d '"' -f 2

# Install pipenv and project dependencies
install:
pipenv install --dev
pipenv install --dev --categories encryption

# Run tests with pytest or unittest
test:
Expand Down
20 changes: 20 additions & 0 deletions android_sms_gateway/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,26 @@ def get_state(self, _id: str) -> domain.MessageState:
)
)

def get_webhooks(self) -> t.List[domain.Webhook]:
return [
domain.Webhook.from_dict(webhook)
for webhook in self.http.get(
f"{self.base_url}/webhooks", headers=self.headers
)
]

def create_webhook(self, webhook: domain.Webhook) -> domain.Webhook:
return domain.Webhook.from_dict(
self.http.post(
f"{self.base_url}/webhooks",
payload=webhook.asdict(),
headers=self.headers,
)
)

def delete_webhook(self, _id: str) -> None:
self.http.delete(f"{self.base_url}/webhooks/{_id}", headers=self.headers)


class AsyncAPIClient(BaseClient):
def __init__(
Expand Down
42 changes: 41 additions & 1 deletion android_sms_gateway/domain.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import dataclasses
import typing as t

from .enums import ProcessState
from .enums import ProcessState, WebhookEvent


def snake_to_camel(snake_str):
Expand Down Expand Up @@ -63,3 +63,43 @@ def from_dict(cls, payload: t.Dict[str, t.Any]) -> "MessageState":
is_hashed=payload.get("isHashed", False),
is_encrypted=payload.get("isEncrypted", False),
)


@dataclasses.dataclass(frozen=True)
class Webhook:
"""A webhook configuration."""

id: t.Optional[str]
"""The unique identifier of the webhook."""
url: str
"""The URL the webhook will be sent to."""
event: WebhookEvent
"""The type of event the webhook is triggered for."""

@classmethod
def from_dict(cls, payload: t.Dict[str, t.Any]) -> "Webhook":
"""Creates a Webhook instance from a dictionary.
Args:
payload: A dictionary containing the webhook's data.
Returns:
A Webhook instance.
"""
return cls(
id=payload["id"],
url=payload["url"],
event=WebhookEvent(payload["event"]),
)

def asdict(self) -> t.Dict[str, t.Any]:
"""Returns a dictionary representation of the webhook.
Returns:
A dictionary containing the webhook's data.
"""
return {
"id": self.id,
"url": self.url,
"event": self.event.value,
}
21 changes: 21 additions & 0 deletions android_sms_gateway/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,24 @@ class ProcessState(enum.Enum):
Sent = "Sent"
Delivered = "Delivered"
Failed = "Failed"


class WebhookEvent(enum.Enum):
"""
Webhook events that can be sent by the server.
"""

SMS_RECEIVED = "sms:received"
"""Triggered when an SMS is received."""

SMS_SENT = "sms:sent"
"""Triggered when an SMS is sent."""

SMS_DELIVERED = "sms:delivered"
"""Triggered when an SMS is delivered."""

SMS_FAILED = "sms:failed"
"""Triggered when an SMS processing fails."""

SYSTEM_PING = "system:ping"
"""Triggered when the device pings the server."""
13 changes: 13 additions & 0 deletions android_sms_gateway/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@ def post(
self, url: str, payload: dict, *, headers: t.Optional[t.Dict[str, str]] = None
) -> dict: ...

@abc.abstractmethod
def delete(self, url: str, *, headers: t.Optional[t.Dict[str, str]] = None) -> None:
"""
Sends a DELETE request to the specified URL.
Args:
url: The URL to send the DELETE request to.
headers: Optional dictionary of HTTP headers to send with the request.
Returns:
None
"""

def __enter__(self):
pass

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,4 @@ dev = ["setuptools", "pytest", "black", "flake8", "wheel"]
requests = ["requests"]
httpx = ["httpx"]
aiohttp = ["aiohttp"]
encryption = ["pycryptodome"]
58 changes: 57 additions & 1 deletion tests/test_domain.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from android_sms_gateway.enums import WebhookEvent
import pytest

from android_sms_gateway.domain import MessageState, RecipientState
from android_sms_gateway.domain import MessageState, RecipientState, Webhook


# Test for successful instantiation from a dictionary
Expand Down Expand Up @@ -79,3 +80,58 @@ def test_message_state_from_dict_incorrect_types():
Exception
): # Replace Exception with the specific exception you expect
MessageState.from_dict(incorrect_payload)


def test_webhook_from_dict():
"""
Tests that a Webhook instance can be successfully instantiated from a dictionary
representation of a webhook.
"""
payload = {
"id": "webhook_123",
"url": "https://example.com/webhook",
"event": "sms:received",
}

webhook = Webhook.from_dict(payload)

assert webhook.id == payload["id"]
assert webhook.url == payload["url"]
assert webhook.event == WebhookEvent(payload["event"])


def test_webhook_asdict():
"""
Tests that a Webhook instance can be successfully converted to a dictionary
representation and that the fields match the expected values.
This test ensures that the asdict method of the Webhook class returns a dictionary
with the correct keys and values.
"""
webhook = Webhook(
id="webhook_123",
url="https://example.com/webhook",
event=WebhookEvent.SMS_RECEIVED,
)

expected_dict = {
"id": "webhook_123",
"url": "https://example.com/webhook",
"event": "sms:received",
}

assert webhook.asdict() == expected_dict

webhook = Webhook(
id=None,
url="https://example.com/webhook",
event=WebhookEvent.SMS_RECEIVED,
)

expected_dict = {
"id": None,
"url": "https://example.com/webhook",
"event": "sms:received",
}

assert webhook.asdict() == expected_dict

0 comments on commit fb18eed

Please sign in to comment.