api response contains escape characters - node.js

I am getting value from API response as below
{
"ORG_ID":"165",
"DEPOT_NAME":"Pesto",
"DEPOT_SHORT_NAME":"PSD",
"PROD_ID":"709492",
"DESCRIPTION":"EX CL (2X14) U17\SH36\5",
"PRICE":"3708.55",
"STOCK":"2"
},
now when I am parsing it in json like json.parse(response) it cashes the app.. error is below:
undefined:11
"DESCRIPTION":"EXELON HGC 4.5MG (2X14) U17\SH36\5",
^
SyntaxError: Unexpected token S in JSON at position 296
What should I do to get rid of these escapes.
though I need the same values I don't want to change any value or remove these slashes.

You need to escape the special characters before parsing the jSON.
In this case for it to be valid it should be:
{
"ORG_ID":"165",
"DEPOT_NAME":"Pesto",
"DEPOT_SHORT_NAME":"PSD",
"PROD_ID":"709492",
"DESCRIPTION":"EX CL (2X14) U17\\SH36\\5",
"PRICE":"3708.55",
"STOCK":"2"
}

Related

Escape character in Groovy to AnsibleTower

During passcode transfer from groovy script to ansible tower plugin, is there any way to send passcode with special character with slash "<passcode>"
ansibleTower(async: false, credential: 'test_cred', extraVars: """
---
password: "U*gLO8br1dMJ\y!U"
"""
While passing a special character it is not able to read the passcode. Is there any regular expression to send this special character
Unable to request job template invocation Extra vars are bad: ["Cannot parse as JSON (error: Expecting value: line 2 column 1 (char 1)) or YAML (error: while scanning a double-quoted scalar\n in \"<unicode string>\", line 4, column 16:\n sudo_password: \"U*gLO8br1dMJ\\y!U\"\n ^\nfound unknown escape character 'y'\n in \"<unicode string>\", line 4, column 30:\n sudo_password: \"U*gLO8br1dMJ\\y!U\"\n ^)."]
Adding an extra "\" in the password will suffice to escape the password. Like "U*gLO8br1dMJ\\y!U" will suffice

System.JSONException: Unexpected character ('i' (code 105)): was expecting comma to separate OBJECT entries at [line:1, column:18]

#SalesforceChallenge
I'm trying to escape a string but I had no success so far.
This is the response body I'm getting:
{"text":"this \"is something\" I wrote"}
Please note that there are 2 backslashes to escape the double quotes char. (This is a sample. Actually I have a big to escape with lots of "text" elements.)
When I try to deserialize it I get the following error:
System.JSONException: Unexpected character ('i' (code 105)): was expecting comma to separate OBJECT entries at [line:1, column:18]
I've tried to escape by using:
String my = '{"text":"this \"is something\" I wrote"}';
System.debug('test 0: ' + my);
System.debug('test 1: ' + my.replace('\"', '-'));
System.debug('test 2: ' + my.replace('\\"', '-'));
System.debug('test 3: ' + my.replace('\\\"', '-'));
System.debug('test 4: ' + my.replace('\\\\"', '-'));
--- Results:
[22]|DEBUG|test 0: {"text":"this "is something" I wrote"}
[23]|DEBUG|test 1: {-text-:-this -is something- I wrote-}
[23]|DEBUG|test 1: {-text-:-this -is something- I wrote-}
[24]|DEBUG|test 2: {"text":"this "is something" I wrote"}
[25]|DEBUG|test 3: {"text":"this "is something" I wrote"}
[26]|DEBUG|test 4: {"text":"this "is something" I wrote"}
--- What I need as result:
{"text":"this -is something- I wrote"}
Please, does someone has any fix to share?
Thanks a lot.
This is the problem with your test runs in Anonymous Apex:
String my = '{"text":"this \"is something\" I wrote"}';
Because \ is an escape character, you need two backslashes in an Apex string literal to produce a backslash in the actual output:
String my = '{"text":"this \\"is something\\" I wrote"}';
Since Apex quotes strings with ', you don't have to escape the quotes for Apex; you're escaping them for the JSON parser.
The same principle applies to the strings you're trying to use to do replacements: you must escape the \ for Apex.
All that said, it's unclear why you are trying to manually alter this string. The payload
{"text":"this \"is something\" I wrote"}
is valid JSON. In general, you should not perform string replacement on inbound JSON structures in Apex unless you're attempting to compensate for a payload that contains an Apex reserved word as a key so that you can use typed deserialization.

Emoji is not rendered in the subject of gmail

I am using GMAIL api to send email from the nodejs api. I am rendering the raw body using the following utility function
message += '[DEFAULT EMOJI 😆]'
const str = [
'Content-Type: text/html; charset="UTF-8"\n',
'MIME-Version: 1.0\n',
'Content-Transfer-Encoding: 7bit\n',
'to: ',
to,
'\n',
'from: ',
from.name,
' <',
from.address,
'>',
'\n',
'subject: ',
subject + '[DEFAULT EMOJI 😆]',
'\n\n',
message
].join('');
return Buffer.alloc(str.length, str).toString('base64').replace(/\+/g, '-').replace(/\//g, '_');
The code i have used to send the email is
const r = await gmail.users.messages.send({
auth,
userId: "me",
requestBody: {
raw: makeEmailBody(
thread.send_to,
{
address: user.from_email,
name: user.from_name,
},
campaign.subject,
campaign.template,
thread.id
),
},
});
The emojis are being rendered in the body but not working in subject. See the pic below
Left one is from Gmail in Google Chrome on Desktop and right one is from Gmail App in Mobile
Your utility may benefit from several improvements (we will get to the emoji problem):
First, make it RFC822 compliant by separating lines with CRLF (\r\n).
Be careful with Content-Transfer-Encoding header, set it to 7bit is easiest, but may not be generic enough (quoted-printable is likely the better option).
Now to the emoji problem:
You need to make sure the subject is correctly encoded separately from the body to be able to pass the emoji. According to RFC13420, you can use either Base64 or quoted-printable encoding on a subject to create an encoded-word, described as:
"=" "?" charset "?" encoding "?" encoded-text "?" "="
Where encoding is either Q for quoted-printable and B for Base64 encoding.
Note that the resulting encoded subject string must not be longer than 76 chars in length, which reserves 75 chars for the string and 1 for the separator (to use multiple words, separate them with space or newline [CRLF as well]).
So, set your charset to utf-8, encoding to Q, encode the actual subject with something like below1, and you are half way done:
/**
* #summary RFC 1342 header encoding
* #see {#link https://www.rfc-editor.org/rfc/rfc1342}
*/
class HeaderEncoder {
/**
* #summary encode using Q encoding
*/
static quotedPrintable(str: string, encoding = "utf-8") {
let encoded = "";
for (const char of str) {
const cp = char.codePointAt(0);
encoded += `=${cp.toString(16)}`;
}
return `=?${encoding}?Q?${encoded}?=`;
}
}
Now, the fun part. I was working on a GAS project that had to leverage the Gmail API directly (after all, that is what the client library does under the hood). Even with the correct encoding, an attempt to pass something like a "Beep! \u{1F697}" resulted in an incorrectly parsed subject.
Turns out you need to leverage fromCodePoint operating on byte array or buffer from the original string. This snippet should suffice (don't forget to apply only to multibyte chars):
const escape = (u: string) => String.fromCodePoint(...Buffer.from(u));
0 This is the initial RFC, it would be more appropriate to refer to RFC 2047. Also, see RFC 2231 for including locale info in the header (and some more obscure extensions).
1 If the char falls into a range of printable US-ASCII, it can be left as-is, but due to an extensive set of rules, I recommend sticking to 48-57 (numbers), 65-90 (uppercase) and 97-122 (lowercase) ranges.

Unexpected token ? in JSON at position 0

I'm making a get request in node.js to a url which returns an object i'm trying to parse. However I am getting the unexpected token error. I have played with different encodings as well as converting the response body into string and then removing those tokens but nothing works. Setting encoding to null also did not solve my problem.
Below is the response body im getting:
��[{"unit":"EN15","BOX":"150027","CD":"12 - Natural Gas Leak","Levl":"1","StrName":"1000 N Madison Ave","IncNo":"2020102317","Address":"1036 N Madison Ave","CrossSt":"W 5TH ST/NECHES ST"},{"unit":"EN23","BOX":"230004","CD":"44 - Welfare Check","Levl":"1","StrName":"S Lancaster Rd / E Overton Rd","IncNo":"2020102314","Address":"S Lancaster Rd / E Overton Rd","CrossSt":""}]
Those are the headers which go with my request
headers: {'Content-Type': 'text/plain; charset=utf-8'}
Here is how I'm parsing response body
const data = JSON.parse(response.body)
Any help would be greatly appreciated!
UPDATE: had to do this with response body to make it work
const data = response.body.replace(/^\uFFFD/, '').replace(/^\uFFFD/, '').replace(/\0/g, '')
You are probably getting byte order mark (BOM) of the UTF-8 string.
The simplest workeround would be to remove it before the parsing.
const data = JSON.parse(response.body.toString('utf8').replace(/^\uFFFD/, ''));
Update: Your first 2 characters are Unicode REPLACEMENT CHARACTER. In order to remove it, use the \uFFD character.

Need to pass multiple variables to payload variables

I am trying to pass multiple variables to payload using format & +str(Var)+ but I am not getting the expected output. I have the hostnames in a file & get a password as input and want to pass it to the payload.
I am getting an error related to "Error while parsing JSON payload or an incompatible argument type for the requested resource"
for x in content:
url='https://url/a/b/c/{}'.format(x.strip())
payload=('{{"ip-address": "x.x.x.x","user-name": "john","password": "'+ str(Pass) +'","db-name": "'+ str(x.strip()) +'","service-name": "y","port": "y","connection-string": "y"}}')
response = req.post(url,json=payload,headers=add_cookie,verify=False)
======================
for x in content:
url='https://url/a/b/c/{}'.format(x.strip())
payload={"ip-address": "x.x.x.x","user-name": "john","password": "{}","db-name": "{}","service-name": "y","port": "y","connection-string": "y"}.format(Pass, x.strip())
response = req.post(url,json=payload,headers=add_cookie,verify=False)
In first part your payload is a string and not a dict, it should be
payload={"ip-address": "x.x.x.x","user-name": "john","password": str(Pass),"db-name": str(x.strip()),"service-name": "y","port": "y","connection-string": "y"}
In the second one you're using the format function on a dict type which is wrong.

Resources