Skip to main content

Remote Attachment Content Type

Remote attachments of any size can be sent using the RemoteAttachmentCodec and a storage provider.

Install the package

npm i @xmtp/content-type-remote-attachment

Import and register

// Import the codecs we're going to use
import {
AttachmentCodec,
RemoteAttachmentCodec,
} from "@xmtp/content-type-remote-attachment";
// Create the XMTP client
const xmtp = await Client.create(signer, { env: "dev" });
// Register the codecs. AttachmentCodec is for local attachments (<1MB)
xmtp.registerCodec(new AttachmentCodec());
//RemoteAttachmentCodec is for remote attachments (>1MB) using thirdweb storage
xmtp.registerCodec(new RemoteAttachmentCodec());

Create an attachment object

// Local file details
const attachment = {
filename: filename,
mimeType: extname,
data: new Uint8Array(data),
};

Encrypt the attachment

Use the RemoteAttachmentCodec.encodeEncrypted to encrypt the attachment:

const encryptedEncoded = await RemoteAttachmentCodec.encodeEncrypted(
attachment,
new AttachmentCodec(),
);

Upload the encrypted attachment

Upload the encrypted attachment anywhere where it will be accessible via an HTTPS GET request. For example, you can use web3.storage:

const { Web3Storage } = require("web3.storage");

class Upload {
constructor(name, data) {
this.name = name;
this.data = data;
}

stream() {
const self = this;
return new ReadableStream({
start(controller) {
controller.enqueue(Buffer.from(self.data));
controller.close();
},
});
}
}

const upload = new Upload("uploadIdOfYourChoice", encryptedEncoded.payload);

const web3Storage = new Web3Storage({
token: "YOURTOKENHERE",
});

const cid = await web3Storage.put([upload]);
const url = `https://${cid}.ipfs.w3s.link/uploadIdOfYourChoice`;

Create a remote attachment

Now that you have a url, you can create a RemoteAttachment.

const remoteAttachment = {
url: url,
contentDigest: encryptedEncoded.digest,
salt: encryptedEncoded.salt,
nonce: encryptedEncoded.nonce,
secret: encryptedEncoded.secret,
scheme: "https://",
filename: attachment.filename,
contentLength: attachment.data.byteLength,
};

Send a remote attachment

Now that you have a remote attachment, you can send it:

await conversation.send(remoteAttachment, {
contentType: ContentTypeRemoteAttachment,
});

Download, decrypt, and decode the attachment

Now that you can receive a remote attachment, you need a way to receive a remote attachment. For example:

if (message.contentType.sameAs(RemoteAttachmentContentType)) {
const attachment = await RemoteAttachmentCodec.load(message.content, client);
}
  • You now have the original attachment:
attachment.filename // => "screenshot.png"
attachment.mimeType // => "image/png",
attachment.data // => [the PNG data]

Create a preview attachment object

Once you have the attachment object created, you can also create a preview for what to show in a message input before sending:

URL.createObjectURL(
new Blob([Buffer.from(attachment.data)], {
type: attachment.mimeType,
}),
),

Was the information on this page helpful?
powered by XMTP