Sending Push Notification to Ionic Service on Rails Controller Doesnt send message - ruby-on-rails-4

So i amusing the Ionic Push API to send a notification and while i am receiving the notification, i however do not get the message included in the notification. Yes it is weird and i know that but i dont know why it is happening.
This is my code
params = {
"tokens" => ["DEVICE_TOKEN"],
"profile" => "PROFILE_TAG",
"notification" => {
"title" => "Partners",
"message" => "Hello World!",
"payload" => {
"$state" => "app.settings"
},
"android" => {,
"content_available" => 1,
"sound" => "default",
"forceShow" => true
}
}
}
uri = URI.parse('https://api.ionic.io/push/notifications')
https = Net::HTTP.new(uri.host,uri.port)
https.use_ssl = true
req = Net::HTTP::Post.new(uri.path)
req['Content-Type'] = 'application/json'
req['Authorization'] = 'Bearer API_TOKEN'
req.body = params.to_json
res = https.request(req)
puts res.body
i get the notification but only the title shows up not the message. So im a bit confused on what i am doing wrong

Related

AWS Cognito JWT will not pass validation with .net core api, missing cognito configuration?

I am trying to attach an angular application to a .NET core API utilizing the JWT token. At this point i have the local angular app authenticating with Cognito and getting the user account.
I've followed this to get the token attached to the request.
https://medium.com/#umashankar.itn/aws-cognito-hosted-ui-with-angular-and-asp-net-core-5ddf351680a5
Amplify.Configure({
Auth: {
region: 'us-west-2',
userPoolId: 'us-west-MY POOL',
userPoolWebClientId: 'MY APP CLIENT ID'
}
}
});
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
if (request.url.indexOf(environment.api.baseUrl) == 0) {
return this.getToken().pipe(mergeMap(token => {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
return next.handle(request);
}));
}
return next.handle(request);
}
}
getToken() {
return from(
new Promise((resolve, reject) => {
Auth.currentSession()
.then((session) => {
if (!session.isValid()) {
resolve(null);
} else {
resolve(session.getIdToken().getJwtToken());
}
})
.catch(err => {
return resolve(null)
});
})
);
}
And i can confirm that it is adding the token to the request.
Interesting thing to note is that i'm using the session.getIdToken().getJwtToken() but there also is session.getAccessToken().getJwtToken() and they are different. I can't find anything telling me what the difference is, but i've tried both and they both have the same issue.
For the server side i've followed this answer to setup the .net core site and i can confirm that it is appropriately downloading the keys from /.well-known/jwks.json. It however just keeps rejecting the request with authentication failure.
How to validate AWS Cognito JWT in .NET Core Web API using .AddJwtBearer()
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKeyResolver = (s, securityToken, identifier, parameters) =>
{
// get JsonWebKeySet from AWS
var json = new WebClient().DownloadString(parameters.ValidIssuer + "/.well-known/jwks.json");
// serialize the result
return JsonConvert.DeserializeObject<JsonWebKeySet>(json).Keys;
},
ValidateIssuer = true,
ValidIssuer = $"https://cognito-idp.us-west-2.amazonaws.com/us-west-MYID",
ValidateLifetime = true,
LifetimeValidator = (before, expires, token, param) => expires > DateTime.UtcNow,
ValidateAudience = true,
ValidAudience = "MY APP CLIENT ID"
};
});
app.UseAuthentication();
[HttpGet]
[Authorize]
public IEnumerable<Device> Get()
{
return 'my devices...';
}
The angular app is running at http://localhost:4200 and the .net core is running at https://localhost:44300.
So the question i have is, am i missing some sort of setup in my cognito app client? What am i missing to get the .NET core app to take the JWT?
Turns out i actually did have everything correct as far as Cognito goes.
What i did have was this.
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
Which is not the correct order for things to work... this is..
app.UseRouting();
app.UseAuthentication(); <-- Authentication before authorization
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});

AWS SMS NOT Delivered Despite Success Response

