forked from retoor/devplacepy
feat: add plug-and-play devRant API client examples with Python and JavaScript
Add complete set of example scripts for the devRant REST protocol under examples/devrant/, including reusable client libraries, a rant poster, a live feed watcher with keyword-based auto-upvote, and an end-to-end smoke test that exercises every endpoint. Both Python (stdlib-only) and JavaScript (Node 18+ global fetch) implementations are provided.
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import time
|
||||
import xmlrpc.client
|
||||
|
||||
from client import DevPlace
|
||||
|
||||
URL = os.environ.get("DEVPLACE_URL", "https://devplace.net")
|
||||
API_KEY = os.environ.get("DEVPLACE_API_KEY", "YOUR_API_KEY")
|
||||
POLL_SECONDS = int(os.environ.get("DEVPLACE_POLL_SECONDS", "10"))
|
||||
|
||||
|
||||
def respond(dp: DevPlace, text: str, sender: dict) -> str:
|
||||
text = (text or "").strip()
|
||||
command = text.lower()
|
||||
name = sender.get("username", "there")
|
||||
if command in ("hi", "hello", "hey", "help", "/help", "/start"):
|
||||
return (
|
||||
f"Hi @{name}! I am a DevPlace chat bot reachable over XML-RPC. "
|
||||
"Try: 'feed' for the latest posts, 'echo your message', or 'whoami'."
|
||||
)
|
||||
if command == "whoami":
|
||||
return f"You are @{name} (uid {sender.get('uid')})."
|
||||
if command == "feed":
|
||||
page = dp.call("feed.list")
|
||||
lines = [
|
||||
f"- {item['post'].get('title') or item['post']['uid']} by @{item['author']['username']}"
|
||||
for item in page.get("posts", [])[:3]
|
||||
]
|
||||
return "Latest posts:\n" + "\n".join(lines) if lines else "The feed is empty."
|
||||
if command.startswith("echo "):
|
||||
return text[5:]
|
||||
return "I did not understand that. Send 'help' for the list of commands."
|
||||
|
||||
|
||||
def run() -> None:
|
||||
dp = DevPlace(URL, api_key=API_KEY)
|
||||
answered: set[str] = set()
|
||||
print(f"Chat bot started; polling {URL} every {POLL_SECONDS}s.")
|
||||
while True:
|
||||
try:
|
||||
inbox = dp.call("messages.inbox")
|
||||
for conversation in inbox.get("conversations", []):
|
||||
if not conversation.get("unread"):
|
||||
continue
|
||||
other = conversation.get("other_user") or {}
|
||||
if not other.get("uid"):
|
||||
continue
|
||||
thread = dp.call("messages.inbox", with_uid=other["uid"])
|
||||
incoming = [m for m in thread.get("messages", []) if not m.get("is_mine")]
|
||||
if not incoming:
|
||||
continue
|
||||
last = incoming[-1]
|
||||
message_uid = last["message"]["uid"]
|
||||
if message_uid in answered:
|
||||
continue
|
||||
answered.add(message_uid)
|
||||
reply = respond(dp, last["message"]["content"], other)
|
||||
dp.call("messages.send", content=reply, receiver_uid=other["uid"])
|
||||
print(f"Replied to @{other.get('username')}: {last['message']['content']!r}")
|
||||
except xmlrpc.client.Fault as fault:
|
||||
print("Poll error:", fault.faultCode, fault.faultString)
|
||||
except OSError as error:
|
||||
print("Network error, retrying:", error)
|
||||
time.sleep(POLL_SECONDS)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
Reference in New Issue
Block a user