Invalid payload - Slack API JSON - json

I am using a Groovy script to send a POST using the Slack API, at present I am getting invalid_payload returned and I think this is most likely due to the formatting of my JSON. I know the Slack API expects it JSON with double quotes but I can't seem to be able to pass a variable into the JSON object:
SUCCESS_MESSAGE = '{"attachments": [{"color": "#2A9B3A", "author_name": ${DEV_NAME}, "title": "Build Status", "title_link": ${BUILD_URL}, "text": "Successful Build" }]}'
def response = ["curl", "-X", "POST", "-H", "Content-Type: application/json", "-d", "${SUCCESS_MESSAGE}", "https://hooks.slack.com/services/${SLACK_WEBHOOK}"].execute().text
How should I correctly format my SUCCESS_MESSAGE var so I don't get the error?

You need to quote your DEV_NAME and BUILD_URL variable expansions so the JSON string is valid.
Your whole string needs to be enclosed in " instead of ' so the variables are actually expanded
And you need to escape the " inside your string so they appear in your JSON string.
SUCCESS_MESSAGE = "{\"attachments\": [{\"color\": \"#2A9B3A\", \"author_name\": \"${DEV_NAME}\", \"title\": \"Build Status\", \"title_link\": \"${BUILD_URL}\", \"text\": \"Successful Build\" }]}"`
Alternatively you can generate the JSON in much nicer programmatic way. Which would be helpful if your notifications got a bit more complicated:
def notification = [
attachments: [
[
color: "#2A9B3A",
author_name: DEV_NAME,
title: "Build Status",
title_link: BUILD_URL,
text: "Successful Build"
]
]
]
def response = ["curl", "-X", "POST", "-H", "Content-Type: application/json", "-d", JsonOutput.toJson(notification), "https://hooks.slack.com/services/${SLACK_WEBHOOK}"].execute().text

Related

Perl LWP::UserAgent parse response JSON

I am using the LWP::UserAgent module to issue a GET request to one of our APIs.
#!/usr/bin/perl
use strict;
use warning;
use LWP::UserAgent;
use Data::Dumper;
my $ua = LWP::UserAgent->new;
my $request = $ua->get("http://example.com/foo", Authorization => "Bearer abc123", Accept => "application/json" );
print Dumper $request->content;
The request is successful. Dumper returns the following JSON.
$VAR1 = '{
"apiVersion": "v1",
"data": {
"ca-bundle.crt": "-----BEGIN CERTIFICATE-----abc123-----END CERTIFICATE-----\\n"
},
"kind": "ConfigMap",
"metadata": {
"creationTimestamp": "2021-07-16T17:13:01Z",
"labels": {
"auth.openshift.io/managed-certificate-type": "ca-bundle"
},
"managedFields": [
{
"apiVersion": "v1",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:data": {
".": {},
"f:ca-bundle.crt": {}
},
"f:metadata": {
"f:labels": {
".": {},
"f:auth.openshift.io/managed-certificate-type": {}
}
}
},
"manager": "cluster-kube-apiserver-operator",
"operation": "Update",
"time": "2021-09-14T17:07:39Z"
}
],
"name": "kube-control-plane-signer-ca",
"namespace": "openshift-kube-apiserver-operator",
"resourceVersion": "65461225",
"selfLink": "/api/v1/namespaces/openshift-kube-apiserver-operator/configmaps/kube-control-plane-signer-ca",
"uid": "f9aea067-1234-5678-9101-9d4073f5ae53"
}
}';
Let's say I want to print the value of the apiVersion key, which should print v1.
print "API Version = $request->content->{'apiVersion'} \n";
The following is being printed. I am not sure how to print the value v1. Since HTTP::Response is included in the output, I suspect I might have to use the HTTP::Response module?
API Version = HTTP::Response=HASH(0x2dffe80)->content->{'apiVersion'}
Perl doesn't expand subroutine calls in a double-quoted string.
print "API Version = $request->content->{'apiVersion'} \n";
In this line of code, content() is a subroutine call. So Perl sees this as:
print "API Version = $request" . "->content->{'apiVersion'} \n";
And if you try to print most Perl objects, you'll get the hash reference along with the name of the class - hence HTTP::Response=HASH(0x2dffe80).
You might think that you just need to break up your print() statement like this:
print 'API Version = ', $request->content->{'apiVersion'}, "\n";
But that's not going to work either. $request->content doesn't return a Perl data structure, it returns a JSON-encoded string. You need to decode it into a data structure before you can access the individual elements.
use JSON;
print 'API Version = ', decode_json($request->content)->{'apiVersion'}, "\n";
But it might be cleaner to do the decoding outside of the print() statement.
use JSON;
my $data = decode_json($request->content);
In which case you can go back to something more like your original code:
print "API Version = $data->{'apiVersion'} \n";
The JSON content must be decoded first. There are several modules for that, like JSON:
use JSON;
# ...
my $href = decode_json $request->content;
And then use it like a normal hash reference: $href->{apiVersion}

Powershell Nested Json doesn't look like a Json

I am currently trying to prepare a JSON body for an API call, which should look something like this
curl -XPOST -H 'Authorization: Bearer ***API*KEY***' -H 'Content-Type: application/json' http://127.0.0.1:9000/api/alert -d '{
"title": "Other alert",
"description": "alert description",
"type": "external",
"source": "instance1",
"sourceRef": "alert-ref",
"severity": 3,
"tlp": 3,
"artifacts": [
{ "dataType": "ip", "data": "127.0.0.1", "message": "localhost" },
{ "dataType": "domain", "data": "thehive-project.org", "tags": ["home", "TheHive"] },
],
"caseTemplate": "external-alert"
}'
The problem however is that my json body which I create with powershell has weird characters and don't see where the problem is. This is my JSON Body
{
"tlp": 1,
"source": "Test",
"title": "Test Alert1",
"artifacts": "{\r\n \"dataType\": \"ip\",\r\n \"data\": \"127.0.0.1\"\r\n}",
"type": "external",
"sourceRef": "1",
"description": "Test",
"severity": 1
}
I create this JSON body as follows. I have already tried CustomObjects and Hashtables, but always get the same output
$body = #{
title = "$title"
description = "$Alert_Description"
type ="external"
source ="$Source"
sourceRef ="$SourceRef"
severity = $Severity
tlp = $tlp
$artifacts = [PSCustomObject]#{
dataType=ip
data=127.0.0.1}
}| ConvertTo-Json
$JsonBody = $body | ConvertTo-Json
Can somebody give me a hint? I have no clue anymore
First, fix your hashtable so that it creates the intended JSON representation, and only apply ConvertTo-Json once:
$body = [ordered] #{
title = $title
description = $Alert_Description
type = 'external'
source = $Source
sourceRef = $SourceRef
severity = $Severity
tlp = $tlp
artifacts = , [pscustomobject] #{
dataType = 'ip'
data = '127.0.0.1'
}
} | ConvertTo-Json
Variables don't need enclosing in "..." unless you explicitly want to convert their values to strings.
Literal textual information such as ip does require quoting ('...', i.e. a verbatim string literal, is best).
The artifacts property is an array in your sample JSON, so the unary form of ,, the array constructor operator is used to wrap the [pscustomobject] instance in a single-element array.
If you have multiple objects, place , between them; if the array was constructed previously and stored in a variable named, say, $arr, use artifacts = $arr.
Use of [ordered], i.e. the creation of an ordered hashtable isn't strictly necessary, but makes it easier to compare the resulting JSON representation to the input hashtable.
Generally keep in mind that explicit use of a -Depth argument with ConvertTo-Json is situationally required in order to ensure that properties aren't truncated - see this post for more information. However, with the hashtable in your question this happens not to be a problem.
Second, since you're sending the json to an external program, curl (note that in Windows PowerShell you'd have to use curl.exe in order to bypass the built-in curl alias for Invoke-WebRequest, an additional escaping step is - unfortunately - required up to at least v7.1 - though that may change in v7.2: The " instances embedded in the value of $body must manually be escaped as \", due to a long-standing bug in PowerShell:
curl -XPOST -H 'Authorization: Bearer ***API*KEY***' -H 'Content-Type: application/json' `
http://127.0.0.1:9000/api/alert -d ($body -replace '([\\]*)"', '$1$1\"')
Note: With your particular sample JSON, -replace '"', '\"' would do.
See this answer for more information.
Slap a "-Depth 50" on your ConvertTo-Json, that should solve your issue.
Like here: ConvertTo-Json flattens arrays over 3 levels deep

