Why always getting bad request fcm? - firebase-cloud-messaging

I am trying to send a notification to the android client from FCM using rest API. My code is: ```
post_offline_message(From, To, Body) ->
K = "FCM key",
U = "https://fcm.googleapis.com/fcm/send",
P = #{
payload => #{
to => <<"rid">>,
priority => <<"high">>,
data => #{
<<"title">> => <<"Some Title">>,
<<"message">> => <<"Hi">>
}
}
},
EP = jiffy:encode(P),
?INFO_MSG("EP data: ~p", [EP]),
httpc:set_options([{keep_alive_timeout, 0}]),
{_, Resp} = httpc:request(post, {U, [{"Authorization", "key=" ++ K}], "application/json", EP}, [], []),
?INFO_MSG("FCM response: ~p", [Resp]).
My EP data (payload) is this:
**<<"{\"payload\":{\"to\":\"dOqZOggYQZG6xKVY9P4_Xi:APA91bG0kuM-o_lSf3fUaWcyiW0fVj8-L49QgzU6rWfxi3o5lMaKapkOjvvLUxm-e78XS49TVl5jjgQt6DrRKTaDK2xzg-ffm1Qe4Xx-61_Hrmr6I0cPOcGAZ9Wv7QgFFjGXtWwWEvSi\",\"priority\":\"high\",\"data\":{\"title\":\"Some Title\",\"message\":\"Hi\"}}}">>**
and response from FCM is:
**{{"HTTP/1.1",400,"Bad Request"},[{"cache-control","private, max-age=0"},{"date","Thu, 03 Sep 2020 08:57:56 GMT"},{"accept-ranges","none"},{"server","GSE"},{"vary","Accept-Encoding"},{"content-length","3"},{"content-type","text/plain; charset=UTF-8"},{"expires","Thu, 03 Sep 2020 08:57:56 GMT"},{"x-content-type-options","nosniff"},{"x-frame-options","SAMEORIGIN"},{"content-security-policy","frame-ancestors 'self'"},{"x-xss-protection","1; mode=block"},{"alt-svc","h3-29=\":443\"; ma=2592000,h3-27=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""}],"to\n"}**
Please suggest what I am doing wrong or missing something. I am calling this method from ejabberd hook which is **offline_message_hook**.

After spending 4 hours I found my mistake. I just remove the payload tag from the request and it worked for me. My updated request is:
post_offline_message(From, To, Body) ->
K = "FCM key",
U = "https://fcm.googleapis.com/fcm/send",
P = #{
to => <<"rid">>,
priority => <<"high">>,
data => #{
<<"title">> => <<"Some Title">>,
<<"message">> => <<"Hi">>
}
},
EP = jiffy:encode(P),
?INFO_MSG("EP data: ~p", [EP]),
httpc:set_options([{keep_alive_timeout, 0}]),
{_, Resp} = httpc:request(post, {U, [{"Authorization", "key=" ++ K}], "application/json", EP}, [], []),
?INFO_MSG("FCM response: ~p", [Resp]).

Related

I can't send email with pdf using Amazon SDK JS, but send txt works fine?

I'm trying to build a function to send email with pdf, I need to read the file from other server and then attach it to the email.
I have test it with txt and it works fine, but when I use pdf, it attach a file that cannot be open.
That's my code until now:
let dados = {
"para": "::EMAIL::",
"body": "Olá",
"assunto": "Teste",
"from": "::EMAIL::",
"anexo": "teste.pdf" // Name of the file I want to read from server
};
request.get("::URL_SERVER::" + dados.anexo, function (error, response, body) {
let anexo;
if (!error && response.statusCode == 200) {
anexo = body;
}
let ses_mail =
`From: 'AWS SES Attchament Configuration' <${dados.from}>
To: <${dados.para}>
Subject: ${dados.assunto}
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="NextPart"
--NextPart
Content-Type: text/html
${dados.body}
--NextPart
Content-Type: application/pdf; name="${dados.anexo}"
Content-Transfer-Encoding: base64
Content-Disposition:attachment
${anexo.toString("base64").replace(/([^\0]{76})/g, "$1\n")}
--NextPart`;
let params = {
RawMessage: {Data: ses_mail},
Source: `'AWS SES Attchament Configuration' <${dados.from}>`
};
let sendPromise = new AWS.SES({apiVersion: '2010-12-01'}).sendRawEmail(params).promise();
return sendPromise.then(
data => {
console.log(data);
return data;
}).catch(
err => {
console.error(err.message);
throw err;
});
});
It is possible to do it with axios? I only found how to download file on my research
I could do it, but I needed to change the lib I was using to sync-request.
My final code:
let anexo = null;
try {
anexo = request( "GET", "::URL::" + dados.anexo );
} catch (err) {
console.error(err, err.stack);
return criarResposta( 404, 'Anexo não encontrado' );
}
anexo = anexo.getBody();
//return criarResposta( 200, anexo.toString("base64") );
let ses_mail =
`From: 'AWS SES Attchament Configuration' <${dados.from}>
To: <${dados.para}>
Subject: ${dados.assunto}
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="NextPart"
--NextPart
Content-Type: text/html
${dados.body}
--NextPart
Content-Type: application/octet; name="arquivo.pdf"
Content-Transfer-Encoding: base64
Content-Disposition:attachment
${anexo.toString("base64")}
--NextPart`;
let params = {
RawMessage: {Data: ses_mail},
Source: `'AWS SES Attchament Configuration' <${dados.from}>`
};
sendPromise = new AWS.SES({apiVersion: '2010-12-01'}).sendRawEmail(params).promise();
try {
const data = await sendPromise;
console.log(data.MessageId);
return criarResposta( 200, 'OK' );
} catch (err) {
console.error(err, err.stack);
return criarResposta( 500, 'Erro interno' );
}

How can I get data from Bitfinex authenticated api endpoints using Google sheets?

Using Google sheets, I have stored my api_key and api_secret in the Property service section of user info as respectively "api_key" and api_secret".
I want to get wallet info from my account. The code I have written is as follows:
function wallet() {
var api_key = PropertiesService.getScriptProperties().getProperty('api_key');
var api_secret = PropertiesService.getScriptProperties().getProperty('api_secret');
var response = UrlFetchApp.fetch("https://api.bitfinex.com/v2/auth/r/wallets", api_key, api_secret);
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheet");
var result = JSON.parse(response.getContentText());
var wallet_btc = result.BALANCE
}
When I run in debug mode the error message is:
Cannot find method fetch(string,null,null). (line 13, file "Code")
Is this approach wrong, the code wrong, or both?
Many thanks.
How about the following modifications?
Modification points :
The parameters for UrlFetchApp.fetch() are UrlFetchApp.fetch(url, params). And params is an object.
This is the reason of error Cannot find method fetch(string,null,null). (line 13, file "Code").
When I saw the sample scripts for Bitfinex API, the request body has to be created using api_key, api_secret, nonce, body and signature. And signature is encrypted by HMAC_SHA_384 and converted to the string of the unsigned hexadecimal.
The sample for the endpoint of https://api.bitfinex.com/v2/auth/r/wallets is as follows. This is from API reference.
Sample for the endpoint of https://api.bitfinex.com/v2/auth/r/wallets
request.post(
`${url}/auth/r/wallets`,
headers: { /* auth headers */ },
body: {},
json: true,
(error, response, body) => console.log(body)
)
When above points are reflected to your script, the modified script is as follows.
Modified script :
function wallet() {
var api_key = PropertiesService.getScriptProperties().getProperty('api_key');
var api_secret = PropertiesService.getScriptProperties().getProperty('api_secret');
var apiPath = "v2/auth/r/wallets";
var nonce = Date.now().toString();
var body = {};
var rawBody = JSON.stringify(body);
var signature = "/api/" + apiPath + nonce + rawBody;
signature = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_384, signature, api_secret)
.map(function(e) {
var v = (e < 0 ? e + 256 : e).toString(16);
return v.length == 1 ? "0" + v : v;
}).join("");
var url = "https://api.bitfinex.com/" + apiPath;
var options = {
method: 'POST',
contentType: "application/json",
headers: {
'bfx-nonce': nonce,
'bfx-apikey': api_key,
'bfx-signature': signature
},
payload: rawBody
};
var response = UrlFetchApp.fetch(url, options);
var result = JSON.parse(response.getContentText());
Logger.log(result)
// var wallet_btc = result.BALANCE // I couldn't confirm whether this key exists.
}
References :
Sample scripts for Bitfinex API
API reference
UrlFetchApp.fetch()
I cannot confirm whether this works. If this didn't work, can you tell me the situation? I would like to modify.
Edit :
When you want 0.0957596 from the result of [["exchange", "USD", 14.81076629, 0, null], ["exchange", "BTC", 0.0957596, 0, null], ["funding", "BTC", 4.13E-6, 0, null], ["funding", "ETH", 3.50186961, 0, null], ["exchange", "OMG", 5.9E-7, 0, null]];, you can use the following script.
Script :
function wallet() {
var api_key = PropertiesService.getScriptProperties().getProperty('api_key');
var api_secret = PropertiesService.getScriptProperties().getProperty('api_secret');
var apiPath = "v2/auth/r/wallets";
var nonce = Date.now().toString();
var body = {};
var rawBody = JSON.stringify(body);
var signature = "/api/" + apiPath + nonce + rawBody;
signature = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_384, signature, api_secret)
.map(function(e) {
var v = (e < 0 ? e + 256 : e).toString(16);
return v.length == 1 ? "0" + v : v;
}).join("");
var url = "https://api.bitfinex.com/" + apiPath;
var options = {
method: 'POST',
contentType: "application/json",
headers: {
'bfx-nonce': nonce,
'bfx-apikey': api_key,
'bfx-signature': signature
},
payload: rawBody
};
var response = UrlFetchApp.fetch(url, options);
var result = JSON.parse(response.getContentText());
// Logger.log(result)
// var wallet_btc = result.BALANCE // I couldn't confirm whether this key exists.
var balance = 0;
for (var i in result) {
if (result[i][0] == "exchange" && result[i][1] == "BTC") {
balance = result[i][2];
break;
}
}
Logger.log(balance)
}
Note :
From the document, it seems that the indexes of WALLET_TYPE, CURRENCY and BALANCE are always 0, 1 and 2 of each element in the response, respectively.

Contentful content-management (node lib) : entry won't update

Title says all. I think I've tried all possible combinations but none of them seem to work.
What am I doing wrong ?
First :
client.getSpace('<SPACEID>')
.then((space) => {
space.updateEntry({
"sys": {
id: "<ENTRYID>",
version:45
},
"fields": {
"job": {
"fr-FR": "blablabla"
}
}
})
})
=> Unhandled promise rejection TypeError: space.updateEntry is not a function
Second :
client.getSpace('<SPACEID>')
.then((space) => {
space.getEntry(<ENTRYID>)
.then((entry) => {
var ver = entry.sys.version
var id = entry.sys.id
entry = {
"sys":{
id: id,
version:ver
},
"fields": {
"job": {
"fr-FR": "blablabla"
}
}
}
entry.update()
})
})
=> got entry.update() is not a function
Third :
.then((space) => {
space.getEntry(entryId)
.then((entry) => {
entry.fields.job = {"fr-FR": "blabla"}
entry.update()
})
})
=> got Exception '-[__NSCFNumber length]: unrecognized selector sent to instance 0xb0000000000002d3'
Fourth :
entry.fields.job['fr-FR'] = 'blabla'
=> same exception
ExceptionsManager.js:78 Exception '-[__NSCFNumber length]: unrecognized selector sent to instance 0xb000000000000013' was thrown while invoking sendRequest on target RCTNetworking with params (
{
data = {
string = "{\"fields\":{\"fireid\":{\"fr-FR\":\"bla\"},\"commission\":{\"fr-FR\":\"bla\"},\"dep\":{\"fr-FR\":\"bla\"},\"desc\":{\"fr-FR\":\"bla\"},\"email\":{\"fr-FR\":\"thp#ggg.com\"},\"firstname\":{\"fr-FR\":\"firstname\"},\"job\":{\"fr-FR\":\"blabla\"},\"name\":{\"fr-FR\":\"name\"},\"tel\":{\"fr-FR\":\"0675234573\"},\"type\":{\"fr-FR\":\"Collaborateur\"}}}";
trackingName = unknown;
};
headers = {
accept = "application/json, text/plain, */*";
authorization = "Bearer TOKEN";
"content-type" = "application/vnd.contentful.management.v1+json";
"x-contentful-user-agent" = "contentful-management.js/1.3.1";
"x-contentful-version" = 1;
};
incrementalUpdates = 0;
method = PUT;
responseType = text;
timeout = 0;
url = "https://api.contentful.com:443/spaces/<SPACEID>/entries/<ENTRYID>";
},
139
)
to update an entry you can do the following :
First, you need the entry object either, you create it or get and entry by id :
// You can get an Entry object by
// 1. Creating one
var myEntry
space.createEntry({}).then((entry) => {myEntry = entry})
// 2. Get an existing one
space.getEntry('ENTRY_ID').then((entry) => {myEntry = entry})
// to Update an entry you can do the following
entry.fields.name['en-US'] = 'Blog Post'
entry.update()
.then(entry => console.log(entry.fields.name['en-US']))
again it depends on the fields of your entry, you might not need to do [en-US] if you don't have localized content

Swift - 8tracks.com API POST json data fails (422) everytime

I'm trying to talk with 8tracks open API in Swift iOS app. I need to make POST authorization request to http://8tracks.com/sessions.jsonwith AFNetworking but everytime I get 422 Unprocessable Entity error..
I tried this endpoint on the web and it works fine. Here is code that I'm using (subclassing AFHTTPSessionManager):
init() {
super.init()
self.responseSerializer = AFJSONResponseSerializer()
self.requestSerializer = AFJSONRequestSerializer()
self.requestSerializer.setValue(API_KEY, forHTTPHeaderField: "X-Api-Key")
self.requestSerializer.setValue("3", forHTTPHeaderField: "X-Api-Version")
}
func login(username: String, password: String, success: (NSURLSessionDataTask!, AnyObject!) -> Void, failure: ((NSURLSessionDataTask!, NSError!) -> Void)?) {
let credentials = ["username": username, "password": password] as Dictionary
self.POST(
API_URL.stringByAppendingString("/sessions.json"),
parameters: credentials,
success: success,
failure: failure
)
}
Error looks as follows:
{ URL: http://8tracks.com/sessions.json } { status code: 422, headers {
"Accept-Ranges" = bytes;
"Access-Control-Allow-Origin" = "*";
Age = 0;
"Cache-Control" = "max-age=0, private, must-revalidate";
Connection = "keep-alive";
"Content-Length" = 125;
"Content-Type" = "application/json; charset=utf-8";
Date = "Wed, 25 Jun 2014 19:29:12 GMT";
Server = "nginx/1.4.3";
Status = "422 Unprocessable Entity";
Via = "1.1 varnish";
"X-Action" = "sessions/create";
"X-Backend" = rails;
"X-Cache" = MISS;
"X-Data-Request" = 1;
"X-Request-Id" = 3040c8bf79936b27075731f634bfd534;
"X-Requests-Left" = 99;
"X-Runtime" = "0.257240";
"X-UA-Compatible" = "IE=Edge,chrome=1";
} }, NSLocalizedDescription=Request failed: client error (422),
NSErrorFailingURLKey=http://8tracks.com/sessions.json}
It might have something to do with subclass AFHTTPSessionManager without a baseURL. I've tested the following code and it works.
let path = "/sessions.json"
let params = ["login": login, "password": password, "api_version": "3"]
let success = {(task: NSURLSessionDataTask!, response: AnyObject!) -> Void in
println(response)
}
let failure = {(task: NSURLSessionDataTask!, error: NSError!) -> Void in
println(error)
}
var client = AFHTTPSessionManager(baseURL: NSURL(string: "https://8tracks.com"))
client.POST(path, parameters: params, success: success, failure: failure)

Google Apps Script Basecamp POST

I've tried all the combinations I can think of to make this work. What do I need to send to the New Basecamp API as a POST field to have it accept my POST data?
My code is:
function getFilterBy() {
var url = "https://basecamp.com/****/api/v1/projects/*****.json";
var payload = {"name" : "myapp", "description" : "no desc mls"};
var opt = {
"contentType" : "application/json",
"method" : "POST",
"headers":{ "User-Agent": "myapp (user#somewhere.com)",
"Authorization" :"Basic " + Utilities.base64Encode("user" + ":" + "pass")},
"validateHttpsCertificates" :false,
"muteHttpExceptions" : true,
"payload" : payload
};
var response = UrlFetchApp.fetch(url, opt);
var text = response.getContentText();
Logger.log(text);
}
My Error is:
lexical error: invalid char in json text.
description=no+desc+mls&name=Ho
(right here) ------^
I have tried to Utilities.jsonStringify, but no luck. I know its a noob error, but I just can't figure it out. If there is a place you are aware of where I can get this info too that would be phenomenal.
Thanks!
UPDATE 1
function getFilterBy() {
var url = "https://basecamp.com/****/api/v1/projects/****.json";
var payload = {name : 'myApp Change'};
var opt = {
"contentType" : "application/json",
"method" : "POST",
"headers":{ "User-Agent": "myApp (user#ex.com)",
"Authorization" :"Basic " + Utilities.base64Encode("user" + ":" + "pass")},
"validateHttpsCertificates" :false,
"muteHttpExceptions" : true,
"payload" : Utilities.jsonStringify(payload)
};
var response = UrlFetchApp.fetch(url, opt);
var text = response.getContentText();
Logger.log(text);
}
Yields Err:
<body>
<div class="dialog">
<div class="innercol">
<h1>Hmm, that isn’t right</h1>
<h2>You may have typed the URL incorrectly.</h2>
<p>Check to make sure you’ve got the spelling, capitalization, etc. exactly right.</p>
</div>
</div>
<p id="back" class="back">
← Back to previous page
</p>
<script type="text/javascript">
if (window.history.length <= 1) document.getElementById("back").style.display = "none";
</script>
</body>
Are you sure you tried with JSON.stringify correctly? This example here correctly creates a project for me in Basecamp with the specifified project name/description in the POST payload.
Note, I wrote this quickly to not include the UserAgent - you'll want to put that back in.
function createProject() {
var user = 'USERNAME';
var password = 'PASSWORD'
var accoundId = 'ACCOUNTID#';
var url = 'https://basecamp.com/'+accoundId+'/api/v1/projects.json';
var payload = {name : 'new project', description : 'my project description'};
var opt = {
contentType : 'application/json',
method : 'post',
headers:{Authorization :"Basic " + Utilities.base64Encode(user + ':' + password)},
validateHttpsCertificates :false,
muteHttpExceptions : true,
payload : JSON.stringify(payload)
};
var response = UrlFetchApp.fetch(url, opt);
var text = response.getContentText();
Logger.log(text);
}
In order to update a project, you have to use the put verb instead of post as documented here
Here is a working sample -
function updateProject() {
var projectId = '2413370';
var url = 'https://basecamp.com/'+accoundId+'/api/v1/projects/'+projectId+'.json';
var payload = {name : 'new project', description : 'my new new project description'};
var opt = {
contentType : 'application/json',
method : 'put',
headers:{Authorization :"Basic " + Utilities.base64Encode(user + ':' + password)},
validateHttpsCertificates :false,
muteHttpExceptions : true,
payload : JSON.stringify(payload)
};
var response = UrlFetchApp.fetch(url, opt);
var text = response.getContentText();
Logger.log(text);
}