What is the best way to send push notifications through Urban AirShip using a Rails 3 web app?
From Urban Airship documentation:
An HTTP POST to /api/push/broadcast/
sends the given notification to all
registered device tokens for the
application. The payload is in JSON
with content-type application/json,
with this structure:
{
"aps": {
"badge": 15,
"alert": "Hello from Urban Airship!",
"sound": "cat.caf"
},
"exclude_tokens": [
"device token you want to skip",
"another device token you want to skip"
]
}
I really don't know where to start!
Better way is to use UrbanAirship Groupon version. Their docs specify every thing very clearly and it will much neater code. Worked and tested in my application.
From the read me file, (with some more comments and all):-
Note: if you are using Ruby 1.8, you should also install the system_timer gem for more reliable timeout behaviour. See http://ph7spot.com/musings/system-timer for more information. Baically
gem install system_timer
Installation
gem install urbanairship
# or specify in your gem file
gem "urbanairship"
Configuration define all this in initializes directory and then make sure u restart your application.
Urbanairship.application_key = 'application-key'
Urbanairship.application_secret = 'application-secret'
Urbanairship.master_secret = 'master-secret'
Urbanairship.logger = Rails.logger
Urbanairship.request_timeout = 5 # default
Usage
Registering a device token
Urbanairship.register_device 'DEVICE-TOKEN' # => true
Unregistering a device token
Urbanairship.unregister_device 'DEVICE-TOKEN' # => true
Sending a push notification (for instant delivery remove schedule_for attribute)
notification = {
:schedule_for => 1.hour.from_now,
:device_tokens => ['DEVICE-TOKEN-ONE', 'DEVICE-TOKEN-TWO'],
:aps => {:alert => 'You have a new message!', :badge => 1}
}
Urbanairship.push notification # => true
Batching push notification sends (for instant delivery remove schedule_for attribute)
notifications = [
{
:schedule_for => 1.hour.from_now,
:device_tokens => ['DEVICE-TOKEN-ONE', 'DEVICE-TOKEN-TWO'],
:aps => {:alert => 'You have a new message!', :badge => 1}
},
{
:schedule_for => 3.hours.from_now,
:device_tokens => ['DEVICE-TOKEN-THREE'],
:aps => {:alert => 'You have a new message!', :badge => 1}
}
]
Urbanairship.batch_push notifications # => true
Sending broadcast notifications
Urbanairship allows you to send a broadcast notification to all active registered device tokens for your app.(for instant delivery remove schedule_for attribute)
notification = {
:schedule_for => 1.hour.from_now,
:aps => {:alert => 'Important announcement!', :badge => 1}
}
Urbanairship.broadcast_push notification # => true
Check out this example:
https://github.com/bhedana/urbanairship_on_rails
It was linked from the Urban Airship support site
Ok, this is a simple way of sending a urban airship broadcast from ROR controller:
require 'net/http'
require 'net/https'
require 'open-uri'
app_key = 'JJqr...'
app_secret = 'lAu7...'
master_secret = 'K81P...'
payload ={
"aps" => {"badge" => "0", "alert" => "My own message", "sound" => ""}
}.to_json
full_path = 'https://go.urbanairship.com/api/push/broadcast/'
url = URI.parse(full_path)
req = Net::HTTP::Post.new(url.path, initheader = {'Content-Type' =>'application/json'})
req.body = payload
req.basic_auth app_key, master_secret
con = Net::HTTP.new(url.host, url.port)
con.use_ssl = true
r = con.start {|http| http.request(req)}
logger.info "\n\n##############\n\n " + "Resonse body: " + r.body + " \n\n##############\n\n"
Cheers!
In Rails 4.2.x and Ruby 2.3.x, I'm using the 'urbanairship' gem, it is best to reference the most recent documentation found here.
Example of sending to ios:
def deliver_push_notification recipient_uuid, message
ua = Urbanairship
client = ua::Client.new(key: ENV["URBAN_AIRSHIP_APP_KEY"], secret: ENV["URBAN_AIRSHIP_MASTER_SECRET"])
p = client.create_push
p.audience = ua.ios_channel(recipient_uuid)
p.notification = ua.notification(ios: ua.ios(alert: message))
p.device_types = ua.device_types(["ios"])
p.send_push
end
Related
I keep getting a WebPush Error (Status Code 403) fro Chrome for a PWA I'm building and the body says that I need to use the VAPID server key from the 'firebase console' but I used nodes Web-Push library to generate the VAPID Keys, whats going on? Do I have to use firebase to build PWAs in Chrome?
Here's the Error Message I'm getting from the browser when I send a push notification:
name: 'WebPushError',
message: 'Received unexpected response code',
statusCode: 403,
headers:
{ 'content-type': 'text/plain; charset=utf-8',
'x-content-type-options': 'nosniff',
'x-frame-options': 'SAMEORIGIN',
'x-xss-protection': '0',
date: 'Thu, 31 Oct 2019 19:59:02 GMT',
'content-length': '194',
'alt-svc':
'quic=":443"; ma=2592000; v="46,43",h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000',
connection: 'close' },
body:
'the key in the authorization header does not correspond to the sender ID used to subscribe this user. Please ensure
you are using the correct sender ID and server Key from the Firebase console.\n',
endpoint:
'https://fcm.googleapis.com/fcm/send/exXmW3OFOTY:APA91bEKW_vxnvOZohog34pprDH6XvBsxtfnUpBdYY7z_7q4GZGa4wrmtBBg4kTRwLtgy3lNpCs8SMlvOr4nY-Fu_4zUus6zEJh69581Ier14QZxkEEVXyZHKRaZcmHa3zmbZRB4VD7Z
and here's the code that is running my node server:
//Handle imports
const express = require('express')
const cors = require('cors')
const bodyParser = require('body-parser')
const webPush = require('web-push')
const vapidKeys = require('./vapid.json')
const path = require('path')
//Setup application
const app = express()
app.use(cors())
app.use(bodyParser.json())
app.use('/static', express.static(path.join(__dirname,'frontend')))
const port = 8080
//Set up webpush
webPush.setVapidDetails(
'mailto: <email>',
vapidKeys.publicKey,
vapidKeys.privateKey
)
const pushOptions = {
proxy: '<proxy>'
}
//setup Push Notification
const sendNotification = (subscription, dataToSend='') => {
webPush.sendNotification(subscription, dataToSend, pushOptions).catch(error => { console.log('Damn it: ', error.message, '||', error)
})
}
//Server Routes Defined
app.get('/', (req, res) => res.sendFile('index.html', { root: './' }))
//Setup Database Methods
const dummyDb = {subscription: null}
const saveToDatabase = async subscription => {
dummyDb.subscription = subscription
}
//Other Server Routes
app.post('/save-subscription', async (req, res) => {
const subscription = req.body
await saveToDatabase(subscription)
console.log('subscribed!')
res.json({message: 'success'})
})
app.get('/send-notification', (req, res) => {
const subscription = dummyDb.subscription
const message = 'hello world'
sendNotification(subscription, message)
res.json({message: dummyDb.subscription})
})
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
I have node.js express, postgres, angular 8 app.
I had the same problem and I got it working by adding the "gcm_sender_id": in the manifest.webmanifest file (or manifest.json I also used firebase generated public and private keys.
your gcm_sender_id is your project id in google cloud or firebase sender id
Same situation and almost lost my sanity. I tried inserting gcm_sender_id with a Firebase senderId and worked finally. I didn't have a Firebase account, but I was able to create a project in seconds and my senderId was ready to be used in the messaging settings.
But a caveat: After my modification in the manifest.json (in my case) in the root's folder, it was needed to uninstall the current service worker and restart my React project. Then I followed again all steps back by asking permissions and subscribe the user and finally trigger a push notification.
During my heat researches for a solution, I found that gcm_sender_id is also used to send and validate push messages from other browsers. According to Google Web Updates:
For Chrome prior to version 52, Opera Android and the Samsung Browser,
you're also still required to include a 'gcm_sender_id' in your web
app's manifest.json. The API key and sender ID are used to check
whether the server making the requests is actually allowed to send
messages to the receiving user.
Im using the paypal plugin for ionic and is not working on iOS
I already have running this plugin on android and it is working perfect, and also have the clientid generated on https://developer.paypal.com/developer/applications/
doPayment() {
const total: any = 10;
const currency: any = 'USD';
const envProduct: any = '';
const envSandbox: any = '{Client ID from developer.paypal.com/developer/applications/}';
this.payPal.init({
PayPalEnvironmentProduction: envProduct,
PayPalEnvironmentSandbox: envSandbox
})
.then(() => {
// Environments: PayPalEnvironmentNoNetwork, PayPalEnvironmentSandbox, PayPalEnvironmentProduction
this.payPal.prepareToRender('PayPalEnvironmentSandbox', new PayPalConfiguration({
// Only needed if you get an "Internal Service Error" after PayPal login!
// payPalShippingAddressOption: 2 // PayPalShippingAddressOptionPayPal
})).then(() => {
const payment = new PayPalPayment(total, currency, 'Description', 'sale');
this.payPal.renderSinglePaymentUI(payment).then(async ( res ) => {
// rest of the code after payment
}, ( errclose ) => {
console.log( errclose ); // Error or render dialog closed without being successful
});
}, ( errconf ) => {
console.log( errconf ); // Error in configuration
});
}, ( errinit ) => {
console.log( errinit ); // Error in initialization, maybe PayPal isn't supported or something else
});
}
Here is the Error:
Payments to this merchant are not allowed (invalid clientId)
Any help is appreciated. Thank you very much.
I get the same error, also on iOS only, when used Ionic Capacitor for runtime instead of Cordova. When I built the app using Cordova runtime it worked correctly on both platforms. Also, you could get the same error when specifying the 'PayPalEnvironmentSandbox' environment name but use production clientId and vice versa.
I'm trying to perform a push notification for Google Actions Intent.
Thus far, I've followed the instructions here: https://developers.google.com/actions/assistant/updates/notifications#send_notifications
This is my resulting code:
const {google} = require('googleapis');
var request = require('request');
const key = require('./bot.json');
module.exports = async function (context, myQueueItem) {
context.log('JavaScript queue trigger function processed work item', myQueueItem);
let jwtClient = new google.auth.JWT(
key.client_email, null, key.private_key,
['https://www.googleapis.com/auth/actions.fulfillment.conversation'],
null
);
jwtClient.authorize((err, tokens) => {
// code to retrieve target userId and intent
let notif = {
userNotification: {
title: [message],
},
target: {
userId:[obtained from permission request],
intent: [name of intent],
// Expects a IETF BCP-47 language code (i.e. en-US)
locale: 'en-US'
},
};
request.post('https://actions.googleapis.com/v2/conversations:send', {
'auth': {
'bearer': tokens.access_token,
},
'json': true,
'body': {'customPushMessage': notif},
}, (err, httpResponse, body) => {
console.log(body);
console.log(httpResponse.statusCode + ': ' + httpResponse.statusMessage);
});
});
};
//module.exports(console, "Test");
This results in a 403 from the notification service. Is this because of the user id, intent name or jwtoken that was generated?
Following are the steps we need to check before sending the push notification
Check your Google permission settings
In order to test the Action, you need to enable the necessary permissions.
Go to the ‘Activity Controls' page (https://myaccount.google.com/activitycontrols).
Sign in with your Google account, if you have not already done so.
Ensure that the following permissions are enabled:
a.Web & App Activity
b.Device Information
c.Voice & Audio Activity
2.Target intent name should be added into the Implicit invocation field.
with enabled push notification.
3.use the same email id in your google assistant which you had used for login in GCP.
My app is ready for production but request details API does not return complete data. I already whitelisted my ip from where i am sending ride request
i am using request endoint to find details with below URL
https://sandbox-api.uber.com/v1/requests/3638f4e4-25d7-47f6-8743-9616d4b4a2df
when i send request using curl below response received form Uber
Array
(
[status] => processing
[destination] => Array
(
[latitude] => 25.7616798
[longitude] => -80.1917902
)
[product_id] => 90384182-0269-4564-827d-e3c42c0eb83b
[request_id] => 3638f4e4-25d7-47f6-8743-9616d4b4a2df
[driver] =>
[pickup] => Array
(
[latitude] => 25.790654
[longitude] => -80.1300455
)
[eta] =>
[location] =>
[vehicle] =>
[surge_multiplier] => 1
[shared] => 1
)
Here driver details, eta everything is empty. I am using production account and i have complete access.
The request details for a request with status processing will return null for eta, location, vehicle and driver because the status indicates that Uber tries to match your rider with a driver. As soon as they are matched, the request status changes to accepted. From this point in time, you will get all the details for the request. If you would like to test this behavior, please check out the Sandbox documentation here. You can change the status of a request within the Sandbox by sending a PUT /v1/sandbox/requests/{request_id}. As payload, it requires a JSON object with a status: {"status": "accepted"}.
I have created a test API on Paypal
Do you know what i have to put in this function to make it work ?
// Creates a configuration array containing credentials and other required configuration parameters.
public static function getAcctAndConfig()
{
$config = array(
// Signature Credential
"acct1.UserName" => "",
"acct1.Password" => "",
"acct1.Signature" => "",
// Subject is optional and is required only in case of third party authorization
//"acct1.Subject" => "",
// Sample Certificate Credential
// "acct1.UserName" => "certuser_biz_api1.paypal.com",
// "acct1.Password" => "D6JNKKULHN3G5B8A",
// Certificate path relative to config folder or absolute path in file system
// "acct1.CertPath" => "cert_key.pem",
// "acct1.AppId" => "APP-80W284485P519543T"
);
return array_merge($config, self::getConfig());;
}
Thanks for your help...
Username is your email address
Password is likely the ClientID
Signature is likely the Secret
You should log into your Sandbox (the actual PayPal Sandbox site, not just Developer) account and verify that is the case