Ansible win_shell with JSON to powershell, works fine other way

I can not get how to get win_shell to send JSON to a powershell script on a windows server. If I run this:
vm:
annotation: This is a VM
cdrom:
type: client
iso_path: ''
controller_type: ''
state: ''
cluster: ''
- name: "Run script '.ps1'"
win_shell: D:\scripts\outputValues.ps1 -vm "{{vm}}"
register: result
- name: Process win_shell output
set_fact:
fullResult: "{{ result.stdout | from_json }}"
I get this string into powershell that I can not even convert TO JSON:
{u'cdrom': {u'controller_type': u'', u'state': u'', u'type': u'client', u'iso_path': u''}, u'cluster': u'', u'annotation': u'This is a VM'}
If I run the script with this:
win_shell: D:\scripts\outputValues.ps1 -vm "{{vm | to_json}}"
All I get is an open curly bracket '{' into powershell.
It does work the other way. As a test, if I call that same powershell script from win_shell and ignore the input in powershell and simply create an object like this and send it back to ansible, it works fine. Why can I send JSON one way and not the other? I have tried vm|to_json etc.
#Powershell
$vmAttribs = #{"type" = "client"; "iso_path" = ""; "controller_type" =""; "state" =""}
$vmObject = New-Object psobject -Property #{
annotation = 'This is a VM'
cdrom = $vmAttribs
cluster = ""
}
$result = $vmObject | ConvertTo-Json -Depth 8
Write-Output $result
ansible gets:
{
"msg": {
"cdrom": {
"controller_type": "",
"state": "",
"type": "client",
"iso_path": ""
},
"cluster": "",
"annotation": "This is a VM"
},
"changed": false,
"_ansible_verbose_always": true,
"_ansible_no_log": false
}
What you're seeing is a Python structure signifying JSON notation with Unicode strings (e.g. u'my string value'). Obviously, that's not exactly portable to other runtimes like Powershell, and results in an invalid string.
Reading up on Ansible filters, you will want to use {{ vm | to_json }} to ensure that the data structure is stringified to JSON correctly.
Workaround
I want to stress that this is not the ideal way of getting a JSON object out of Ansible, and a proper solution that doesn't involve hacking out the Unicode identifier from the JSON string is desirable to this.
I don't know enough about Ansible to know why the string becomes { when piping vm to to_json, but here's a workaround that might get you going until someone else can chime in with what is going on with Ansible's filtering here.
In your .ps1 script, you can use the following -replace to remove those u characters before the strings:
$vm = $vm -replace "u(?=([`"']).*\1)"
You can test this by running the following in an interactive terminal:
"{u'cdrom': {u'controller_type': u'', u'state': u'', u'type': u'client', u'iso_path': u''}, u'cluster': u'', u'annotation': u'This is a VM'}" -replace "u(?=([`"']).*\1)"
The pattern matches on the u character that comes immediately before a single-quote or double-quote followed by any number of characters (including none) followed by another single-quote or double quote, whichever was matched the first time. -replace does not require a second argument if you are replacing the pattern with an empty string.

