gork-sdk 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gork_sdk-1.0.0/PKG-INFO +59 -0
- gork_sdk-1.0.0/README.md +42 -0
- gork_sdk-1.0.0/pyproject.toml +27 -0
- gork_sdk-1.0.0/setup.cfg +4 -0
- gork_sdk-1.0.0/src/gork/__init__.py +19 -0
- gork_sdk-1.0.0/src/gork/client.py +180 -0
- gork_sdk-1.0.0/src/gork/errors.py +9 -0
- gork_sdk-1.0.0/src/gork/types.py +59 -0
- gork_sdk-1.0.0/src/gork_sdk.egg-info/PKG-INFO +59 -0
- gork_sdk-1.0.0/src/gork_sdk.egg-info/SOURCES.txt +10 -0
- gork_sdk-1.0.0/src/gork_sdk.egg-info/dependency_links.txt +1 -0
- gork_sdk-1.0.0/src/gork_sdk.egg-info/top_level.txt +1 -0
gork_sdk-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: gork-sdk
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Official Python SDK for gork.email programmable email infrastructure for AI agents
|
|
5
|
+
Author: gork.email
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://gork.email
|
|
8
|
+
Project-URL: Documentation, https://gork.email/docs
|
|
9
|
+
Project-URL: Repository, https://github.com/shyamcxy/gork-sdk
|
|
10
|
+
Keywords: email,agent,ai,mcp,inbox,mail
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Topic :: Communications :: Email
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
15
|
+
Requires-Python: >=3.9
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# gork-sdk — Python SDK for gork.email
|
|
19
|
+
|
|
20
|
+
Programmable email infrastructure for AI agents. Provision inboxes, send and receive mail, manage threads, webhooks, domains, keys, and suppressions.
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install gork-sdk
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quickstart
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from gork import GorkClient
|
|
32
|
+
|
|
33
|
+
gork = GorkClient() # reads GORK_KEY / GORK_API_KEY
|
|
34
|
+
|
|
35
|
+
inbox = gork.create_inbox(username="sdr-alex", name="SDR Alex")
|
|
36
|
+
print(inbox["address"]) # sdr-alex@gork.email
|
|
37
|
+
|
|
38
|
+
gork.send_message(
|
|
39
|
+
inbox_id=inbox["id"],
|
|
40
|
+
to=["prospect@acme.com"],
|
|
41
|
+
subject="Quick intro",
|
|
42
|
+
text="Hi — wanted to share what we're building.",
|
|
43
|
+
idempotency_key="outreach-001", # safe retries
|
|
44
|
+
)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Webhook verification
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from gork import verify_signature
|
|
51
|
+
|
|
52
|
+
ok = verify_signature(raw_body, request.headers["X-Gork-Signature"], webhook_secret)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Links
|
|
56
|
+
|
|
57
|
+
- Docs: https://gork.email/docs
|
|
58
|
+
- API reference: https://api.gork.email/openapi.json
|
|
59
|
+
- Changelog: https://gork.email/changelog
|
gork_sdk-1.0.0/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# gork-sdk — Python SDK for gork.email
|
|
2
|
+
|
|
3
|
+
Programmable email infrastructure for AI agents. Provision inboxes, send and receive mail, manage threads, webhooks, domains, keys, and suppressions.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install gork-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quickstart
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from gork import GorkClient
|
|
15
|
+
|
|
16
|
+
gork = GorkClient() # reads GORK_KEY / GORK_API_KEY
|
|
17
|
+
|
|
18
|
+
inbox = gork.create_inbox(username="sdr-alex", name="SDR Alex")
|
|
19
|
+
print(inbox["address"]) # sdr-alex@gork.email
|
|
20
|
+
|
|
21
|
+
gork.send_message(
|
|
22
|
+
inbox_id=inbox["id"],
|
|
23
|
+
to=["prospect@acme.com"],
|
|
24
|
+
subject="Quick intro",
|
|
25
|
+
text="Hi — wanted to share what we're building.",
|
|
26
|
+
idempotency_key="outreach-001", # safe retries
|
|
27
|
+
)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Webhook verification
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from gork import verify_signature
|
|
34
|
+
|
|
35
|
+
ok = verify_signature(raw_body, request.headers["X-Gork-Signature"], webhook_secret)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Links
|
|
39
|
+
|
|
40
|
+
- Docs: https://gork.email/docs
|
|
41
|
+
- API reference: https://api.gork.email/openapi.json
|
|
42
|
+
- Changelog: https://gork.email/changelog
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "gork-sdk"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Official Python SDK for gork.email programmable email infrastructure for AI agents"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "gork.email" }]
|
|
13
|
+
keywords = ["email", "agent", "ai", "mcp", "inbox", "mail"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Topic :: Communications :: Email",
|
|
18
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[project.urls]
|
|
22
|
+
Homepage = "https://gork.email"
|
|
23
|
+
Documentation = "https://gork.email/docs"
|
|
24
|
+
Repository = "https://github.com/shyamcxy/gork-sdk"
|
|
25
|
+
|
|
26
|
+
[tool.setuptools.packages.find]
|
|
27
|
+
where = ["src"]
|
gork_sdk-1.0.0/setup.cfg
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""gork.email Python SDK — programmable email infrastructure for AI agents."""
|
|
2
|
+
|
|
3
|
+
from .client import GorkClient
|
|
4
|
+
from .errors import GorkError
|
|
5
|
+
from .types import Inbox, Message, Thread, Webhook, ApiKey, Domain, Suppression
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"GorkClient",
|
|
9
|
+
"GorkError",
|
|
10
|
+
"Inbox",
|
|
11
|
+
"Message",
|
|
12
|
+
"Thread",
|
|
13
|
+
"Webhook",
|
|
14
|
+
"ApiKey",
|
|
15
|
+
"Domain",
|
|
16
|
+
"Suppression",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
__version__ = "1.0.0"
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"""GorkClient — zero-dependency (stdlib only) REST client for api.gork.email."""
|
|
2
|
+
|
|
3
|
+
import hashlib
|
|
4
|
+
import hmac
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import urllib.parse
|
|
8
|
+
import urllib.request
|
|
9
|
+
from typing import Any, Dict, List, Optional
|
|
10
|
+
|
|
11
|
+
from .errors import GorkError
|
|
12
|
+
|
|
13
|
+
DEFAULT_BASE_URL = "https://api.gork.email"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def verify_signature(payload: str, signature_header: str, secret: str) -> bool:
|
|
17
|
+
"""Verify an X-Gork-Signature webhook header (HMAC-SHA256, timestamp-tolerated)."""
|
|
18
|
+
try:
|
|
19
|
+
parts = dict(p.split("=", 1) for p in signature_header.split(",") if "=" in p)
|
|
20
|
+
timestamp, signature = parts.get("t", ""), parts.get("v1", "")
|
|
21
|
+
if not timestamp or not signature:
|
|
22
|
+
return False
|
|
23
|
+
expected = hmac.new(
|
|
24
|
+
secret.encode(), f"{timestamp}.{payload}".encode(), hashlib.sha256
|
|
25
|
+
).hexdigest()
|
|
26
|
+
return hmac.compare_digest(signature, expected)
|
|
27
|
+
except Exception:
|
|
28
|
+
return False
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class GorkClient:
|
|
32
|
+
def __init__(self, api_key: str = "", base_url: str = DEFAULT_BASE_URL):
|
|
33
|
+
self.api_key = api_key or os.environ.get("GORK_KEY") or os.environ.get("GORK_API_KEY") or ""
|
|
34
|
+
self.base_url = (base_url or DEFAULT_BASE_URL).rstrip("/")
|
|
35
|
+
if not self.api_key:
|
|
36
|
+
import warnings
|
|
37
|
+
|
|
38
|
+
warnings.warn(
|
|
39
|
+
"[gork] initialized without an api_key. Set GORK_KEY or pass api_key explicitly."
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
def _request(
|
|
43
|
+
self,
|
|
44
|
+
method: str,
|
|
45
|
+
path: str,
|
|
46
|
+
body: Optional[Dict[str, Any]] = None,
|
|
47
|
+
query: Optional[Dict[str, Any]] = None,
|
|
48
|
+
headers: Optional[Dict[str, str]] = None,
|
|
49
|
+
) -> Any:
|
|
50
|
+
url = self.base_url + path
|
|
51
|
+
if query:
|
|
52
|
+
url += "?" + urllib.parse.urlencode({k: v for k, v in query.items() if v is not None})
|
|
53
|
+
data = json.dumps(body).encode() if body is not None else None
|
|
54
|
+
req = urllib.request.Request(url, data=data, method=method)
|
|
55
|
+
req.add_header("Authorization", f"Bearer {self.api_key}")
|
|
56
|
+
req.add_header("Content-Type", "application/json")
|
|
57
|
+
req.add_header("User-Agent", "gork-sdk-python/1.0.0")
|
|
58
|
+
for k, v in (headers or {}).items():
|
|
59
|
+
req.add_header(k, v)
|
|
60
|
+
try:
|
|
61
|
+
with urllib.request.urlopen(req, timeout=30) as res:
|
|
62
|
+
payload = json.loads(res.read().decode() or "{}")
|
|
63
|
+
except urllib.error.HTTPError as e:
|
|
64
|
+
try:
|
|
65
|
+
payload = json.loads(e.read().decode() or "{}")
|
|
66
|
+
except Exception:
|
|
67
|
+
payload = {}
|
|
68
|
+
err = (payload.get("error") or {}) if isinstance(payload, dict) else {}
|
|
69
|
+
raise GorkError(
|
|
70
|
+
err.get("message") or f"API request failed with status {e.code}",
|
|
71
|
+
err.get("code") or "api_error",
|
|
72
|
+
e.code,
|
|
73
|
+
err.get("details"),
|
|
74
|
+
)
|
|
75
|
+
data_key = payload.get("data", payload) if isinstance(payload, dict) else payload
|
|
76
|
+
return data_key
|
|
77
|
+
|
|
78
|
+
# ---- Inboxes ----
|
|
79
|
+
def create_inbox(self, username: str = "", name: str = "") -> Dict[str, Any]:
|
|
80
|
+
return self._request("POST", "/v1/inboxes", {"username": username, "name": name})
|
|
81
|
+
|
|
82
|
+
def list_inboxes(self) -> List[Dict[str, Any]]:
|
|
83
|
+
return self._request("GET", "/v1/inboxes")
|
|
84
|
+
|
|
85
|
+
def get_inbox(self, inbox_id: str) -> Dict[str, Any]:
|
|
86
|
+
return self._request("GET", f"/v1/inboxes/{urllib.parse.quote(inbox_id)}")
|
|
87
|
+
|
|
88
|
+
def delete_inbox(self, inbox_id: str) -> Dict[str, Any]:
|
|
89
|
+
return self._request("DELETE", f"/v1/inboxes/{urllib.parse.quote(inbox_id)}")
|
|
90
|
+
|
|
91
|
+
# ---- Messages ----
|
|
92
|
+
def send_message(
|
|
93
|
+
self,
|
|
94
|
+
inbox_id: str,
|
|
95
|
+
to: List[str],
|
|
96
|
+
subject: str = "(no subject)",
|
|
97
|
+
text: str = "",
|
|
98
|
+
html: str = "",
|
|
99
|
+
in_reply_to: str = "",
|
|
100
|
+
idempotency_key: str = "",
|
|
101
|
+
) -> Dict[str, Any]:
|
|
102
|
+
body: Dict[str, Any] = {"inboxId": inbox_id, "to": to, "subject": subject}
|
|
103
|
+
if text:
|
|
104
|
+
body["text"] = text
|
|
105
|
+
if html:
|
|
106
|
+
body["html"] = html
|
|
107
|
+
if in_reply_to:
|
|
108
|
+
body["inReplyTo"] = in_reply_to
|
|
109
|
+
headers = {"Idempotency-Key": idempotency_key} if idempotency_key else None
|
|
110
|
+
return self._request("POST", "/v1/messages/send", body, headers=headers)
|
|
111
|
+
|
|
112
|
+
def list_messages(
|
|
113
|
+
self, inbox_id: str = "", thread_id: str = "", limit: int = 50
|
|
114
|
+
) -> List[Dict[str, Any]]:
|
|
115
|
+
return self._request(
|
|
116
|
+
"GET", "/v1/messages",
|
|
117
|
+
query={"inboxId": inbox_id or None, "threadId": thread_id or None, "limit": limit},
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
def get_message(self, message_id: str) -> Dict[str, Any]:
|
|
121
|
+
return self._request("GET", f"/v1/messages/{urllib.parse.quote(message_id)}")
|
|
122
|
+
|
|
123
|
+
# ---- Threads ----
|
|
124
|
+
def list_threads(self) -> List[Dict[str, Any]]:
|
|
125
|
+
return self._request("GET", "/v1/threads")
|
|
126
|
+
|
|
127
|
+
def get_thread(self, thread_id: str) -> Dict[str, Any]:
|
|
128
|
+
return self._request("GET", f"/v1/threads/{urllib.parse.quote(thread_id)}")
|
|
129
|
+
|
|
130
|
+
# ---- Webhooks ----
|
|
131
|
+
def create_webhook(self, url: str, events: Optional[List[str]] = None) -> Dict[str, Any]:
|
|
132
|
+
return self._request(
|
|
133
|
+
"POST", "/v1/webhooks",
|
|
134
|
+
{"url": url, "subscribedEvents": events or ["email.received", "email.sent", "email.bounced"]},
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
def list_webhooks(self) -> List[Dict[str, Any]]:
|
|
138
|
+
return self._request("GET", "/v1/webhooks")
|
|
139
|
+
|
|
140
|
+
def rotate_webhook_secret(self, webhook_id: str) -> Dict[str, Any]:
|
|
141
|
+
return self._request("POST", f"/v1/webhooks/{urllib.parse.quote(webhook_id)}/rotate-secret")
|
|
142
|
+
|
|
143
|
+
def delete_webhook(self, webhook_id: str) -> Dict[str, Any]:
|
|
144
|
+
return self._request("DELETE", f"/v1/webhooks/{urllib.parse.quote(webhook_id)}")
|
|
145
|
+
|
|
146
|
+
def list_deliveries(self, limit: int = 50) -> List[Dict[str, Any]]:
|
|
147
|
+
return self._request("GET", "/v1/webhooks/deliveries", query={"limit": limit})
|
|
148
|
+
|
|
149
|
+
# ---- API keys ----
|
|
150
|
+
def create_api_key(self, name: str, scopes: Optional[List[str]] = None) -> Dict[str, Any]:
|
|
151
|
+
return self._request("POST", "/v1/keys", {"name": name, "scopes": scopes or ["*"]})
|
|
152
|
+
|
|
153
|
+
def list_api_keys(self) -> List[Dict[str, Any]]:
|
|
154
|
+
return self._request("GET", "/v1/keys")
|
|
155
|
+
|
|
156
|
+
def revoke_api_key(self, key_id: str) -> Dict[str, Any]:
|
|
157
|
+
return self._request("DELETE", f"/v1/keys/{urllib.parse.quote(key_id)}")
|
|
158
|
+
|
|
159
|
+
# ---- Domains ----
|
|
160
|
+
def create_domain(self, domain: str) -> Dict[str, Any]:
|
|
161
|
+
return self._request("POST", "/v1/domains", {"domain": domain})
|
|
162
|
+
|
|
163
|
+
def list_domains(self) -> List[Dict[str, Any]]:
|
|
164
|
+
return self._request("GET", "/v1/domains")
|
|
165
|
+
|
|
166
|
+
def verify_domain(self, domain_id: str) -> Dict[str, Any]:
|
|
167
|
+
return self._request("POST", f"/v1/domains/{urllib.parse.quote(domain_id)}/verify")
|
|
168
|
+
|
|
169
|
+
def delete_domain(self, domain_id: str) -> Dict[str, Any]:
|
|
170
|
+
return self._request("DELETE", f"/v1/domains/{urllib.parse.quote(domain_id)}")
|
|
171
|
+
|
|
172
|
+
# ---- Suppressions ----
|
|
173
|
+
def list_suppressions(self) -> List[Dict[str, Any]]:
|
|
174
|
+
return self._request("GET", "/v1/suppressions")
|
|
175
|
+
|
|
176
|
+
def suppress(self, email: str, reason: str = "manual") -> Dict[str, Any]:
|
|
177
|
+
return self._request("POST", "/v1/suppressions", {"email": email, "reason": reason})
|
|
178
|
+
|
|
179
|
+
def unsuppress(self, suppression_id: str) -> Dict[str, Any]:
|
|
180
|
+
return self._request("DELETE", f"/v1/suppressions/{urllib.parse.quote(suppression_id)}")
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""Error type carrying the API's stable error code."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class GorkError(Exception):
|
|
5
|
+
def __init__(self, message: str, code: str = "api_error", status: int = 0, details=None):
|
|
6
|
+
super().__init__(message)
|
|
7
|
+
self.code = code
|
|
8
|
+
self.status = status
|
|
9
|
+
self.details = details
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""TypedDict shapes mirroring the gork.email API envelopes."""
|
|
2
|
+
|
|
3
|
+
from typing import List, Optional, TypedDict
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Inbox(TypedDict, total=False):
|
|
7
|
+
id: str
|
|
8
|
+
address: str
|
|
9
|
+
name: Optional[str]
|
|
10
|
+
isActive: bool
|
|
11
|
+
createdAt: str
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Message(TypedDict, total=False):
|
|
15
|
+
id: str
|
|
16
|
+
threadId: str
|
|
17
|
+
inboxId: str
|
|
18
|
+
direction: str
|
|
19
|
+
fromAddress: str
|
|
20
|
+
subject: str
|
|
21
|
+
textBody: Optional[str]
|
|
22
|
+
status: str
|
|
23
|
+
createdAt: str
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Thread(TypedDict, total=False):
|
|
27
|
+
id: str
|
|
28
|
+
subject: str
|
|
29
|
+
messageCount: int
|
|
30
|
+
lastMessageAt: str
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class Webhook(TypedDict, total=False):
|
|
34
|
+
id: str
|
|
35
|
+
url: str
|
|
36
|
+
subscribedEvents: List[str]
|
|
37
|
+
isActive: bool
|
|
38
|
+
secret: Optional[str]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ApiKey(TypedDict, total=False):
|
|
42
|
+
id: str
|
|
43
|
+
name: str
|
|
44
|
+
keyPrefix: str
|
|
45
|
+
apiKey: Optional[str]
|
|
46
|
+
scopes: List[str]
|
|
47
|
+
createdAt: str
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class Domain(TypedDict, total=False):
|
|
51
|
+
id: str
|
|
52
|
+
domainName: str
|
|
53
|
+
status: str
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class Suppression(TypedDict, total=False):
|
|
57
|
+
id: str
|
|
58
|
+
email: str
|
|
59
|
+
reason: str
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: gork-sdk
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Official Python SDK for gork.email programmable email infrastructure for AI agents
|
|
5
|
+
Author: gork.email
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://gork.email
|
|
8
|
+
Project-URL: Documentation, https://gork.email/docs
|
|
9
|
+
Project-URL: Repository, https://github.com/shyamcxy/gork-sdk
|
|
10
|
+
Keywords: email,agent,ai,mcp,inbox,mail
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Topic :: Communications :: Email
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
15
|
+
Requires-Python: >=3.9
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# gork-sdk — Python SDK for gork.email
|
|
19
|
+
|
|
20
|
+
Programmable email infrastructure for AI agents. Provision inboxes, send and receive mail, manage threads, webhooks, domains, keys, and suppressions.
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install gork-sdk
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quickstart
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from gork import GorkClient
|
|
32
|
+
|
|
33
|
+
gork = GorkClient() # reads GORK_KEY / GORK_API_KEY
|
|
34
|
+
|
|
35
|
+
inbox = gork.create_inbox(username="sdr-alex", name="SDR Alex")
|
|
36
|
+
print(inbox["address"]) # sdr-alex@gork.email
|
|
37
|
+
|
|
38
|
+
gork.send_message(
|
|
39
|
+
inbox_id=inbox["id"],
|
|
40
|
+
to=["prospect@acme.com"],
|
|
41
|
+
subject="Quick intro",
|
|
42
|
+
text="Hi — wanted to share what we're building.",
|
|
43
|
+
idempotency_key="outreach-001", # safe retries
|
|
44
|
+
)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Webhook verification
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from gork import verify_signature
|
|
51
|
+
|
|
52
|
+
ok = verify_signature(raw_body, request.headers["X-Gork-Signature"], webhook_secret)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Links
|
|
56
|
+
|
|
57
|
+
- Docs: https://gork.email/docs
|
|
58
|
+
- API reference: https://api.gork.email/openapi.json
|
|
59
|
+
- Changelog: https://gork.email/changelog
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/gork/__init__.py
|
|
4
|
+
src/gork/client.py
|
|
5
|
+
src/gork/errors.py
|
|
6
|
+
src/gork/types.py
|
|
7
|
+
src/gork_sdk.egg-info/PKG-INFO
|
|
8
|
+
src/gork_sdk.egg-info/SOURCES.txt
|
|
9
|
+
src/gork_sdk.egg-info/dependency_links.txt
|
|
10
|
+
src/gork_sdk.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
gork
|