sendDirectMessage method
- String contactUserId, {
- String? text,
- MessageType messageType = MessageType.regular,
- String? referencedMessageId,
- String? reaction,
- String? attachmentUrl,
- Map<
String, dynamic> ? metadata, - String? clientMessageId,
Sends a direct message to a contact (creates a 1:1 room if needed).
Convenience wrapper around rooms.create + messages.send —
the backend resolves or creates the 1:1 room behind the scenes
and returns the message with its real id. Use this on the
"first message in a DM that has never been opened" path; for
subsequent messages in an existing DM prefer
ChatMessagesApi.sendViaWs against the resolved room id (cheaper
— no room-resolution round trip).
If the recipient has blocked the sender the backend answers 204 No Content: the returned ChatMessage is synthesized locally
with ReceiptStatus.sent and ChatMessage.silentlyDropped set to
true, so the caller can show a distinct state (e.g. a single
grey check with no further progress) instead of a normal "sent".
clientMessageId is the idempotency key for the send — same
semantics as ChatMessagesApi.send: auto-generated when omitted,
reused verbatim on offline-queue retries. Under the backend's
ack_mode = async (the default) the returned message is a
provisional echo (ChatMessage.isProvisional true) whose id does
not match the stored message; correlate the authoritative
new_message event via ChatMessage.clientMessageId and never use
a provisional id for follow-up operations.
Implementation
@override
Future<ChatResult<ChatMessage>> sendDirectMessage(
String contactUserId, {
String? text,
MessageType messageType = MessageType.regular,
String? referencedMessageId,
String? reaction,
String? attachmentUrl,
Map<String, dynamic>? metadata,
String? clientMessageId,
}) async {
final msg = ChatMessage(
id: _client._nextMessageId(),
from: _client.currentUserId,
timestamp: DateTime.now(),
text: text,
messageType: messageType,
clientMessageId: clientMessageId,
);
return ChatSuccess(msg);
}