A sample bot that passes simple media attachments (images) to a message.
The minimum prerequisites to run this sample are:
- Latest Node.js with NPM. Download it from here.
- The Bot Framework Emulator. To install the Bot Framework Emulator, download it from here. Please refer to this documentation article to know more about the Bot Framework Emulator.
- [Recommended] Visual Studio Code for IntelliSense and debugging, download it from here for free.
Many messaging channels provide the ability to attach richer objects. Bot Builder lets you express these attachments in a cross channel way and connectors will do their best to render the attachments using the channels native constructs. If you desire more control over the channels rendering of a message you can use Message.sourceEvent to provide attachments using the channels native schema. The types of attachments that can be sent varies by channel but these are the basic types:
- Media and Files: Basic files can be sent by setting contentType to the MIME type of the file and then passing a link to the file in contentUrl.
- Cards and Keyboards: A rich set of visual cards and custom keyboards can by setting contentType to the cards type and then passing the JSON for the card in content. If you use one of the rich card builder classes like HeroCard the attachment will automatically filled in for you.
As a developer, you have three ways to send the attachment. The attachment can be:
- An inline file, by encoding the file as base64 and use it in the contentUrl
- A file uploaded to the channel's store via the Connection API, then using the attachmentId to create the contentUrl
- An externally hosted file, by just specifying the Url of the file (it should be publicly accessible)
It consists on sending the file contents, encoded in base64, along with the message payload. This option works for small files, like icon size images.
You'll need to encode file's content, then set the attachment's contentUrl
as follows:
data:image/png;base64,iVBORw0KGgo…
Checkout app.js to see how to convert a file read using fs.readFile()
and then create the message attachment.
fs.readFile('./images/small-image.png', function (err, data) {
var contentType = 'image/png';
var base64 = Buffer.from(data).toString('base64');
var msg = new builder.Message(session)
.addAttachment({
contentUrl: util.format('data:%s;base64,%s', contentType, base64),
contentType: contentType,
name: 'BotFrameworkLogo.png'
});
session.send(msg);
});
This option should be used when the file to send is less than 256Kb in size when encoded to base64. A good scenario are images generated based on user input. It does require a few more steps than the other methods, but leverages the channels store to store the file:
- Read (or generate) the content file and store it in a Buffer for encoding to base64 (relevant code)
- Create a client to the Connector API (relevant code)
- Inject the Bot Connector's token into the Connector API client (relevant code)
- Set the Connector API client service url to the Connector's (relevant code)
- Upload the base64 encoded payload to the conversations/attachments endpoint (relevant code)
- Use the returned attachmentId to generate the contentUrl (relevant code)
This sample provides a helper method you can use that encapsulates most of the previous steps.
// read file content and upload
fs.readFile('./images/big-image.png', function (err, data) {
if (err) {
return session.send('Oops. Error reading file.');
}
// Upload file data using helper function
uploadAttachment(
data,
'image/png',
'BotFrameworkImage.png',
connector,
connectorApiClient,
session.message.address.serviceUrl,
session.message.address.conversation.id)
.then(function (attachmentUrl) {
// Send Message with Attachment obj using returned Url
var msg = new builder.Message(session)
.addAttachment({
contentUrl: attachmentUrl,
contentType: 'image/png',
name: 'BotFrameworkLogo.png'
});
session.send(msg);
})
.catch(function (err) {
console.log('Error uploading file', err);
session.send('Oops. Error uploading file. ' + err.message);
});
});
This option is the simplest but requires the image to be already on the Internet and be publicly accesible. You could also provide an Url pointing to your own site.
Checkout app.js to see how to create a message with a single image attachment.
var msg = new builder.Message(session)
.addAttachment({
contentUrl: 'https://docs.botframework.com/en-us/images/faq-overview/botframework_overview_july.png',
contentType: 'image/png',
name: 'BotFrameworkOverview.png'
});
session.send(msg);
You will see the following in the Bot Framework Emulator when selecting the inline attachment. See how the image is encoded in the contentUrl
of the attachment.
You will see the following in your Facebook Messenger when selecting to upload the attachment.
On the other hand, you will see the following in Skype when selecting an Internet attachment.
To get more information about how to get started in Bot Builder for Node and Attachments please review the following resources: