ntfy.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import logging
  2. import requests
  3. logger = logging.getLogger(__name__)
  4. def initialize_monitor(
  5. ping_url, config, config_filename, monitoring_log_level, dry_run
  6. ): # pragma: no cover
  7. '''
  8. No initialization is necessary for this monitor.
  9. '''
  10. pass
  11. def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run):
  12. '''
  13. Ping the configured Ntfy topic. Use the given configuration filename in any log entries.
  14. If this is a dry run, then don't actually ping anything.
  15. '''
  16. run_states = hook_config.get('states', ['fail'])
  17. if state.name.lower() in run_states:
  18. dry_run_label = ' (dry run; not actually pinging)' if dry_run else ''
  19. state_config = hook_config.get(
  20. state.name.lower(),
  21. {
  22. 'title': f'A borgmatic {state.name} event happened',
  23. 'message': f'A borgmatic {state.name} event happened',
  24. 'priority': 'default',
  25. 'tags': 'borgmatic',
  26. },
  27. )
  28. base_url = hook_config.get('server', 'https://ntfy.sh')
  29. topic = hook_config.get('topic')
  30. logger.info(f'Pinging ntfy topic {topic}{dry_run_label}')
  31. logger.debug(f'Using Ntfy ping URL {base_url}/{topic}')
  32. headers = {
  33. 'X-Title': state_config.get('title'),
  34. 'X-Message': state_config.get('message'),
  35. 'X-Priority': state_config.get('priority'),
  36. 'X-Tags': state_config.get('tags'),
  37. }
  38. username = hook_config.get('username')
  39. password = hook_config.get('password')
  40. access_token = hook_config.get('access_token')
  41. auth = None
  42. if access_token is not None:
  43. if username or password:
  44. logger.warning(
  45. 'ntfy access_token is set but so is username/password, only using access_token'
  46. )
  47. auth = requests.auth.HTTPBasicAuth('', access_token)
  48. elif (username and password) is not None:
  49. auth = requests.auth.HTTPBasicAuth(username, password)
  50. logger.info(f'Using basic auth with user {username} for ntfy')
  51. elif username is not None:
  52. logger.warning(
  53. 'Password missing for ntfy authentication, defaulting to no auth'
  54. )
  55. elif password is not None:
  56. logger.warning(
  57. 'Username missing for ntfy authentication, defaulting to no auth'
  58. )
  59. if not dry_run:
  60. logging.getLogger('urllib3').setLevel(logging.ERROR)
  61. try:
  62. response = requests.post(f'{base_url}/{topic}', headers=headers, auth=auth)
  63. if not response.ok:
  64. response.raise_for_status()
  65. except requests.exceptions.RequestException as error:
  66. logger.warning(f'ntfy error: {error}')
  67. def destroy_monitor(
  68. ping_url_or_uuid, config, monitoring_log_level, dry_run
  69. ): # pragma: no cover
  70. '''
  71. No destruction is necessary for this monitor.
  72. '''
  73. pass