Agora - Is there anyway I can know how many users currently joined in channel? - agora.io

I would like to know the total number of users currently in the same channel. This is a crucial information I believe.
Scenario
Caller initiates call by joining the channel -> A push goes to receiver -> Caller decides to leave call/channel before receiver joins. When the receiver reacts to push and joins the channel, sees no one in that channel. If I had a way to tell the receiver that there's no one in that channel at the moment then the receiver could be notified with dialog or some sort.
Note: without using the RTM library. Can this be done with RTC only?

You can use the RESTful API to get a list of users in the channel: https://docs.agora.io/en/Agora%20Platform/dashboard_restful_communication?platform=All%20Platforms#gets-the-user-list-in-a-channel-get
You can also implement the Agora RTM SDK together with Agora RTC SDK and implement the logic for users to join the same channel as using Agora RTC SDK. And call getMembers method to get a list of users in the RTM channel.
Here is the API document for getMembers method: https://docs.agora.io/en/Real-time-Messaging/API%20Reference/RTM_java/classio_1_1agora_1_1rtm_1_1_rtm_channel.html#a567aca5f866cf71c3b679ae09b4bf626
Here is a quick start guide for the RTM SDK: https://docs.agora.io/en/Real-time-Messaging/messaging_android?platform=Android

While using agora rtm for messaging,We can use getMembers() functionality which is provided by agora to get the active people in a channel in agora.I am defining it using javascript below for reference.
In javascript,Define a function GetMembers()-->
name='The channel Name of your channel';
function GetMembers(name)
{
rtm.channels[name].channel.getMembers().then((memberNames)=>{
/* memberNames contains an array of the names of the members*/
})
}
Call the GetMembers() function wherever it is required to get the names of the active members.

You can get the list of joined members using getMembers method of agora rtm. Remember it also gives your own id if you are logged in. This method return array.
GetChannelMembersList()
{
channel.getMembers().then(async (memberNames)=>{
console.log(memberNames, 'memberNames');
for (let index = 0; index < memberNames.length; index++) {
const user = await rtm.client.getUserAttributes(memberNames[index].toString());
console.log(user, 'user'); // To find more details of joined user
}
})
}

Related

Kotlin for Volley, how can I check the JSON request for newer data in the API?

I'm working on an app that gets a list of documents/source URL from an api. I'd like to periodically check for new or updated contents within that API so users can update saved items in the database. I'm at a loss on the correct wording to search, thus Google and Stack Overflow have both failed me. My fetching function is below:
The URL for the API is https://api.afiexplorer.com
private fun fetchPubs() {
_binding.contentMain.loading.visibility = View.VISIBLE
request = JsonArrayRequest(
Request.Method.GET,
Config.BASE_URL,
JSONArray(),{ response ->
val items: List<Pubs> =
Gson().fromJson(response.toString(), object : TypeToken<List<Pubs>>() {}.type)
val sortedItems = items.sortedWith(compareBy { it.Number })
pubsList?.clear()
pubsList?.addAll(sortedItems)
// Hardcoded pubs moved to Publications Gitlab Repo
// https://gitlab.com/afi-explorer/pubs
_binding.contentMain.recyclerView.recycledViewPool.clear()
adapter?.notifyDataSetChanged()
_binding.contentMain.loading.visibility = View.GONE
setupData()
Log.i("LENGTH OF DATA", "${items.size}")
},
{error ->
println(error.printStackTrace())
Toasty.error(applicationContext, getString(string.no_internet), Toast.LENGTH_SHORT, true).show()
}
)
MyApplication.instance.addToRequestQueue(request!!)
}
private fun setupData(){
adapter = MainAdapter(applicationContext, pubsList!!, this)
_binding.contentMain.recyclerView.adapter = adapter
}
I tried using ChatGPT to see if that would get me started and that failed miserably. Also searched Google, Reddit and Stack Overflow for similar projects, but mine is a unique scenario I guess. I'm just a hobbyist and intermediate dev I guess. First time working with Volley, everything works, but I would like to find a way to send a notification (preferably not Firebase) if there is updated info within the API listed above. I'm not sure if this is actually doable.
Are you asking if you can somehow find if the remote API has changed its content? If so, how would that service advise you? If the service provider provides a web hook or similar callback you could write a server-based program to send a push notification to your Android app.
Perhaps you intent to poll the API periodically, and then you want to know if there is a change?
If you use a tool such as Postman or curl to easily see the headers of the API https://api.afiexplorer.com you will see, unfortunately, there is no Last-Modified header or ETag header which would allow you to easily determine if there was a change.
Next looking at the content of the API, the author does not provide an obvious version/change date, so no luck there.
What you could do is receive the content as a String, and perform a checksum operation on it, and if it differs you know there has been a change
or if you are deserialising the received JSON in Kotlin data classes, then out of the box, Kotlin will enable you to perform an equality operation on a previous copy of the data to know if there was a change.
This looks like an android app; if so, why don't you create a background service that makes requests to the API and updates the data as needed? You can use an AlarmManager class to set the interval threshold for polling by using the setInexactRepeating() method.
Most apps are updated in this fashion; sometimes, a separate table is created to catalog changesets.
Let me know if this helps.