I have seen the posts on StackOverflow with similar issues as mine, but none of them helped me resolve the issue. This is why I am creating a new post.
When I first set AWS SNS up, I tested sending SMS using the online console, it worked!
Then I wrote PHP code to send a sample message. I got some errors but was able to resolve them easily. However, when I got a success response, the message was not received at all.
I thought it is a Limitation issue. So I contacted AWS and increased my limit to 20US/month. I updated the preferences, but still the same result. I get a success response, the dashboard shows that a message was sent successfully (although it takes time to update the number of messages sent). But the message is not received.
Here is my code for reference:
<?php
require './aws/aws-autoloader.php';
use Aws\Sns\SnsClient;
use Aws\Exception\AwsException;
$sdk = new SnsClient([
'region' => 'us-east-1',
'version' => 'latest',
'credentials' => [
'key' => 'XXXXXXXXXXXXXXXXXXX',
'secret' => 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
]
]);
try {
$result = $sdk->publish([
'Message' => 'Reminder - You are scheduled for a session on 2020-05-20 at 4:30 PM',
'MessageStructure' => 'String',
'PhoneNumber' => '+1XXX789XXXX',
'MessageAttributes' => [
'AWS.SNS.SMS.SenderID' => [
'DataType' => 'String',
'StringValue' => 'MyName'
],
'AWS.SNS.SMS.SMSType' => [
'DataType' => 'String',
'StringValue' => 'Transactional'
]
]
]);
var_dump($result);
echo "\n";
} catch (AwsException $e) {
// output error message if fails
var_dump($e->getMessage());
}
And here is the result object:
object(Aws\Result)#119 (2) {
["data":"Aws\Result":private]=>
array(2) {
["MessageId"]=>
string(36) "8cf11950-cdb0-5503-9b69-4e6e9b61eaba"
["#metadata"]=>
array(4) {
["statusCode"]=>
int(200)
["effectiveUri"]=>
string(35) "https://sns.us-east-1.amazonaws.com"
["headers"]=>
array(4) {
["x-amzn-requestid"]=>
string(36) "0488b803-8776-57bc-b9a9-ef3dd1a71805"
["content-type"]=>
string(8) "text/xml"
["content-length"]=>
string(3) "294"
["date"]=>
string(29) "Tue, 19 May 2020 21:50:09 GMT"
}
["transferStats"]=>
array(1) {
["http"]=>
array(1) {
[0]=>
array(0) {
}
}
}
}
}
["monitoringEvents":"Aws\Result":private]=>
array(0) {
}
}
I am out of ideas. Not sure how to resolve this issue. Any help would be appreciated.
Thanks,
I believe by SMS's nature it can fail from time to time.
By my own observation, AWS employ some regional SMS providers that will help them send the SMS to your carriers.
Sometimes the SMS provider fails to send. Sometimes they are rejected by the receiving carrier.
At the moment, we have no way to be sure if It fails ( and react on this situation ) If the SMS is critical to your business, I suggest using another SMS service in conjunction with AWS.

How to send XML POST request with Guzzle to web service API using Laravel?

I am trying to post a request to my Web API, using Laravel Guzzle Http client. However, I am getting errors trying to post the request. The data I want to send is XML as the API controller is built in XML return format.
I have tried all sorts of methods to post the request with Guzzle but it is yet to work.
public function createProperty(Request $request)
{
$client = new Client();
$post = $request->all();
$create = $client->request('POST', 'http://127.0.0.1:5111/admin/hotel', [
'headers' => [
'Content-Type' => 'text/xml; charset=UTF8',
],
'form-data' => [
'Name' => $post['hotel_name'],
'Address' => $post['address'],
'Phone' => $post['phone'],
'Email' => $post['email'],
'Website' => $post['website'],
'Latitude' => $post['latitude'],
'Longitude' => $post['longitude'],
'Tags' => $post['tags'],
'Priority' => $post['priority'],
'Visible' => $post['visible'],
'Stars' => $post['stars'],
'Description' => $post['description'],
'Facilities' => $post['facilities'],
'Policies' => $post['policies'],
'ImportantInfo' => $post['important_info'],
'MinimumAge' => $post['minimum_age']
]
]);
//dd($create->getBody());
echo $create->getStatusCode();
echo $create->getHeader('content-type');
echo $create->getBody();
$response = $client->send($create);
$xml_string = preg_replace('/(<\?xml[^?]+?)utf-16/i', '$1utf-8', $create->getBody());
$xml_string = $create->getBody();
//dd($xml_string);
$hotels = simplexml_load_string($xml_string);
return redirect()->back();
}
I expected the result to POST to the web service and save data to database, but however I got the error "Client error: POST 'http://127.0.0.1:5111/admin/hotel' resulted in a '400 bad request' response. Please provide a valid XML object in the body
Rather than using post-data in the guzzle request, you need to use body:
$create = $client->request('POST', 'http://127.0.0.1:5111/admin/hotel', [
'headers' => [
'Content-Type' => 'text/xml; charset=UTF8',
],
'body' => $xml
]);
$xml will be the XML data you want to send to the API. Guzzle will not create the XML data for you, you'll need to do this yourself.
The XML data can be created using the DomDocument class in PHP.
If you are using Laravel 7+ this simple line should work very well
$xml = "<?xml version='1.0' encoding='utf-8'?><body></body>";
Http::withHeaders(["Content-Type" => "text/xml;charset=utf-8"])
->post('https://destination.url/api/action', ['body' => $xml]);

Passport Authedication Error in laravel 5.5

