Twilio - channel descriptor paginator order - twilio

I want to retrieve the list of channels for a user containing unread messages. The best solution I have found so far (please correct me if I'm wrong) is using channel descriptors.
// Example for a single page
client.getUserChannelDescriptors().then(function(paginator) {
for (var i = 0; i < paginator.items.length; i++) {
var descriptor = paginator.items[i].descriptor;
if (descriptor.unread_messages_count > 0) {
console.log("Channel found, id: " + descriptor.uniqueName);
}
}
});
My question: is there a way to order in the paginator object so I could retrieve channels with unread messages first so I wouldn't have to go through the whole list of channels?

Twilio developer evangelist here.
You can sort channels, but not with getUserChannelDescriptors. Instead, you need to make sure you've loaded all the subscribed channels and then you can sort them with getLocalChannels.
From the docs:
getLocalChannels( [sortingOptions])
Get array of Channels locally known to Client in provided sorting order. Locally known channels are the ones created and/or joined during client runtime and currently logged in User subscribed Channels. To ensure full list of subscribed Channels fetched - call the Client#getSubscribedChannels method and fetch all pages with help of Paginator#nextPage method.
The sorting options then allow you to sort by lastmessage.

Related

Twilio SWIFT API get consumed messages always returns 0

I want to display next to a chat channel the number of messages a channel has that have been unconsumed or unread (I assume this is what unconsumed means?)
Currently I send messages to a channel that two users are subscribed to , a private chat. Then before opening up the chat window I check the channel for unconsumed messages, but it always say 0 messages even if I call setNoMessagesConsumedWithCompletion.
I am using the Swift API...What do I need to do to find out how many messages in my channel have not been read yet? At what point do they become read? (when the user opens up a chat channel and requests to getLastWithCount?)
I read in the docs you have to set something called the consumption horizon to get unconsumed message, but I don't know how you do that in SWIFT API https://www.twilio.com/docs/chat/consumption-horizon also this was for Javascript API so perhaps it is easier with Swift Api?
I figured out the solution. As per the documentation you need to update the last consumed message index. So for example if the user has a chat window open you need to record for that user (or instance of the Chat Client) what was the last message they saw before they close their chat. I am storing all the messages in a message array and update the last consumed message index with the length of the array of messages:
generalChannel?.messages?.setLastConsumedMessageIndex(NSNumber.init(value: self.messages.count), completion: { (result, count) in
if !result.isSuccessful() {
print(result.error.debugDescription)
}
})
Then if you send messages to that channel when the user is not in the channel these will be recorded as unconsumed, you can get the number by calling:
channel.getUnconsumedMessagesCount(completion: { (results, numberUnconsumed) in
print(numberUnconsumed)
})

Twilio Chat getChannels order by most recent message

In twilio chat, is there a way to specify an order to the getChannels() method? Or is there a property on the Channel object that will tell me when the last message sent on that channel was? The dateUpdated property on Channel seems to be when properties on the channel were updated, not including messages sent/received.
I would like to order my channels list by the most recent messages. And I would like to do this without having to retrieve all the messages first.
You can add the attributes parameter upon updating a channel.
An optional string metadata field you can use to store any data you
wish.
You could track time/date info of messages here.
# Update the channel
service = client.services.get(sid="CHANNEL_SID")
channel = service.channels.create()
response = channel.update(friendly_name="NEW_FRIENDLY_NAME", attributes="ANY_DATA_YOU_WISH")
print(response)
You should then be able to subscribe to a channel event (JavaScript SDK example). As you did not specify what language you're using you will also find more details in the API Docs for iOS and Android SDKs as well.
// A channel's attributes or metadata have changed.
messagingClient.on('channelUpdated', function(channel) {
console.log('Channel updates: ' + channel.sid);
});

How can a Slack bot detect a direct message vs a message in a channel?

TL;DR: Via the Slack APIs, how can I differentiate between a message in a channel vs a direct message?
I have a working Slack bot using the RTM API, let's call it Edi. And it works great as long as all commands start with "#edi"; e.g. "#edi help". It currently responses to any channel it's a member of and direct messages. However, I'd like to update the bot so that when it's a direct message, there won't be a need to start a command with "#edi"; e.g. "#edi help" in a channel, but "help" in a direct message. I don't see anything specific to differentiate between the two, but I did try using the channel.info endpoint and counting the number of people in "members"; however, this method only works on public channel. For private channels and direct messages, the endpoint returns an "channel_not_found" error.
Thanks in advance.
I talked to James at Slack and he gave me a simply way to determine if a message is a DM or not; if a channel ID begins with a:
C, it's a public channel
D, it's a DM with the user
G, it's either a private channel or multi-person DM
However, these values aren't set in stone and could change at some point, or be added to.
So if that syntax goes away, another way to detect a DM to use both channels.info and groups.info. If they both return “false” for the “ok” field, then you know it’s a DM.
Note:
channels.info is for public channels only
groups.info is for private channels and multi-person DMs only
Bonus info:
Once you detect a that a message is a DM, use either the user ID or channel ID and search for it in the results of im.list; if you find it, then you’ll know it’s a DM to the bot.
“id” from im.list is the channel ID
“user” from im.list is the user ID from the person DM’ing with the bot
You don’t pass in the bot’s user ID, because it’s extracted from the token
FYI as of July 2017, for "message.im" events (via your app's Event Subscriptions), the event payload seems to now return additional fields to detect if the message is coming from your own bot (pasted in here from my logs):
INFO[0012] got Slack message: (bot.SlackMessage) {
SlackEvent: (bot.SlackEvent) {
Type: (string) (len=7) "message",
EventTs: (string) (len=17) "1501076832.063834",
User: (string) ""
},
SubType: (string) (len=11) "bot_message",
Channel: (string) (len=9) "D6CJWD132",
Text: (string) (len=20) "this is my bot reply",
Username: (string) (len=15) "Myapp Local",
BotID: (string) (len=9) "B6DAZKTGG",
Ts: (string) (len=17) "1501076832.063834"
}
Slack have added Conversations API some time ago. You should use it to differentiate between PM/channel instead of relying on prefix.
From Conversations API documentation:
Each channel has a unique-to-the-team ID that begins with a single letter prefix, either C, G, or D. When a channel is shared across teams (see Developing for Shared Channels), the prefix of the channel ID may be changed, e.g. a private channel with ID G0987654321 may become ID C0987654321.
This is one reason you should use the conversations methods instead of the previous API methods! You cannot rely on a private shared channel's unique ID remaining constant during its entire lifetime.
Get conversation info using conversations.info method and check is_im flag. is_im == true means that the conversation is a direct message between two distinguished individuals or a user and a bot.
The info function is also available for private channels with the Slack API method groups.info. This works also for direct message channels with multiple participants, since they are a special form of private channels.
You can use groups.list to get the IDs of all private channels incl. direct message channels with multiple participants.
Note that groups.list will only return private channels, that the user or bot that the access token belongs to has been invited to.

Get related subscribed channel(s) in didReceiveStatus in PubNub for iOS objective C

When didReceiveStatus is called after subscribing to a channel, We are not able to retrieve the channel(s) that was just subscribed.
PNSubscribeStatus.data.subscribedChannel or PNSubscribeStatus.data.actualChannel are always null and PNSubscribeStatus.subscribedChannels gives all currently subscribed channels and not the ones that triggered the didReceiveStatus callback.
What are we doing wrong here ?
In SDK 4.0, didReceiveStatus returns a PNStatus, which according to the class documentation doesn't contain that extra information unless there's an error condition. For our application, we use that handler to monitor connection status to the PubNub server.
PubNub Message Received Channel Name in iOS
You should be able to get the channel that you received the message on but getting it depends on whether you are subscribed to the channel or to a channel group that contains the channel. This is sample code from the PubNub Objective-C for iOS SDK subscribe API Reference:
- (void)client:(PubNub *)client didReceiveMessage:(PNMessageResult *)message {
// Handle new message stored in message.data.message
if (message.data.actualChannel) {
// Message has been received on channel group stored in
// message.data.subscribedChannel
}
else {
// Message has been received on channel stored in
// message.data.subscribedChannel
}
NSLog(#"Received message: %# on channel %# at %#", message.data.message,
message.data.subscribedChannel, message.data.timetoken);
}
If you need other channels that the client is subscribed to, you can call the where-now API.
If you need to be more dynamic about what the reply-to channel should be, then just include that channel name in the message when it is published, assuming the publisher has prior knowledge about which channel this is. Or you can do a just in time lookup on your server as to which channel to reply to.
Here is PubNub support answer on this :
Actually status.data.subscribedChannel and status.data.actualChannel
dedicated to presence events and messages receiving callbacks where
information about sources of event is important.
In -client:didReceiveStatus: client doesn’t give information about
particular channel on which client has been subscribed. If client will
start track this information, there is no guarantee what it will
return expected value (as developer expect some channels to be there).
In previous version (3.x) all this information has been tracked, but
because it can be modified at any moment – result sometimes was
unpredictable.
Subscribe can be done in sequence of methods (one after another) like:
subscribe A1, subscribe C1, subscribe B1 and B2, unsubscribe C1 and B1
– this as result will end up with single call of
-client:didReceiveStatus: with resulting set of channels.
It always best practice just to check whether your channels is in
s_tatus.subscribedChannels_.
My comments:
The point of having asynchronous process is exactly not to think this as sequence of methods... We can not have the guaranty that subscriptions are done in the exact same order as the subscription request unless we block other subscription request until the previous one is done.

How can I get all my subscribed channel using youtube api v3

I'm new to youtube api v3, and I have a problem when get all my subscribed channel. I've subscribed 65 channel but I can only get 50 each api call. So, Is there any way to get all?
Another thing is, I have a channelID, is there any api to check this channel in a list of my subscribed channel?
Youtube API restricts 50 results per call. In case you were asking whether you can get all 65 in the same call, then the answer is no. However, if you meant whether all 65 can be retrieved then, yes. You'll need to use the nextPageToken paramter value and pass it to the pageToken parameter which will take you to the next page. In code, it can be handled in the following way(as shown in the documentation):
var nextPageToken = '';
// This loop retrieves a set of playlist items and checks the nextPageToken
// in the response to determine whether the list contains additional items.
// It repeats that process until it has retrieved all of the items in the list.
while (nextPageToken != null) {
var playlistResponse = YouTube.PlaylistItems.list('snippet', {
playlistId: playlistId,
maxResults: 25,
pageToken: nextPageToken
});
Regarding your ChannelID problem, from your description I understand you want to check whether you are subscribed to a particular channel in case you have it's ID. I believe the Activities method of Youtube API should be able to help you out. Look at contentDetails.subscription property. I hope that resolves your problem.

Resources