RabbitMQ REST HTTP JSON payload

I am trying to use RabbitMQ HTTP REST client to publish messages into the queue. I am using the following url and request
http://xxxx/api/exchanges/xxxx/exc.notif/publish
{
"routing_key":"routing.key",
"payload":{
},
"payload_encoding":"string",
"properties":{
"headers":{
"notif_d":"TEST",
"notif_k": ["example1", "example2"],
"userModTime":"timestamp"
}
}
}
And getting back from the rabbit the following response:
{"error":"bad_request","reason":"payload_not_string"}
I have just one header set:
Content-Type:application/json
I was trying to set the
"payload_encoding":"base64",
but it didn't help. I am new to rabbit any response is welcome.
Try with
{
"properties": {
"content-type": "application/json"
},
"routing_key": "testKey",
"payload": "1234",
"payload_encoding": "string"
}
Working example. We need simple to escape doublequotes.
It is important that the colon is outside of the quotes, as this causes inexplicable errors.
{
"properties": {},
"routing_key": "q_testing",
"payload": "{
\"message\": \"message from terminal\"
}",
"payload_encoding": "string"
}
I managed to send content-type using underscore "_" instead of dash.
See here for list of valid properties.
See RabbitMQ Management HTTP API for some examples.
To publish a json message using curl to rabbit exchange:
curl -i -u guest:guest -XPOST --data '{"properties":\
{"content_type":"application/json"}, \
"routing_key":"", \
"payload":"{\"foo\":\"bar\"}",\
"payload_encoding":"string"}' \
"http://localhost:15672/api/exchanges/%2f/exchange_name/publish"
content_type is written using underscore, routing_key is empty to send a message to exchange, not to particular queue.
To use a JSON formatted payload you have to encode it in base64 and use the "payload_encoding": "base64" attribute.

