How to see if a twilio message has been read? - next.js

I have a nextjs project and I integrated twilio programmable chat. It basically works. Next step is to add notifications and I have very big problems due to the not updated or lack of doc. I tried this guide for web push notifications but I gave it up because after the step7 I don't know what to do and can't find anything about it.
What I want to do now is to get the status of the messages and eventually update them once I read them. First of all is it possible to do it? I don't find anything about twilio web notifications on the internet.
For example if I want to get the messages of a specific room I do as follows:
const response = await getTwilioClient(token, unique_room_name);
const messages = await response.channel.getMessages(MESSAGES_LIMIT);
messages has the following shape:
{
hasNextPage: boolean,
hasPrevPage: boolean,
items: Message[],
nextPage: () => Message[],
prevPage: () => Message[],
}
And Message looks like this:
So how can I see the status of a message?

Message read status is actually stored on the Member object. A Member is the object that represents a User in a Channel and it has a lastConsumedMessageIndex property which relates to the last message they read.
In order to read the lastConsumedMessageIndex property, you need to set where the member has read up to, using the Channel methods advanceLastConsumedMessageIndex, setAllMessagesConsumed or setNoMessagesConsumed.
I recommend you read the documentation on the Message Consumption Horizon and Read Status.
As an extra note, I see you're asking questions about Twilio Chat, however Twilio Chat will be coming to the end of life in July 2022. We recommend that you migrate to the Twilio Conversations API instead.

Related

Firebase Cloud Messaging Reports wrong

I am sending cloud-messages to my app but Firebase-CF-Reports tells me that they would not be received:
But I know for sure that some devices do receive them. e.g. my own. So something is going wrong here in the reports.
I read about this problem here and here but I already have an analytics-label that I send with my cloud-message.
This is how I sent my notifications with java-admin-sdk:
Message message = Message.builder()
.setTopic(topic)
.setAndroidConfig(AndroidConfig.builder()
.setPriority(AndroidConfig.Priority.HIGH)
.build())
.setApnsConfig(ApnsConfig.builder()
.setAps(Aps.builder()
.setMutableContent(true)
.setContentAvailable(true)
.build())
.putHeader("apns-push-type", "background")
.putHeader("apns-priority", "5")
.putHeader("apns-topic", "my.bundle.id")
.build())
.putData("\"content\"", contentString)
.putData("\"actionButtons\"", actionButtonsString)
.setFcmOptions(FcmOptions.withAnalyticsLabel("SendToAll"))
.build();
Also interesting is, that If I am not filtering for Platform/Channel (altough still filter only for my android app with Apps=) I get this:
But these numbers still don't make any sense. I also opened some notifications on my own device. And I can't believe that only 18 were received.
Has anyone an idea what I am doing wrong?
I use this fcm-sdk in my flutter app:
firebase_messaging: ^9.1.2
Despite I did not find this in the official documentation, I found information in this discussion in the comments to this answer here. Turns out that subscribing to a topic in FCM is not necessarily permanent. So don't subscribe users to a topic once. Instead do it on every app start, although it is
"not technically necessary. It may depend on your use case. For
example, if you want a global topic where all users are a member of,
you'd have to make sure that they are subscribed to it. Putting the
subscribe method when the app starts guarantees this."
-#AL.
Since I changed that, the Notifications are received by a lot more people than before. Only the open-count is still not working for me. It is always on zero.

Flutter - How can I build chat app that implement read or not read message feature?

I try to make a chat application that has read or not read messages feature. But I truly have no idea how to implement it.
I currently use firestore as the database to store the message.
I use streambuilder to stream the message and rebuild UI every time message is added to the chat room.
Can I have a suggestion on what widget I should be looking for or any ideas on how I can implement it?
What you can do here is create a Firestore collection for the conversation of users. To send a message, store the messages as a document of the conversation collection along with the timestamp and an isRead boolean flag. Also add a sender value since this is where we'll know if the message came from the user or not.
Collection
-- conversation_userA_userB
-- Document
-- message: "Hello"
sender: userA
timestamp: {UNIX_TIME}
isRead: true
-- message: "Hi"
sender: userB
timestamp: {UNIX_TIME}
isRead: false
Once the user has seen the message, update the isRead flag of the message if it came from the other user. The app can listen to the collection using a Stream so the UI can be updated in real-time.

Firestore Timeout [duplicate]

