health-push.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #!/usr/bin/env python3
  2. """
  3. health-push.py — 通过 push.rrbrr.com WebSocket 推送服务发推送
  4. Usage:
  5. PUSH_API_URL=https://push.rrbrr.com PUSH_API_KEY=xxx PUSH_USER_ID=admin \
  6. python3 health-push.py <title> <<< "content"
  7. Env required:
  8. PUSH_API_URL push 服务地址,默认 https://push.rrbrr.com
  9. PUSH_API_KEY API key(绑定 channel),默认 monitor-api-key-001
  10. PUSH_USER_ID 接收推送的 userId,默认 admin
  11. PUSH_CHANNEL 推送 channel,默认 monitor
  12. """
  13. import os
  14. import sys
  15. import json
  16. import urllib.request
  17. import urllib.error
  18. import ssl
  19. def main():
  20. if len(sys.argv) < 2:
  21. print("Usage: health-push.py <title>", file=sys.stderr)
  22. sys.exit(2)
  23. title = sys.argv[1]
  24. content = sys.stdin.read() if not sys.stdin.isatty() else "(empty)"
  25. url = os.environ.get('PUSH_API_URL', 'https://push.rrbrr.com').rstrip('/')
  26. api_key = os.environ.get('PUSH_API_KEY', 'monitor-api-key-001')
  27. user_id = os.environ.get('PUSH_USER_ID', 'admin')
  28. channel = os.environ.get('PUSH_CHANNEL', 'monitor')
  29. body = json.dumps({
  30. 'userId': user_id,
  31. 'channel': channel,
  32. 'title': title,
  33. 'content': content[:500], # 限制长度,H5 显示友好
  34. 'data': {'ts': __import__('time').time()},
  35. }).encode('utf-8')
  36. req = urllib.request.Request(
  37. f'{url}/api/notify',
  38. data=body,
  39. method='POST',
  40. headers={
  41. 'Authorization': f'Bearer {api_key}',
  42. 'Content-Type': 'application/json',
  43. },
  44. )
  45. ctx = ssl.create_default_context()
  46. ctx.check_hostname = False
  47. ctx.verify_mode = ssl.CERT_NONE # 自签证书先跳过
  48. try:
  49. with urllib.request.urlopen(req, timeout=10, context=ctx) as r:
  50. resp = json.loads(r.read().decode('utf-8'))
  51. if resp.get('ok'):
  52. print(f"OK: sent '{title}' to userId={user_id} channel={channel}, online={resp.get('online', 0)}")
  53. sys.exit(0)
  54. else:
  55. print(f"API NOK: {resp}", file=sys.stderr)
  56. sys.exit(3)
  57. except urllib.error.HTTPError as e:
  58. print(f"HTTP {e.code}: {e.read().decode('utf-8', 'replace')[:200]}", file=sys.stderr)
  59. sys.exit(4)
  60. except Exception as e:
  61. print(f"NET FAIL [{type(e).__name__}]: {e}", file=sys.stderr)
  62. sys.exit(5)
  63. if __name__ == '__main__':
  64. main()