I am sending push notifications to my Android phone. I want these notifications grouped so my notification list does not get flooded.
According to the documentation messages from the same 'source' get grouped but on my phone the messages always show up ungrouped.
I call the push API from a Google Apps script and have tried setting source_device_iden, source_user_iden and notification_tag when I call the push API. None of these seem to make any difference.
How can I get the pushmessages to be grouped on my phone?
Google Apps script code
function pushNoteToPhone(title, body) {
var digest = "Basic "+Utilities.base64Encode(PUSH_BULLET_TOKEN+":");
var options = {
"method" : "post",
"payload" : {
"device_iden" : MYPHONE_ID,
"type" : "note",
"title" : title,
"body" : body,
"source_device_iden" : <device id>,
"notification_tag": "tag1",
},
"headers" : {
"Authorization": digest
}
};
var push_bullet_url = "https://api.pushbullet.com/v2/pushes";
UrlFetchApp.fetch(push_bullet_url, options);
}
The easiest way to do this (admittedly it should be easier) is to create an OAuth Client and then send using an access token for that oauth client. That way the pushes will all appear to come from that client instead of you. This is how IFTTT and Zapier work on Pushbullet.
Here's how to setup an oauth client: https://docs.pushbullet.com/#oauth
To get an access token you can use the "oauth test url" on the create client page, you will end up with an access token in the URL once you approve access. Use that access token instead of your normal one and the pushes will appear to come from the client instead of you.
Don't know how you are trying to update the notification but without the code, my guess is that you are trying to pass a new Notification ID to each notification being sent to the device. However, please take a look here and look under, "Updating Notifications". As explained in the documentation, by passing the same ID to each notification it will either group these notifications on the device or create a new one in case the old one has been dismissed.
Related
I have implemented the chrome.identity launchWebAuthFlow to authenticate users of a web extension against an oauth2 provider and the entire flow works perfectly, I receive the access token back in the redirect URL, I extract the token using a regex and then it is valid and accepted to query the APIs.
However, I do not understand why it does not prompt anymore for credentials when I launch again the launchWebAuthFlow. Instead, it retrieves another (valid !) token in the background. Don't get me wrong, I like this, and I prefer it works in the background, but I just don't understand how. Even after clearing all cookies and local data, when I launch the launchWebAuthFlow again it just works in the background without asking for credentials...where are they stored?
Also, not sure if that helps, but my flow is the following:
extension ->oauth2 server->azure ad SSO->enter credentials->redirect to extension
So the real authentication is managed by Azure AD. However, even when I'm signed out from Microsoft, the extension keeps getting a valid auth token when the below code is triggered and without asking for credentials...so the credentials must be stored somewhere...
chrome.identity.launchWebAuthFlow(
{
url: dev.identity_url(),
interactive: true
},
function (responseWithToken) {
// the access token needs to be extracted from the response.
console.log(responseWithToken);
let token = responseWithToken.match(/(?<=access_token=).*(?=&token_type)/);
token = token[0];
chrome.storage.local.set({ "auth-token": token }, function () {
console.log(`Access Token has been saved: ${token}`);
});
}
);
I am trying to send a message from Google Apps Script to Slack via a Webhook URL that works great, but I can't figure out how to send a highlighted or selected user in that text. For example '#UsernameTest how are you?' is something I want to send to a person or channel, but it doesn't work. I figured out that to highlight the channel i.e. send '#Channel' I just needed to write , but that is not what I want. I tried <#UserID> but it still didn't work. (I Received the UserID by using inspector tool on the web-version of Slack on the user.)
The Slack API docs helped some but still have problems.
Here is the code I'm using, thank you.
var SLACK_URL = 'https://hooks.slack.com/services/...
function sendSlackMessage(text) {
var slackMessage = {
text: "#UsernameTest how are you? and all you guys <#Channel>?"
};
var options = {
method: 'POST',
contentType: 'application/json',
payload: JSON.stringify(slackMessage)
};
UrlFetchApp.fetch(SLACK_URL, options);
}
The correct format for sending user mentions is <#[user-id]>
And for channel pings the syntax is <!channel> or <!here>.
e.g. to send a mention to a user with user ID U1234567 you need to sent the string:
<#U12345678> how are you? and all you guys <!channel>?"
For more information on how to link users and channel see the documentation.
Note that #username is being phased out and should no longer be used. For more details see "A lingering farewell to the username" from Slack.
Seems that you have 3 " in that line:
text: "#UsernameTest how are you? and all you guys "<#Channel>?"
I am trying to PATCH (partially update) Firebase records (firebase.com). This works perfect outside of Google Apps Script using PATCH. GAS is not supporting PATCH and I tried X-HTTP-Method-Override without success. Using GAS with X-HTTP-Method-Override renders the same result as a standard GET. There is no security on my test database. No log-in is required.
var myPayload = "{\"WSD124\" : {\"auction\" : {\"stockno\" : \"ESD124\", \"highbid\" : \"240\"}}}";
var myURL = "https://mydatabase.firebaseio.com/auctions/.json";
var options = {
headers: {
"X-HTTP-Method-Override" : "PATCH"
},
method: "POST",
payload: myPayload
};
var oResponse = UrlFetchApp.fetch(myURL,options);
A quick update for those coming back to this old thread - we now support X-HTTP-Method-Override headers on all REST API calls, so this should now work
UPDATE
This is now supported. See Chris Raynor's answer.
OLD ANSWER
We don't currently support X-HTTP-Method-Override though we are considering it. For now you'll likely have to do a PUT with the whole record. Give us an email at support#firebase.com if this is significantly blocking you.
I'm developing a quickblox application using Adobe AIR, which forces me to use the REST Api instead of the native libraries. I can't get the push notifications to work for offline Messages or the admin panel. Here's the details of what I do:
Admin panel:
uploaded Apple certificates for both Devel and Production push notifications
Setup project ID and server key for GCM
on Application Activate:
Register with APNS. Get device token:
XXXXXXX1fd86e783c1410e9b9e41e9f11339e33f17f59bfcc7d6bf9XXXXXXXXX
Generate udid for device. This is not Apple's device UDID, since it is now deprecated. I generate one myself. I'm saying this just in case this could be the problem
Login to Quickblox as user with device info
POST
{
"auth_key":"XXXXXXXXXX",
"nonce":8072,
"user":{
"password":"XXXXXXX",
"login":"XXXXXX"
},
"application_id":"1563",
"timestamp":1363692198,
"device":{
"platform":"ios",
"udid":"71B18699-E1A3-13B6-F8C3-BDBF01AC1FFC-B4B3475569E9-6B6A-A27E-56D1-B73E0ED4"
},
"signature":"d61293bbd98d2e523952c0f30e44ec514fb7f86a"
}
Login is ok. Create push token. As client_identification_sequence I use the token retrieved from Apple
POST
{
"push_token":{
"environment":"development",
"client_identification_sequence":"XXXXXXX1fd86e783c1410e9b9e41e9f11339e33f17f59bfcc7d6bf9XXXXXXXXX"
},
"device":{
"platform":"ios",
"udid":"71B18699-E1A3-13B6-F8C3-BDBF01AC1FFC-B4B3475569E9-6B6A-A27E-56D1-B73E0ED4"
}
}
Quickblox returns a token 153323 so I assume everything is ok
Now create subscription
POST
{
"notification_channels":"apns"
}
Quickblox returns the following
[
{
"subscription":{
"device":{
"udid":"71B18699-E1A3-13B6-F8C3-BDBF01AC1FFC-B4B3475569E9-6B6A-A27E-56D1-B73E0ED4",
"platform":{
"name":"ios"
}
},
"id":167704,
"notification_channel":{
"name":"apns"
}
}
}
]
UDid matches udid I passed from login. Everything looks good
Now I go to Admin panel and try to send Message. Admin panel says:
Notification has been successfully added to queue
If I go to queue, message shows as 'sent' but I never receive the notification in my device.
Any help would be greatly appreciated
your code looks good,
some comments:
1) you dont need to pass
"device":{
"platform":"ios",
"udid":"71B18699-E1A3-13B6-F8C3-BDBF01AC1FFC-B4B3475569E9-6B6A-A27E-56D1-B73E0ED4"
},
params to session, because you are passing them while creating push token
2) udid - it's just to separate users devices, because user can has more than 1 device. So you can pass any value to 'udid' which uniquely identify user's particular device
3) if you have sent message from admin panel - it means i think everything is OK on client side. So just check your APNS certificates, reupload them.
I started with an little application for showing some relevant information to our developer team, which is collected from different sources. Like google calendar, our project backoffice, an openarena server-logs etc.
I started with an web application, but then decided to switch the project to an chrome extension. Now i already had the google calendar integration up and running using the V3 Javascript(alpha) Client-Lib. This wasn't working anymore because i had to change the OAUTH dance, from the one for web-apps, to the one for packaged/installed apps.
For this i followed the tutorial (It's my first extension.) http://code.google.com/chrome/extensions/tut_oauth.html and got the OAUTH dance working again. Now i'am trying to request my calendar-data from the google api using the signedRequest-Methode from the tutorial, but alway receive the response "Daily Limit Exceeded. Please sign up" (Api Console shows i haven't performed any request).
Maybe someone has an idea what i am doing wrong here, because i tried everthing i could think about. Thanks in advance, Florian
Code -
manifest.json:
{
"name": "MIS",
"version": "0.1",
"description": "Monitor Information System",
"background_page": "background.html",
"browser_action": {
"default_icon": "img/mis/icon.png",
"default_title": "Mis"
},
"permissions": [
"tabs",
"https://www.googleapis.com/",
"https://www.google.com/"]
}
background.html:
...
oauth = ChromeExOAuth.initBackgroundPage
({
'request_url':'https://www.google.com/accounts/OAuthGetRequestToken',
'authorize_url':'https://www.google.com/accounts/OAuthAuthorizeToken',
'access_url':'https://www.google.com/accounts/OAuthGetAccessToken',
'consumer_key': 'anonymous',
'consumer_secret': 'anonymous',
'scope': 'https://www.googleapis.com/auth/calendar',
'app_name': 'Mis'
});
...
main.html Methode call:
function performCalendarEventsRequest(calendarId)
{
var requestUrl = 'https://www.googleapis.com/calendar/v3/calendars/'+calendarId+'/events';
var request = {
'method': 'GET',
'headers': {
'GData-Version': '3.0',
'Content-Type': 'application/atom+xml'
},
'parameters': {
'alt': 'json'
},
'body': 'Data to send'
};
oauth.sendSignedRequest(requestUrl, calendarEventsRequestCallback, request);
}
Since your consumer key and secret are both set as anonymous you are not identifying your application in any way.
You can either replace these with the Client ID and Client secret values respectively, which can be found on the API Access tab on your projects page in the API Console, or you can pass the API key (found just under the auth tokens on the same page) using an additional key parameter.
This is the same for most Google APIs.
Source: http://code.google.com/apis/calendar/v3/using.html#APIKey
I know this is an old question but I was stuck in the same error using the PHP implementation (Beta) of the API (2016-01-06), because I initially thought the setAuthConfigFile was all it was needed:
$client = new Google_Client();
$client->setApplicationName('MyCalendarAppName');
$client->setAuthConfigFile(APPPATH.'client_secret.json'); //file downloaded from GDC:
// https://console.developers.google.com/apis/credentials?project=YOUR-PROJECT-ID
$client->addScope(Google_Service_Calendar::CALENDAR_READONLY);
$service = new Google_Service_Calendar($client);
The error was not really due to a "daily limit" of requests but to the fact that I (owner of the Google account) hadn't explicitly given access permissions to the calendar. This is how to do it:
access the URL returned by the createAuthUrl() method (which can be invoked before calling the service);
a "Deny" and "Allow" form for accessing the calendars shows up – press Allow;
a code is returned – copy&paste this code to the authenticate($code) method and voilá, no more 403: Daily Limit Exceeded errors.
For doing this, just use the following lines before invoking the service:
//$client->createAuthUrl();
// - invoke the method above one time only: returns a URL with the "Allow" form
// which will give the code for authentication
$client->authenticate('YOUR_CODE_GOES_HERE');
$service = new Google_Service_Calendar($client); //invokes the Calendar service
However, this will allow a one time access to the calendar. If you try this twice, you get:
Google_Auth_Exception: Error fetching OAuth2 access token, message: 'invalid_grant: Code was already redeemed.'
Meaning that a token is needed to reaccess the calendar with the reedemed code. This token is returned by the authenticate method and can be assigned to the client through the setAccessToken method:
//get the access token you previously stored or get a new one to be stored:
$accessToken = $client->authenticate('YOUR_CODE_GOES_HERE');
//after the if-else blocks...
$client->setAccessToken($accessToken);
//refresh the token if it's expired
if ($client->isAccessTokenExpired())
$client->refreshToken($client->getRefreshToken());
The goal is to reuse that access token repeatedly (implicitly also reusing the redeemed code) and only invoke a refreshToken when the token expires. Google's quickstart creates a specific file for storing this token (calendar-php-quickstart.json) and only uses the authenticate method when the token is not found in that file. I.e. the setAccessToken is the only Client authentication method (besides the setAuthConfigFile) that needs to be used in subsequent requests.
I only fully understood this OAuth 2.0 logic by going through these errors and since this question attracted so many people already, perhaps this may help others...