I'd like to list all channels associated with a subscribe key that have active subscribers. Is there a way to do that with pubnub? I am using the JavaScript API if that makes any difference.
PubNub Where Now API
Return a list of channels, associated with a subscribe key, where subscribers exist.
PUBNUB.where_now( { uuid : 'optional-uuid' }, function(data) {
console.log(data);
} );
Note at the time of this posting, where_now() is only available in +3.6 SDK versions.
Related
I am using getstream nodejs package.
I've got an aggregated notifications feed and it properly fetches aggregated activities with feed.get()
The problem is that when subscribing via feed.subscribe() I only get the activity, not the agreaggated info with the seen & unseen counts as described here https://kuus.github.io/getstream/docs/index.html#realtime
Is there some parameter I'm missing?
So, I tried different versions of the Stream js client (I'm using 4.3.0v because it's latest compatible with Node v8.0) up to the latest 4.7.0 and the behaviour persists. It looks like Notifications feeds don't really push aggregated data to the client, just activities like a flat feed. Anyhow, this is the workaround I found around that.
feed.subscribe(async ({ new: activities }) => {
const {
results: notifications,
unread,
unseen,
} = await feed.getActivityDetail([activities.map(({ id }) => id)]);
/* ...do something with notifications, unseen and unread */
});
Looking at the docs for the SignalR bindings to send a message to a specified user you include the UserId property on the message as such -
[FunctionName("SendMessage")]
public static Task SendMessage(
[HttpTrigger(AuthorizationLevel.Anonymous, "post")]object message,
[SignalR(HubName = "chat")]IAsyncCollector<SignalRMessage> signalRMessages)
{
return signalRMessages.AddAsync(
new SignalRMessage
{
// the message will only be sent to these user IDs
UserId = "userId1",
Target = "newMessage",
Arguments = new [] { message }
});
}
This example is taken straight from the documentation, but the comment implies you message multiple userids, even though the property is a string and not an array.
How would you specify multiple users? (If for example, they are in a private chat channel together) Or is this mistake in the wording of the comment and you would need to send a message per user?
With other versions of SignalR I would put them in a group, but bindings for this do not exist for functions.
Group operations were introduced in the latest release.
Now you can:
Send a message to a group using GroupName in SignalRMessage
Add/remove user in a group using IAsyncCollector<SignalRGroupAction> output
Unfortunately just like the doc says, right now with Azure function binding we can only send message to one user or to all clients.
See the code of current extension SDK Microsoft.Azure.WebJobs.Extensions.SignalRService v1.0.0-preview1-10002.
It shows the extension has only two methods SendToAll and SendToUser.
Task SendToAll(string hubName, SignalRData data);
Task SendToUser(string hubName, string userId, SignalRData data);
The comment confused you is actually for old sample, the author forgot to modify it.
Good news is that support for group operation is under progress.
I am writing an iOS app that allows people to set sound settings (either default sound or no sound) for a particular push notification that subscribe to a particular topic.
Different people will have different sound settings, is there a way to send push notification settings to a topic, but with differing sound settings depending on the user.
I have the following implementation:
exports.pushNotifications = functions.database.ref('/companies/{companyID}/posts').onWrite((snap, context) => {
const companyID = context.params.companyID
const message = {
"condition": `'allCompanies' in topics || '${companyID}' in topics`,
"apns": {
"headers": {
"apns-priority": "5"
},
"payload": {
"aps": {
"alert": {
"body": "New gossips"
},
"sound": "default", //Any ways to vary this?
"badge": 1
}
}
}
};
return admin.messaging().send(message)
.then((response) => {
return console.log('PNForAllCompanies Successful: ', response);
})
.catch((error) => {
return console.log('PNForAllCompanies Error: ', error);
});
})
I tried to find resources in this area but seems limited. Does anyone have any idea to do so?
EDIT (For clearer description of use case):
In the settings page of the app, users can set the sound settings (either default, or none) of a push notification when a new post is added with the tag "My Company" like so:
How I implement this is to do a database trigger to that company node. When there is a new post added to that company node, it will send a push notification to everyone who has subscribed to that companyID as a topic.
However, for everyone who have subscribed to that companyID as a topic may like to have sound when this notification is pushed while others may not want silent. With that, is there a way vary the sound parameter depending on the user's preference?
The value for the sound parameter should be the name of the sound file included in the app. For more details about the payload parameter, see the official documentation:
The sound to play when the device receives the notification.
Sound files can be in the main bundle of the client app or in the Library/Sounds folder of the app's data container. See the iOS Developer Library for more information.
"Different people will have different sound settings, is there a way to send push notification settings to a topic, but with differing sound settings depending on the user."
I'm not sure if I understand your use-case properly, but if you want the sound to vary depending on the topic the message it's coming from, you'll have to handle that from the client app side -- determining which topic the message it actually came from.
In my chat room there can be multiple moderators in a room at same time.
Every moderator can open/close room from public at any time.
If a room is closed, no new members can access it, no need to care for those who are already in.
So a question, how do I correctly sync the chatroom open / closed status?
I was using a special moderator channel, every moderator page kept publishing it's state to it, and also was subscribed to it.
It works most of the time, but I believe there can be a sync issue, when I publish Closed state, and then get Open state from another moderator who hasn't yet received my publish update.
PubNub State Sync for Multiple Chat Clients
One good way to handle this situation is use the PubNub Storage & Playback Service for Data Management and Message State. Specifically the PUBNUB.history({...}) API call. You can create a "chatroom_status" channel for every chat room (i.e. "chatroom_a_status", "chatroom_b_status").
Note: are you creating a unique moderator channel for each chat room, or a shared moderator channel? If the former, then the "chatroom_status_n" example above is basically the same thing.
Before the moderator changes the state of a chatroom, he can just call PUBNUB.history({...}) on the "chatroom_n_status" channel to retrieve the last known state of the chatroom. If the status is "closed" the moderator will know another moderator closed the chat room (and if you pass the moderator ID, you could also track which moderator closed the channel).
You will be able to achieve State sync for chat may be accomplished by using PubNub Storage & Playback Service for Data Management.
Here is some example code for simple state management:
// Init PubNub
var pubnub = PUBNUB({ publish_key : 'demo', subscribe_key : 'demo' });
// Get State of Chat Room
function get_state( chat_room, callback ) {
pubnub.history({
channel : chat_room + '-state',
callback : function(msgs) { callback(msgs[0][0] || default_state) }
});
}
// Set State of Chat Room
function set_state( chat_room, state ) {
pubnub.publish({ channel : chat_room + '-state', message : state });
}
And you can use this like:
set_state( 'chatroom_a', { open : true } );
get_state( 'chatroom_a', function(state) { console.log(state) } );
I was wondering how to implement user presence with PubNub in Rails apps, but I didn't find a complete guide to how to implement this feature in both server and client side.
PubNub Presence with Ruby and JavaScript
Get started easily with PubNub Presence in Ruby and JavaScript by following this short guide which connects the state between the two PubNub SDKs. First you'll want to make sure you have the latest PubNub Ruby GEM client SDK install on your server. But before we get into the coding aspect we can talk about what PubNub Presence actually is.
PubNub Presence Introduction
PubNub Presence allows you to ask the question "Who is there?" and receive back an answer in the form of a List of UserIDs and an occupancy count of who is currently online right now.
Usually you ask this question in the context of a PubNub Channel. User's connect to a PubNub Channel in order to receive a stream of data from the PubNub Network. You control the stream by way of Channels by publishing and subscribing to channels by any valid UTF-8 string. Sometimes you want to know the current state of the PubNub Channel by requesting the current activity and list of connected users on the channel. You can do this by using PubNub Presence feature which provides the answer you seek.
PubNub Presence SDKs
Let's get starte by listing the two starting steps of including/loading the GEM ans JavaScript SDKs for your target platforms (This time it's Ruby+JavaScript Combo).
Install PubNub Ruby GEM
sudo gem install pubnub
Next you will ensure that you are running one of the latest JavaScript SDKs on your JavaScript Client App (usually a mobile phone app or website app).
Include PubNub JavaScript Client SDK
<script src=http://cdn.pubnub.com/pubnub-3.4.2.min.js ></script>
Now that you have accessed the two necessary base SDK libs for Ruby and JavaScript, you are able to receive/transmit information freely over the PubNub Network. Next we'll talk about how you can easily receive presence events as they occur on your PubNub Channel and also how you can query directly for the current channel state with here_now() API.
PubNub Dev Console - Presence
Use the PubNub Developer's Console to Monitor Presence Events.
You can use the PubNub Developer's Console to watch Presence Events as they occur. You will be able to see the event payload in JSON form in the presence section which is shown in the following image:
There are three events "action"s you can receive including:
"join" - A new user joined the channel.
"leave" - A user left the channel.
"timeout" - A user dropped connection and timed out.
PubNub Presence with REST
PubNub Here Now
With PubNub Presence you have access to TWO REST routes. The easiest route is the here_now() route.
PubNub Presence with SDKs
Example Source Code in JavaScript
The following is an example of method in JavaScript to receive data on a Channel and also receive Presence Events for that channel as they occur in real-time. Also you will notice the paramaters that are passed to you in your Function Callback. This method allows you to receive a stream of data into your JavaScript Application. Note there is a second method to receive presence data (called here_now()) which we will cover a bit further down.
<script>(function(){
var pubnub = PUBNUB.init({
subscribe_key : 'demo'
});
pubnub.subscribe({
channel : "hello_world", // YOUR CHANNEL.
message : function( message, env, channel ) {}, // RECEIVE MESSAGE.
presence : function( message, env, channel ) { // PRESENCE EVENTS.
console.log( "Channel: ", channel );
console.log( "Join/Leave/Timeout: ", message.action );
console.log( "Occupancy: ", message.occupancy );
console.log( "User ID: ", message.uuid );
}
})
})();</script>
Example Source Code in Ruby
Here is Ruby Code which is the ruby method to receive Presence Events in real-time as they occur. You can process the stream or (Firehose) of events as they come in. Note there is a second method to receive presence data (called here_now()) which we will cover a bit further down.
require 'pubnub'
pubnub = Pubnub.new(
:publish_key => 'demo', # publish_key only required if publishing.
:subscribe_key => 'demo', # required
:secret_key => nil, # optional, if used, message signing is enabled
:cipher_key => nil, # optional, if used, encryption is enabled
:ssl => nil # true or default is false
)
## Receive Presence Events on a Channel
pubnub.presence(
:channel => :hello_world,
:callback => lambda { |event_data| puts(event_data) }
)
When an event occurs (such as a user joining) the output data will look like:
{"action":"join", "timestamp":1364261400, "uuid":"9d497a30-3af2-4b67-a6b3-82f254711c11", "occupancy":4}
on a User Disconnect, the presence event is triggered as:
{"action":"leave", "timestamp":1364251540, "uuid":"9d497a30-3af2-4b67-a6b3-82f254711c11", "occupancy":3}
and potentially in the event of an error/timeout:
{"action":"timeout", "timestamp":1364251540, "uuid":"9d497a30-3af2-4b67-a6b3-82f254711c11", "occupancy":3}
Here_Now in JavaScript
There is a here_now() function available to you that allows you to issue a single REST request to the PubNub Network that gets the Current state of a channel's connectivity. The request looks like:
<script>(function(){
var pubnub = PUBNUB.init({
subscribe_key : 'demo'
});
pubnub.here_now({
channel : 'hello_world',
callback : function (message) { console.log(message) }
});
})();</script>
and the response object will look like:
{"uuids":["754e58b3-a79b-4d91-8f6c-5d994e43a310","175c2c67-b2a9-470d-8f4b-1db94f90e39e","fafd273d-9be5-4049-a6ce-653c467f7c5d"],"occupancy":3}
Here_Now in Ruby
Just like in JavaScript the same function for here_now() is available in Ruby too. Here is the ruby syntax version:
require 'pubnub'
pubnub = Pubnub.new(
:publish_key => 'demo', # publish_key only required if publishing.
:subscribe_key => 'demo', # required
:secret_key => nil, # optional, if used, message signing is enabled
:cipher_key => nil, # optional, if used, encryption is enabled
:ssl => nil # true or default is false
)
pubnub.here_now(
:channel => :hello_world,
:callback => lambda { |event_data| puts(event_data) }
)
And the response object data is identical to what is available to you in JavaScript.
{"uuids":["754e58b3-a79b-4d91-8f6c-5d994e43a310","175c2c67-b2a9-470d-8f4b-1db94f90e39e","fafd273d-9be5-4049-a6ce-653c467f7c5d"],"occupancy":3}
Finally if you want to use the simple JSON REST interface provided by the PubNub Network, you can issue the following requests easily:
curl http://pubsub.pubnub.com/v2/presence/sub_key/demo/channel/hello_world
and the response output is identical:
{"uuids":["754e58b3-a79b-4d91-8f6c-5d994e43a310","175c2c67-b2a9-470d-8f4b-1db94f90e39e","fafd273d-9be5-4049-a6ce-653c467f7c5d"],"occupancy":3}
That's it! Super simple and easy to use PubNub Network Presence with Ruby on Rails and JavaScript. If you have any questions please contact PubNub directly and also visit the following links for more details:
PubNub Network Ruby SDK - https://github.com/pubnub/ruby
PubNub Network JavaScript SDK - https://github.com/pubnub/javascript#simple-example