Skip to content

Commit

Permalink
Added http_method & content_type settings
Browse files Browse the repository at this point in the history
Added http_method & content_type settings to allow further configuration.
  • Loading branch information
2blane committed May 3, 2020
1 parent 26979f6 commit 9a19d3a
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 9 deletions.
69 changes: 60 additions & 9 deletions octoprint_webhooks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,19 @@ def replace_dict_with_data(d, v):
d[key] = d[key].replace(value[start_index:end_index], v[value_key])
return d

# Checks for the name/value pair to make sure it matches
# and if not sets the name/value and returns
def check_for_header(headers, name, value):
is_set = False
for key in headers:
if name.lower() in key.lower():
is_set = True
if value.lower() not in headers[key].lower():
headers[key] = value
if not is_set:
headers[name] = value
return headers


class WebhooksPlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplatePlugin, octoprint.plugin.SettingsPlugin,
octoprint.plugin.EventHandlerPlugin, octoprint.plugin.AssetPlugin, octoprint.plugin.SimpleApiPlugin):
Expand Down Expand Up @@ -58,10 +71,14 @@ def get_settings_defaults(self):
eventUserActionNeeded=True, eventError=True,
headers='{\n "Content-Type": "application/json"\n}',
data='{\n "deviceIdentifier":"@deviceIdentifier",\n "apiSecret":"@apiSecret",\n "topic":"@topic",\n "message":"@message",\n "extra":"@extra"\n}',
http_method="POST",
content_type="JSON",
oauth=False,
oauth_url="",
oauth_headers='{\n "Content-Type": "application/json"\n}',
oauth_data='{\n "client_id":"myClient",\n "client_secret":"mySecret",\n "grant_type":"client_credentials"\n}',
oauth_http_method="POST",
oauth_content_type="JSON",
test_event="PrintStarted"
)

Expand Down Expand Up @@ -139,9 +156,26 @@ def on_event(self, event, payload):
oauth_headers = json.loads(self._settings.get(["oauth_headers"]))
parsed_oauth_headers = True
oauth_data = json.loads(self._settings.get(["oauth_data"]))
oauth_http_method = self._settings.get(["oauth_http_method"])
oauth_content_type = self._settings.get(["oauth_content_type"])
# 1.2) Send the request
self._logger.info("Sending OAuth Request")
response = requests.post(oauth_url, json=oauth_data, headers=oauth_headers)
response = ""
if oauth_http_method == "GET":
response = requests.get(oauth_url, params=oauth_data, headers=oauth_headers)
else:
if oauth_content_type == "JSON":
# Make sure the Content-Type header is set to application/json
oauth_headers = check_for_header(oauth_headers, "content-type", "application/json")
self._logger.info("oauth headers: " + json.dumps(oauth_headers) + " - data: " + json.dumps(oauth_data))
self._logger.info("oauth_http_method: " + oauth_http_method + " - oauth_content_type: " + oauth_content_type)
response = requests.request(oauth_http_method, oauth_url, json=oauth_data, headers=oauth_headers)
else:
# Make sure the Content-Type header is set to application/x-www-form-urlencoded
oauth_headers = check_for_header(oauth_headers, "content-type", "application/x-www-form-urlencoded")
self._logger.info("oauth headers: " + json.dumps(oauth_headers) + " - data: " + json.dumps(oauth_data))
self._logger.info("oauth_http_method: " + oauth_http_method + " - oauth_content_type: " + oauth_content_type)
response = requests.request(oauth_http_method, oauth_url, data=oauth_data, headers=oauth_headers)
# 1.3) Check to make sure we got a valid response code.
self._logger.info("OAuth Response: " + " - " + response.text)
code = response.status_code
Expand Down Expand Up @@ -178,26 +212,43 @@ def on_event(self, event, payload):
headers = json.loads(self._settings.get(["headers"]))
parsed_headers = True
data = json.loads(self._settings.get(["data"]))
http_method = self._settings.get(["http_method"])
content_type = self._settings.get(["content_type"])
# 2.1) Create a dictionary of all possible replacement variables.
values = {
"topic": topic,
"message": message,
"extra": extra,
"apiSecret": api_secret,
"deviceIdentifier": device_identifier
"deviceIdentifier": device_identifier,
"extra": extra
}
# 2.2) Merge these values with the oauth values.
values.update(oauth_result)
# 2.3) Replace the data and header elements that start with @
data = replace_dict_with_data(data, values)
headers = replace_dict_with_data(headers, values)
# 2.4) Send the request
self._logger.info("headers: " + json.dumps(headers) + " - data: " + json.dumps(data) + " - values: " + json.dumps(values))
response = requests.post(url, json=data, headers=headers)
result = json.loads(response.text)
response = ""
if http_method == "GET":
response = requests.get(url, params=data, headers=headers)
else:
if content_type == "JSON":
# Make sure the Content-Type header is set to application/json
headers = check_for_header(headers, "content-type", "application/json")
self._logger.info("headers: " + json.dumps(headers) + " - data: " + json.dumps(data) + " - values: " + json.dumps(values))
self._logger.info("http_method: " + http_method + " - content_type: " + content_type)
response = requests.request(http_method, url, json=data, headers=headers)
else:
# Make sure the Content-Type header is set to application/x-www-form-urlencoded
headers = check_for_header(headers, "content-type", "application/x-www-form-urlencoded")
self._logger.info("headers: " + json.dumps(headers) + " - data: " + json.dumps(data) + " - values: " + json.dumps(values))
self._logger.info("http_method: " + http_method + " - content_type: " + content_type)
response = requests.request(http_method, url, data=data, headers=headers)
self._logger.info("Response: " + response.text)
# Try to parse the response if possible.
code = response.status_code
if 200 <= code < 400:
self._logger.info("API SUCCESS: " + event + " " + json.dumps(result))
self._logger.info("API SUCCESS: " + event + " " + response.text)
# Optionally show a message of success if the payload has popup=True
if type(payload) is dict and "popup" in payload:
self._plugin_manager.send_plugin_message(self._identifier, dict(type="success", hide=True, msg="Response: " + response.text))
Expand All @@ -208,10 +259,10 @@ def on_event(self, event, payload):
self._logger.info("API ERROR: " + str(e))
except Exception as e:
if parsed_headers:
self._logger.info("JSON Parse DATA Issue" + str(e))
self._logger.info("JSON Parse DATA Issue: " + str(e))
self._plugin_manager.send_plugin_message(self._identifier, dict(type="error", msg="Invalid JSON for Webhooks DATA Setting"))
else:
self._logger.info("JSON Parse HEADERS Issue")
self._logger.info("JSON Parse HEADERS Issue: " + str(e))
self._plugin_manager.send_plugin_message(self._identifier, dict(type="error", msg="Invalid JSON for Webhooks HEADERS Setting"))