wso2 Could not save JSON payload. Invalid input stream found

This is my very first REST API in WSO2, the sequence in wso2 as below.
<? xml version = "1.0" encoding = "UTF-8" ?>
< api xmlns = "http://ws.apache.org/ns/synapse"
name = "createIssue"
context = "/rest"
hostname = "XXX"
port = "XXX" >
< resource methods = "POST"
inSequence = "createInSequence"
`enter code here`
outSequence = "createOutSequence" >
< faultSequence / >
< /resource>
</api >
<? xml version = "1.0"
encoding = "UTF-8" ?>
< sequence xmlns = "http://ws.apache.org/ns/synapse"
name = "createInSequence" >
< log level = "custom" >
< property name = "location"
expression = "json-eval($.fields)" / >
< /log>
</sequence >
The curl command that I am making to invoke the api, is as below.
'curl -X POST -H "Content-Type:application/json" -d#"h:\createissue_own.json" "http://ip:port/rest/api/createissue"'
WSo2 esb Console shows the following error
newJsonPayload. Could not save JSON payload. Invalid input stream found.'
The input json, is a valid json, which I have validated and given below.
{
"fields": {
"project": {
"id": "10301"
},
"summary": "Issue",
"description": "Description text",
"issuetype": {
"id": "10205"
},
"customfield_10600": {
"id": "10300"
},
"customfield_10602": {
"id": "10301"
},
"customfield_10603": "ID text",
"customfield_10608": {
"id": "10303"
},
"customfield_10609": " text",
"customfield_10610": " text",
"customfield_10611": " text",
"customfield_10612": "Postcode text"
}
}
Any suggestions please. I am not able to hit the url, and log the input json.
This error usually comes when you send XML payload with application/json Content-Type header to the ESB. The best thing we can do here is enable the wirelogs and check the HTTP headers and payloads sent to the ESB. To enable wirelogs follow these steps,
Shutdown the ESB instance
Move onto the $ESB_HOME/repository/conf directory and locate the
log4j.properties file Then uncomment the following line
log4j.logger.org.apache.synapse.transport.http.wire=DEBUG
Then restart the ESB instance again and send a request
Monitor the ESB console for wirelogs as follows
The symbol '>>' gives the contents written into the ESB and '<<' gives the contents written out of the ESB.
Also I doubt your curl command, hence a sample curl command is given below.
curl -v -d #test.json -H "Content-Type:application/json" http://localhost:8280/rest/api/createissue