Which chat api has a good Search function?

I am developing a web app that is used for professional service professionals (accountants) to create shared workspaces (portals) for each client. These workspaces need a real-time Slack-like conversation across accountant and client -- and a key requirement is to be able to search the message history. I've looked at PubNub ChatEngine, Twilio, TalkJS, Applozic, Sendbird etc. but can't seem to find even one with this Search capability. Any suggestions?
With PubNub ChatEngine, you can use JavaScript to get past messages in a particular chat. You can write a few lines of JavaScript to filter the messages that are returned. For your use case, you would filter for your search input.
The documentation for this feature is here.
chat.search({
event: 'message',
sender: ChatEngine.me, // You can filter on a specific sender
limit: 20, // You can make a limit for the number of messages to recall and search through
start: "14375189629170609", // Optional beginning time token of messages to search through
end: "14375189629999999"
}).on('message', (event) => {
// Filter messages based on search input
}).on('$.search.finish', () => {
console.log('we have all our results!')
});

Leave a conversation with Skype Web SDK on page reload

We're building a web application using the Skype Web SDK (https://msdn.microsoft.com/en-us/skype/websdk/docs/skypewebsdk). We use both the audio and the IM capability to get connected to other parties.
Currently we're facing the following problem: If our application is in a conversation with another party (e. g. with a Skype for Business desktop client) and the user leaves or reloads the page, the other party doesn't get notified about the left user.
For audio conversations the result is the following: The other party is still in the call and the only indication of the leaving is that the other party can't hear anything.
For IM conversations the result is the following: If the other party sends an IM in this conversation it gets the notification that the message couldn't be delivered.
We've tried to leave the conversation before the unload of the page using the onbeforeunload event. The callback is executed both in IE 11 and Chrome, but only in Chrome the user actually leaves the conversation (tested with IM conversation since audio/video is not supported in Chrome).
window.onbeforeunload = function() {
// conversation is the conversation we're currently in
conversation.leave().then(function () {
client.conversationsManager.conversations.remove(conversation);
});
};
Since we rely on the audio capability we're not able to simply switch to Chrome only. Is there any way to ensure that the conversations are cleaned up on page reload/leave in Internet Explorer?
The problem with what you are trying to do is that the (on)beforeunload event does not wait around for asynchronous methods to complete so you are not guaranteed that leave() will execute nor the inner action to remove the conversation from the conversationsManager. I would suggest an approach similar to the following question - onbeforeunload confirmation screen customization or beforeunload
What you want to do is put the user into a state where the need to interact with a dialog which may (but also not guaranteed) give enough cycles to leave the conversation. In your case it might look something like the following:
window.onbeforeunload = function(e) {
// track if a conversation is live
if (_inActiveConversation) {
// conversation is the conversation we're currently in
conversation.leave().then(function () {
client.conversationsManager.conversations.remove(conversation);
});
var msg = 'Cleaning up active conversations...';
e.returnValue = msg;
return msg;
}
};
What you should also understand is that eventually the server side will remove that user from the conversation because the application is no longer processing incoming events. So the above is a best effort to clean up resources that will eventually be reclaimed.
You could also try to issuing a signOut request on the signInManager as that should allow the server to clean up resources related to that application on the server side.
window.onbeforeunload = function() {
...
_client.signInManager.signOut();
...
};

