Skip to content

Commit

Permalink
add custom content types for preparing a message
Browse files Browse the repository at this point in the history
  • Loading branch information
nplasterer committed Dec 16, 2024
1 parent d8d37aa commit 8f85a16
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,26 @@ class XMTPModule : Module() {
}
}

AsyncFunction("prepareEncodedMessage") Coroutine { installationId: String, conversationId: String, encodedContentData: List<Int> ->
withContext(Dispatchers.IO) {
logV("prepareEncodedMessage")
val client = clients[installationId] ?: throw XMTPException("No client")
val conversation = client.findConversation(conversationId)
?: throw XMTPException("no conversation found for $conversationId")
val encodedContentDataBytes =
encodedContentData.foldIndexed(ByteArray(encodedContentData.size)) { i, a, v ->
a.apply {
set(
i,
v.toByte()
)
}
}
val encodedContent = EncodedContent.parseFrom(encodedContentDataBytes)
conversation.prepareMessage(encodedContent = encodedContent)
}
}

AsyncFunction("findOrCreateDm") Coroutine { installationId: String, peerAddress: String ->
withContext(Dispatchers.IO) {
logV("findOrCreateDm")
Expand Down
19 changes: 19 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,25 @@ export async function prepareMessage(
)
}

export async function prepareMessageWithContentType<T>(
installationId: InstallationId,
conversationId: ConversationId,
content: any,
codec: ContentCodec<T>
): Promise<MessageId> {
if ('contentKey' in codec) {
return prepareMessage(installationId, conversationId, content)
}
const encodedContent = codec.encode(content)
encodedContent.fallback = codec.fallback(content)
const encodedContentData = EncodedContent.encode(encodedContent).finish()
return await XMTPModule.prepareEncodedMessage(
installationId,
conversationId,
Array.from(encodedContentData)
)
}

export async function findOrCreateDm<
ContentTypes extends DefaultContentTypes = DefaultContentTypes,
>(
Expand Down
4 changes: 4 additions & 0 deletions src/lib/Conversation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ export interface ConversationBase<ContentTypes extends DefaultContentTypes> {
content: ConversationSendPayload<SendContentTypes>,
opts?: SendOptions
): Promise<MessageId>
prepareMessage<SendContentTypes extends DefaultContentTypes = ContentTypes>(
content: ConversationSendPayload<SendContentTypes>,
opts?: SendOptions
): Promise<MessageId>
sync()
messages(opts?: MessagesOptions): Promise<DecodedMessageUnion<ContentTypes>[]>
streamMessages(
Expand Down
33 changes: 28 additions & 5 deletions src/lib/Dm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,13 @@ export class Dm<ContentTypes extends DefaultContentTypes = DefaultContentTypes>
*/
async prepareMessage<
SendContentTypes extends DefaultContentTypes = ContentTypes,
>(content: ConversationSendPayload<SendContentTypes>): Promise<string> {
// TODO: Enable other content types
// if (opts && opts.contentType) {
// return await this._sendWithJSCodec(content, opts.contentType)
// }
>(
content: ConversationSendPayload<SendContentTypes>,
opts?: SendOptions
): Promise<MessageId> {
if (opts && opts.contentType) {
return await this._prepareWithJSCodec(content, opts.contentType)
}

try {
if (typeof content === 'string') {
Expand All @@ -135,6 +137,27 @@ export class Dm<ContentTypes extends DefaultContentTypes = DefaultContentTypes>
}
}

private async _prepareWithJSCodec<T>(
content: T,
contentType: XMTP.ContentTypeId
): Promise<MessageId> {
const codec =
this.client.codecRegistry[
`${contentType.authorityId}/${contentType.typeId}:${contentType.versionMajor}.${contentType.versionMinor}`
]

if (!codec) {
throw new Error(`no codec found for: ${contentType}`)
}

return await XMTP.prepareMessageWithContentType(
this.client.installationId,
this.id,
content,
codec
)
}

/**
* Publish all prepared messages.
*
Expand Down
37 changes: 30 additions & 7 deletions src/lib/Group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export class Group<
* Sends a message to the current group.
*
* @param {string | MessageContent} content - The content of the message. It can be either a string or a structured MessageContent object.
* @returns {Promise<string>} A Promise that resolves to a string identifier for the sent message.
* @returns {Promise<MessageId>} A Promise that resolves to a string identifier for the sent message.
* @throws {Error} Throws an error if there is an issue with sending the message.
*/
async send<SendContentTypes extends DefaultContentTypes = ContentTypes>(
Expand Down Expand Up @@ -136,16 +136,18 @@ export class Group<
* Prepare a group message to be sent.
*
* @param {string | MessageContent} content - The content of the message. It can be either a string or a structured MessageContent object.
* @returns {Promise<string>} A Promise that resolves to a string identifier for the prepared message to be sent.
* @returns {Promise<MessageId>} A Promise that resolves to a string identifier for the prepared message to be sent.
* @throws {Error} Throws an error if there is an issue with sending the message.
*/
async prepareMessage<
SendContentTypes extends DefaultContentTypes = ContentTypes,
>(content: ConversationSendPayload<SendContentTypes>): Promise<string> {
// TODO: Enable other content types
// if (opts && opts.contentType) {
// return await this._sendWithJSCodec(content, opts.contentType)
// }
>(
content: ConversationSendPayload<SendContentTypes>,
opts?: SendOptions
): Promise<MessageId> {
if (opts && opts.contentType) {
return await this._prepareWithJSCodec(content, opts.contentType)
}

try {
if (typeof content === 'string') {
Expand All @@ -163,6 +165,27 @@ export class Group<
}
}

private async _prepareWithJSCodec<T>(
content: T,
contentType: XMTP.ContentTypeId
): Promise<MessageId> {
const codec =
this.client.codecRegistry[
`${contentType.authorityId}/${contentType.typeId}:${contentType.versionMajor}.${contentType.versionMinor}`
]

if (!codec) {
throw new Error(`no codec found for: ${contentType}`)
}

return await XMTP.prepareMessageWithContentType(
this.client.installationId,
this.id,
content,
codec
)
}

/**
* Publish all prepared messages.
*
Expand Down

0 comments on commit 8f85a16

Please sign in to comment.