We are building a real-time chat app using Firestore. We need to handle a situation when Internet connection is absent. Basic message sending code looks like this
let newMsgRef = database.document(“/users/\(userId)/messages/\(docId)“)
newMsgRef.setData(payload) { err in
if let error = err {
// handle error
} else {
// handle OK
}
}
When device is connected, everything is working OK. When device is not connected, the callback is not called, and we don't get the error status.
When device goes back online, the record appears in the database and callback triggers, however this solution is not acceptable for us, because in the meantime application could have been terminated and then we will never get the callback and be able to set the status of the message as sent.
We thought that disabling offline persistence (which is on by default) would make it trigger the failure callback immediately, but unexpectedly - it does not.
We also tried to add a timeout after which the send operation would be considered failed, but there is no way to cancel message delivery when the device is back online, as Firestore uses its queue, and that causes more confusion because message is delivered on receiver’s side, while I can’t handle that on sender’s side.
If we could decrease the timeout - it could be a good solution - we would quickly get a success/failure state, but Firebase doesn’t provide such a setting.
A built-in offline cache could be another option, I could treat all writes as successful and rely on Firestore sync mechanism, but if the application was terminated during the offline, message is not delivered.
Ultimately we need a consistent feedback mechanism which would trigger a callback, or provide a way to monitor the message in the queue etc. - so we know for sure that the message has or has not been sent, and when that happened.
The completion callbacks for Firestore are only called when the data has been written (or rejected) on the server. There is no callback for when there is no network connection, as this is considered a normal condition for the Firestore SDK.
Your best option is to detect whether there is a network connection in another way, and then update your UI accordingly. Some relevant search results:
Check for internet connection with Swift
How to check for an active Internet connection on iOS or macOS?
Check for internet connection availability in Swift
As an alternatively, you can check use Firestore's built-in metadata to determine whether messages have been delivered. As shown in the documentation on events for local changes:
Retrieved documents have a metadata.hasPendingWrites property that indicates whether the document has local changes that haven't been written to the backend yet. You can use this property to determine the source of events received by your snapshot listener:
db.collection("cities").document("SF")
.addSnapshotListener { documentSnapshot, error in
guard let document = documentSnapshot else {
print("Error fetching document: \(error!)")
return
}
let source = document.metadata.hasPendingWrites ? "Local" : "Server"
print("\(source) data: \(document.data() ?? [:])")
}
With this you can also show the message correctly in the UI

Queue of Future in dart

I want to implement a chat system.
I am stuck at the point where user sends multiple messgaes really fast. Although all the messages are reached to the server but in any order.
So I thought of implementing a queue where each message shall
First be placed in queue
Wait for its turn
Make the post request on its turn
Wait for around 5 secs for the response from server
If the response arrives within time frame and the status is OK, message sent else message sending failed.
In any case of point 5, the message shall be dequeued and next message shall be given chance.
Now, the major problem is, there could be multiple queues for each chat head or the user we are talking to. How will I implement this? I am really new to dart and flutter. Please help. Thanks!
It sounds like you are describing a Stream - a series of asynchronous events which are ordered.
https://www.dartlang.org/guides/language/language-tour#handling-streams
https://www.dartlang.org/guides/libraries/library-tour#stream
Create a StreamController, and add messages to it as they come in:
var controller = StreamController<String>();
// whenever you have a message
controller.add(message);
Listen on that stream and upload the messages:
await for(var messsage in controller.messages) {
await uploadMessage(message);
}

Issue with Notification and Disconnect

We are trying to upgrade existing app with your framework, other things are working fine like connection/read/write however we are facing issues with Notification/Disconnect
Can you please guide for following scenarios:-
Need call back for disconnection
Notification not working we are not able to receive any notification alert
Is there any method to check characteristics of devices, as we have different devices and some characteristics are not present in all devices, when we try to read/write non present chacraterstics on devices, it throws exception and app crashes
Code :-
connection.writeDescriptor(
Defs.SVC_AUTOMATIONIO_UUID,
Defs.CHAR_AUTOMATION_IO,
Defs.DESC_CLIENT_CHAR_CONFIGURATION_UUID,
BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
)
.subscribe(
this::onWriteSuccess,
this::onWriteFailure
);
connection.setupNotification(iCharUuid)
.flatMap(notificationObservable -> notificationObservable)
.subscribe(
this::onNotificationReceived,
this::onConnectionFailure
);
Thanks
Swayam
In general you don't have to write descriptor manually to enable notifications. The library does it for you.
Try: (example)
rxBleConnection.setupNotification(Defs.DESC_CLIENT_CHAR_CONFIGURATION_UUID)
.flatMap(notificationObservable -> notificationObservable)
.subscribe(this::onNotificationReceived, this::onNotificationSetupFailure);
In order to get callback for disconnection: (example)
You can observe onError from establishConnection method.
You can setup connection status observable
bleDevice.observeConnectionStateChanges().subscribe(this::onConnectionStateChange);
To check characteristics you can go with service discovery: (example)
bleDevice.establishConnection(this, false)
.flatMap(RxBleConnection::discoverServices)
.first() // Disconnect automatically after discovery
.subscribe(this::processDiscoveredServices, this::onConnectionFailure);

Resources