webhooks_worker.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import hashlib
  2. import hmac
  3. import requests
  4. import json
  5. from django_rq import job
  6. from rest_framework.utils.encoders import JSONEncoder
  7. from extras.constants import WEBHOOK_CT_JSON, WEBHOOK_CT_X_WWW_FORM_ENCODED, OBJECTCHANGE_ACTION_CHOICES
  8. @job('default')
  9. def process_webhook(webhook, data, model_class, event, timestamp):
  10. """
  11. Make a POST request to the defined Webhook
  12. """
  13. payload = {
  14. 'event': dict(OBJECTCHANGE_ACTION_CHOICES)[event].lower(),
  15. 'timestamp': timestamp,
  16. 'model': model_class._meta.model_name,
  17. 'data': data
  18. }
  19. headers = {
  20. 'Content-Type': webhook.get_http_content_type_display(),
  21. }
  22. params = {
  23. 'method': 'POST',
  24. 'url': webhook.payload_url,
  25. 'headers': headers
  26. }
  27. if webhook.http_content_type == WEBHOOK_CT_JSON:
  28. params.update({'data': json.dumps(payload, cls=JSONEncoder)})
  29. elif webhook.http_content_type == WEBHOOK_CT_X_WWW_FORM_ENCODED:
  30. params.update({'data': payload})
  31. prepared_request = requests.Request(**params).prepare()
  32. if webhook.secret != '':
  33. # sign the request with the secret
  34. hmac_prep = hmac.new(bytearray(webhook.secret, 'utf8'), prepared_request.body, digestmod=hashlib.sha512)
  35. prepared_request.headers['X-Hook-Signature'] = hmac_prep.hexdigest()
  36. with requests.Session() as session:
  37. session.verify = webhook.ssl_verification
  38. response = session.send(prepared_request)
  39. if response.status_code >= 200 and response.status_code <= 299:
  40. return 'Status {} returned, webhook successfully processed.'.format(response.status_code)
  41. else:
  42. raise requests.exceptions.RequestException(
  43. "Status {} returned, webhook FAILED to process.".format(response.status_code)
  44. )