def recv_callback(self, comm_instance, line, *args, **kwargs):
Expand Down
53 changes: 53 additions & 0 deletions octoprint_webhooks/templates/webhooks_settings.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,31 @@
This URL will be called whenever one of the enabled events below is triggered.
</div>

<label class="control-label">{{ _('HTTP METHOD') }}</label>
<div class="controls">
<select id="selectHTTPMethod" class="control-select" data-bind="value: settings.settings.plugins.webhooks.http_method">
<option value="POST">POST</option>
<option value="PUT">PUT</option>
<option value="DELETE">DELETE</option>
<option value="GET">GET</option>
</select>
</div>
<div class="control-description">
The type of HTTP request to make.
</div>

<label class="control-label">{{ _('CONTENT TYPE') }}</label>
<div class="controls">
<select id="selectHTTPMethod" class="control-select" data-bind="value: settings.settings.plugins.webhooks.content_type">
<option value="JSON">JSON</option>
<option value="FORM">x-www-form-urlencoded</option>
</select>
</div>
<div class="control-description">
How to encode the data before sending. The header for 'Content-Type' will be overridden if necessary
to support this content type.
</div>

<label class="control-label">{{ _('API SECRET') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: settings.settings.plugins.webhooks.apiSecret">
Expand Down Expand Up @@ -145,6 +170,7 @@
Provide a JSON dictionary of parameters that will be passed along with each request.
</div>


<!-- ----- -->
<!-- ----- -->
<!-- OAUTH -->
Expand Down Expand Up @@ -177,6 +203,33 @@
The URL to your OAuth Endpoint. This will be called first to trade credentials for an access token.
</div>

<!-- OAuth HTTP Method -->
<label class="control-label">{{ _('OAUTH HTTP METHOD') }}</label>
<div class="controls">
<select id="selectHTTPMethod" class="control-select" data-bind="value: settings.settings.plugins.webhooks.oauth_http_method">
<option value="POST">POST</option>
<option value="PUT">PUT</option>
<option value="DELETE">DELETE</option>
<option value="GET">GET</option>
</select>
</div>
<div class="control-description">
The type of HTTP request to make.
</div>

<!-- OAuth HTTP Content Type -->
<label class="control-label">{{ _('OAUTH CONTENT TYPE') }}</label>
<div class="controls">
<select id="selectHTTPMethod" class="control-select" data-bind="value: settings.settings.plugins.webhooks.oauth_content_type">
<option value="JSON">JSON</option>
<option value="FORM">x-www-form-urlencoded</option>
</select>
</div>
<div class="control-description">
How to encode the data before sending. The header for 'Content-Type' will be overridden if necessary
to support this content type.
</div>

<!-- OAuth Headers -->
<label class="control-label">{{ _('OAUTH HEADERS') }}</label>
<div class="controls">
Expand Down

0 comments on commit 9a19d3a

Please sign in to comment.