Error creating resource: [message] fopen(http://127.0.0.1:8000/oauth/token): failed to open stream: HTTP request failed! [file] /var/www/html/local/api-sample-application/vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php [line] 324
I'm getting this error when try to implement laravel passport authentication.
This is my code in routes/web.php content:
Route::get('/redirect', function () {
$query = http_build_query([
'client_id' => '3',
'redirect_uri' => 'http://127.0.0.1:8000/oauth/callback',
'response_type' => 'code',
'scope' => '',
]);
return redirect('http://127.0.0.1:8000/oauth/authorize?' . $query);
});
Route::get('/oauth/callback', function () {
$http = new GuzzleHttp\Client;
if (request('code')) {
$response = $http->post('http://127.0.0.1:8000/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => '3',
'client_secret' => 'H1UQCKVRARwASEJLR4ugGjBHHvFy34SCzSJFqQLL',
'redirect_uri' => 'http://127.0.0.1:8000/oauth/callback',
'code' => request('code'),
],
]);
return json_decode((string)$response->getBody(), TRUE);
} else {
return response()->json(['error' => request('error')]);
}
});
When i hit this URL, i'm getting this error, not able to generate the token.
Error message screenshot
I had the same problem, and after 1 day I found the reason...
Since the PHP built-in server is single threaded, requesting another url on your server will halt first request and it gets timed out.
So you can't request localhost from localhost in same thread.
You can easy check it, try 'get' come public server host, 'http://www.example-host.com'..
Check this http://stackoverflow.com/a/25651196/916682

Limitation of number posts on API

I want to build a FB app which posts messages to the walls of those registered for the app.
There are two setups:
One message to many people (1-many, could occur few times a day)
Many user-specific massages (1-1, but many of them, could occur few times a day for each user)
All in all; one user could get a few different updates on his wall per day, but it could affect many users (that's pretty much the whole point of my idea)
Into what extend is Facebook going to allow me to do this, and won't think I'll be spamming.
PS:
I've come along this post, which seems to have remained unsolved...:
Post on Multiple Friend's Wall
And this post, which doesn't make it clear for me whether my idea is something I should start or not ;)
Graph API post to wall limitation
You can use Facebook batch API to do what you intent.
You can get more information on Facebook batch request at: http://25labs.com/tutorial-post-to-multiple-facebook-wall-or-timeline-in-one-go-using-graph-api-batch-request/
$batchPost[] = array(
'method' => 'POST',
'relative_url' => "/{ID1}/feed?access_token={ACCESS_TOKEN_FOR_ID1}",
'body' => http_build_query($body) );
$batchPost[] = array(
'method' => 'POST',
'relative_url' => "/{ID2}/feed?access_token={ACCESS_TOKEN_FOR_ID2}",
'body' => http_build_query($body) );
$batchPost[] = array(
'method' => 'POST',
'relative_url' => "/{ID3}/feed?access_token={ACCESS_TOKEN_FOR_ID3}",
'body' => http_build_query($body) );
$multiPostResponse = $facebook->api('?batch='.urlencode(json_encode($batchPost)), 'POST');
I developed an app in my website http://www.cefozyt.com which can post links, message etc. to multiple facebook users wall & groups. I used :-
if($user){
// Proceed knowing you have a logged in user who has a valid session.
//========= Batch requests over the Facebook Graph API using the PHP-SDK ========
// Save your method calls into an array
$queries = array(
array('method' => 'GET', 'relative_url' => '/'.$user),
array('method' => 'GET', 'relative_url' => '/'.$user.'/friends'),
array('method' => 'GET', 'relative_url' => '/'.$user.'/groups'),
array('method' => 'GET', 'relative_url' => '/'.$user.'/likes'),
);
// POST your queries to the batch endpoint on the graph.
try{
$batchResponse = $facebook->api('?batch='.json_encode($queries), 'POST');
}catch(Exception $o){
error_log($o);
}
//Return values are indexed in order of the original array, content is in ['body'] as a JSON
//string. Decode for use as a PHP array.
$user_info = json_decode($batchResponse[0]['body'], TRUE);
$friends_list = json_decode($batchResponse[1]['body'], TRUE);
$groups = json_decode($batchResponse[2]['body'], TRUE);
$pages = json_decode($batchResponse[3]['body'], TRUE);
//========= Batch requests over the Facebook Graph API using the PHP-SDK ends =====
if(isset($_POST['submit_x'])){
if($_POST['message'] || $_POST['link'] || $_POST['picture']) {
$body = array(
'message' => $_POST['message'],
'link' => $_POST['link'],
'picture' => $_POST['picture'],
'name' => $_POST['name'],
'caption' => $_POST['caption'],
'description' => $_POST['description'],
);
$batchPost=array();
$i=1;
$flag=1;
foreach($_POST as $key => $value) {
if(strpos($key,"id_") === 0) {
$batchPost[] = array('method' => 'POST', 'relative_url' => "/$value/feed", 'body' => http_build_query($body));
if($i++ == 50) {
try{
$multiPostResponse = $facebook->api('?batch='.urlencode(json_encode($batchPost)), 'POST');
}catch(FacebookApiException $e){
error_log($e);
echo("Batch Post Failed");
}
$flag=0;
unset($batchPost);
$i=1;
}
}
}
if(isset($batchPost) && count($batchPost) > 0 ) {
try{
$multiPostResponse = $facebook->api('?batch='.urlencode(json_encode($batchPost)), 'POST');
}catch(FacebookApiException $e){
error_log($e);
echo("Batch Post Failed");
}
$flag=0;
}
}
else {
$flag=2;
}
}
}
?>