GCM 3.0: New registration does not expire tokens registered with GCMRegistrar

We are switching our notifications infrastructure to use new GCM 3.0 registration mechanism using Instance ID API. Previously we were using old mechanism using GCMRegistrar.register() method.
The problem we have is that we have noticed that if device was registered with old GCMRegistrar, after update and registering with new Instance ID API, both registration tokens are valid and can receive notifications.
I expected old registration token to be deactivated and that our push server would receive canonical registration ID when sending notification to old token (as described here GCM registering with two different working registration ids), especially that application version has changed, but such case seems not to happen.
Is this correct behavior of GCM? Is there any way we can detect on push server that device received new token (without unregistering from app)?
I have finally received an answer from Google support regarding my issue. It turned out that this was intended behavior:
What you observed is in the intended behavior due to the need to support backward compatible
registration ID.
We recommend you to flag the old registration ID from gcmregistrar() and don't use that to send anymore once you have the registration token from getToken(). (I believe you probably has implemented a solution to detect such)
Our solution was to simply remove old registration tokens from our push server before registering new user.
We did not use GCMRegistrar.unregister() as we observed that it was able to unregister new tokens (obtained via getToken()).
UPDATE:
I just wanted to provide a quick update to anyone interested in this subject.
It seems that this issue was fixed as when we tested our registration mechanism recently, it turned out that new GCM tokens replace (and unregister) old tokens.
Registration token may change upon certain scenarios even going forward. While cononical registration ID is also a good idea. Use tokenRefresh as shown here as well.
#Override
public void onTokenRefresh() {
// Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
Suggesting based on this line "it is needed for key rotation and to handle special cases" in method reference.

IBM Worklight: Extend Server-side Java Code

Can I extend the server-side Java Code in Worklight?
For example, there is a class called JavaScriptIntegrationLibraryImplementation under com.worklight.integration.js. Inside this class, there is a method broadcastNotification and I would like to override this method. Is it possible to do so?
EDIT
The reason is that:
When I make the subscription in client side with option field (e.g. add customType: A), I would like to retrieve a list of devices which have been subscribed to this event source. Base on the option field in deviceSubscrpition, I would like to have some business logic to determine who to send the notification message. For example, I will only submit the message to the user which 'customType=A'.
However, there is no API in Worklight which can retrieve a list of devices which make me to retrieve the list first. Then do the logic in JavaScript and called WL.Server.notifyDevice..
Therefore, I would like to check whether there is any method to retrieve a list of devices (through API / Adapter which connects to DB) which have subscribed to an event source.
Thanks.
This part of Worklight is not extendable. You can try and override this method as you say, but do note this is not supported and we cannot help in this case.
Edit
Now that it is clear what you're trying to achieve... what you are looking for currently not available. I will open a feature request for it and it will get evaluated at some point (if you are a customer of IBM, I suggest to get in touch with your contact...).
My suggestion (somewhat hackish in form): you could perhaps use multiple Event Sources, where each event source represents an iOS version. On the client-side, upon app initialization, you can retrieve the iOS version and use it to register to the correct event source (this would be very generic code to allow re-use). In case a new iOS version is released (you will likely know of this in advance), you simply add this event source to the adapter code and re-deploy the adapter. Users of the new iOS version could still register for notification, because you get the iOS version upon init, and use this information to register to the correct event source...
To reiterate:
The adapter contains: ES_iOS5 ES_iOS6
The client:
fetches iOS version, stores it in some variable.
registers to event source, where event source name is ES_${iOSVersion}
if a new iOS version is released, simply create a new event source and re-deploy
the adapter; the client is already equipped to handle this.
#Red23jordon,
i had similar case, i created a custom table where at the time of subscription, I was saving
user ID and event type in custom table. and when user unsubscribe then i also remove details from custom table.
For sending push to users subscribed to a particular "even type" i look into custom table to get list of user IDs subscribed to particular event type, and then i went into Notification user/device tables and fetching corresponding devices and sending Push.
Hope it may help you.
thanks