@microsoft/teams.api
Version:
<p> <a href="https://www.npmjs.com/package/@microsoft/teams.api" target="_blank"> <img src="https://img.shields.io/npm/v/@microsoft/teams.api/latest" /> </a> <a href="https://www.npmjs.com/package/@microsoft/teams.api?activeTab=code" t
508 lines (505 loc) • 14.1 kB
JavaScript
'use strict';
var models = require('../../models');
var activity = require('../activity');
var utils = require('../utils');
class MessageActivityInput extends activity.ActivityInput {
/**
* Message text.
*/
text;
/**
* Format of the message text.
*/
textFormat;
/**
* Layout hint for multiple attachments.
*/
attachmentLayout;
/**
* Attachments sent with the message.
*/
attachments;
/**
* Suggested actions presented with the message.
*/
suggestedActions;
/**
* Create an outbound message activity input.
* @param text - Initial message text.
* @param value - Initial modeled input fields and unmodeled extension fields to serialize.
*/
constructor(text = "", value = {}) {
super("message");
const { type: _type, text: _text, ...fields } = value;
Object.assign(this, fields, { text });
}
static from(activity) {
const text = activity.text ?? "";
const {
type: _type,
text: _text,
from: _from,
conversation: _conversation,
channelId: _channelId,
serviceUrl: _serviceUrl,
timestamp: _timestamp,
localTimestamp: _localTimestamp,
relatesTo: _relatesTo,
stripMentionsText: _stripMentionsText,
isRecipientMentioned: _isRecipientMentioned,
getAccountMention: _getAccountMention,
getQuotedMessages: _getQuotedMessages,
...value
} = activity;
return new MessageActivityInput(text, value);
}
/**
* Set the message text.
* @param value - Message text.
*/
withText(value) {
this.text = value;
return this;
}
/**
* Append text to the message.
* @param value - Text to append.
*/
addText(value) {
this.text = `${this.text || ""}${value}`;
return this;
}
/**
* Set the message text format.
* @param value - Text format.
*/
withTextFormat(value) {
this.textFormat = value;
return this;
}
/**
* Set the attachment layout.
* @param value - Attachment layout.
*/
withAttachmentLayout(value) {
this.attachmentLayout = value;
return this;
}
/**
* Set suggested actions for the message.
* @param value - Suggested actions.
*/
withSuggestedActions(value) {
this.suggestedActions = value;
return this;
}
/**
* Add attachments to the message.
* @param value - Attachments to add.
*/
addAttachments(...value) {
if (!this.attachments) {
this.attachments = [];
}
this.attachments.push(...value);
return this;
}
/**
* Add a card attachment to the message.
* @param type - Card attachment type.
* @param content - Card content.
*/
addCard(type, content) {
return this.addAttachments(models.cardAttachment(type, content));
}
/**
* Add a mention entity and optionally append mention text.
* @param account - Account being mentioned.
* @param options - Mention options.
*/
addMention(account, options = {}) {
const text = options.text || account.name;
if (options.addText !== false) {
this.addText(`<at>${text}</at>`);
}
return this.addEntity({
type: "mention",
mentioned: account,
text: `<at>${text}</at>`
});
}
/**
* Mark the message as the final activity in a stream.
*
* The final carries no `streamSequence`. Teams documents the sequence as required on every streaming
* request except this one: "For the final message, `streamSequence` must not be set."
* https://learn.microsoft.com/en-us/microsoftteams/platform/bots/streaming-ux#stream-message-through-rest-api
*/
addStreamFinal() {
if (!this.channelData) {
this.channelData = {};
}
const streamId = this.channelData.streamId || this.id || "";
this.channelData.streamId = streamId;
this.channelData.streamType = "final";
delete this.channelData.streamSequence;
this.addEntity({
type: "streaminfo",
streamId,
streamType: "final"
});
return this;
}
/**
* Add a quoted message reference and append a `<quoted messageId="..."/>` placeholder to text.
* Teams renders the quoted message as a preview bubble above the response text.
* If text is provided, it is appended to the quoted message placeholder.
* @param messageId - The ID of the message to quote
* @param text - Optional text, appended to the quoted message placeholder
* @returns this instance for chaining
*/
addQuote(messageId, text) {
if (!this.entities) {
this.entities = [];
}
this.entities.push({
type: "quotedReply",
quotedReply: { messageId }
});
this.addText(`<quoted messageId="${messageId}"/>`);
if (text) {
this.addText(` ${text}`);
}
return this;
}
/**
* Prepend a quotedReply entity and `<quoted messageId="..."/>` placeholder
* before existing text. Used by reply()/quote() for quote-above-response.
* @param messageId - The IC3 message ID of the message to quote
*/
prependQuote(messageId) {
if (!this.entities) {
this.entities = [];
}
this.entities.push({
type: "quotedReply",
quotedReply: { messageId }
});
const placeholder = `<quoted messageId="${messageId}"/>`;
const hasText = !!this.text?.trim();
this.text = hasText ? `${placeholder} ${this.text}` : placeholder;
return this;
}
}
class MessageActivity extends activity.Activity {
/**
* The text content of the message.
*/
text;
/**
* The text to speak.
* @deprecated This will be removed by end of summer 2026.
*/
speak;
/**
* Indicates whether your bot is accepting,
* expecting, or ignoring user input after the message is delivered to the client. Possible
* values include: 'acceptingInput', 'ignoringInput', 'expectingInput'
* @deprecated This will be removed by end of summer 2026.
*/
inputHint;
/**
* The text to display if the channel cannot render cards.
*/
summary;
/**
* Format of text fields Default:markdown. Possible values include: 'markdown', 'plain', 'xml', 'extendedmarkdown'. See {@link TextFormat} for all values
*/
textFormat;
/**
* The layout hint for multiple attachments. Default: list. Possible values include: 'list',
* 'carousel'
*/
attachmentLayout;
/**
* Attachments
*/
attachments;
/**
* The suggested actions for the activity.
*/
suggestedActions;
/**
* The importance of the activity. Possible values include: 'low', 'normal', 'high'
* @deprecated This will be removed by end of summer 2026.
*/
importance;
/**
* A delivery hint to signal to the recipient alternate delivery paths for the activity.
* The default delivery mode is "default". Possible values include: 'normal', 'notification'
*/
deliveryMode;
/**
* The time at which the activity should be considered to be "expired" and should not be
* presented to the recipient.
* @deprecated This will be removed by end of summer 2026.
*/
expiration;
/**
* A value that is associated with the activity.
*/
value;
constructor(text = "", value = {}) {
super({
...value,
type: "message"
});
Object.assign(this, { text, ...value });
}
/**
* initialize from interface
*/
static from(activity) {
return new MessageActivity(activity.text, activity);
}
/**
* convert to interface
*/
toInterface() {
return Object.assign(
{
stripMentionsText: this.stripMentionsText.bind(this),
isRecipientMentioned: this.isRecipientMentioned.bind(this),
getAccountMention: this.getAccountMention.bind(this),
getQuotedMessages: this.getQuotedMessages.bind(this)
},
this
);
}
/**
* copy to a new instance
*/
clone(options = {}) {
return new MessageActivity(this.text, {
...this.toInterface(),
...options
});
}
/**
* The text content of the message.
*/
withText(value) {
this.text = value;
return this;
}
/**
* The text to speak.
* @deprecated This will be removed by end of summer 2026.
*/
withSpeak(value) {
this.speak = value;
return this;
}
/**
* Indicates whether your bot is accepting,
* expecting, or ignoring user input after the message is delivered to the client. Possible
* values include: 'acceptingInput', 'ignoringInput', 'expectingInput'
* @deprecated This will be removed by end of summer 2026.
*/
withInputHint(value) {
this.inputHint = value;
return this;
}
/**
* The text to display if the channel cannot render cards.
*/
withSummary(value) {
this.summary = value;
return this;
}
/**
* Format of text fields Default:markdown. Possible values include: 'markdown', 'plain', 'xml', 'extendedmarkdown'. See {@link TextFormat} for all values
*/
withTextFormat(value) {
this.textFormat = value;
return this;
}
/**
* The layout hint for multiple attachments. Default: list. Possible values include: 'list',
* 'carousel'
*/
withAttachmentLayout(value) {
this.attachmentLayout = value;
return this;
}
/**
* The suggested actions for the activity.
*/
withSuggestedActions(value) {
this.suggestedActions = value;
return this;
}
/**
* The importance of the activity. Possible values include: 'low', 'normal', 'high'
* @deprecated This will be removed by end of summer 2026.
*/
withImportance(value) {
this.importance = value;
return this;
}
/**
* A delivery hint to signal to the recipient alternate delivery paths for the activity.
* The default delivery mode is "default". Possible values include: 'normal', 'notification'
*/
withDeliveryMode(value) {
this.deliveryMode = value;
return this;
}
/**
* The time at which the activity should be considered to be "expired" and should not be
* presented to the recipient.
* @deprecated This will be removed by end of summer 2026.
*/
withExpiration(value) {
this.expiration = value;
return this;
}
/**
* Append text
*/
addText(text) {
this.text += text;
return this;
}
/**
* Attachments
*/
addAttachments(...value) {
if (!this.attachments) {
this.attachments = [];
}
this.attachments.push(...value);
return this;
}
/**
* `@mention` an account
* @param account the account to mention
* @param options options to customize the mention
*/
addMention(account, options = {}) {
const text = options.text || account.name;
const addText = options.addText ?? true;
if (addText) {
this.addText(`<at>${text}</at>`);
}
return this.addEntity({
type: "mention",
mentioned: account,
text: `<at>${text}</at>`
});
}
/**
* Add a card attachment
*/
addCard(type, content) {
return this.addAttachments(models.cardAttachment(type, content));
}
/**
* remove "\<at>...\</at>" text from an activity
*/
stripMentionsText(options = {}) {
this.text = utils.stripMentionsText(this, options);
return this;
}
/**
* is the recipient account mentioned
*/
isRecipientMentioned() {
return (this.entities || []).filter((e) => e.type === "mention").some((e) => e.mentioned.id === this.recipient.id);
}
/**
* get a mention by the account id if exists
*/
getAccountMention(accountId) {
return (this.entities || []).filter((e) => e.type === "mention").find((e) => e.mentioned.id === accountId);
}
/**
* get all quoted reply entities from this message
*/
getQuotedMessages() {
return (this.entities ?? []).filter(
(e) => e.type === "quotedReply"
);
}
/**
* Add stream info, making
* this a final stream message
*/
addStreamFinal() {
if (!this.channelData) {
this.channelData = {};
}
this.channelData.streamId = this.id;
this.channelData.streamType = "final";
return this.addEntity({
type: "streaminfo",
streamId: this.id,
streamType: "final"
});
}
/**
* Set the recipient of this message, optionally marking it as a targeted (ephemeral) message.
* Targeted messages are only visible to the specified recipient in a shared conversation.
* @param account - The recipient account
* @param isTargeted - If true, marks this as a targeted message visible only to the recipient
* @returns this instance for chaining
*/
withRecipient(account, isTargeted = false) {
super.withRecipient(account, isTargeted);
return this;
}
/**
* Add a quoted message reference and append a `<quoted messageId="..."/>` placeholder to text.
* Teams renders the quoted message as a preview bubble above the response text.
* If text is provided, it is appended to the quoted message placeholder.
* @param messageId - The ID of the message to quote
* @param text - Optional text, appended to the quoted message placeholder
* @returns this instance for chaining
*/
addQuote(messageId, text) {
if (!this.entities) {
this.entities = [];
}
this.entities.push({
type: "quotedReply",
quotedReply: { messageId }
});
this.addText(`<quoted messageId="${messageId}"/>`);
if (text) {
this.addText(` ${text}`);
}
return this;
}
/**
* Prepend a quotedReply entity and `<quoted messageId="..."/>` placeholder
* before existing text. Used by reply()/quote() for quote-above-response.
* @param messageId - The IC3 message ID of the message to quote
*/
prependQuote(messageId) {
if (!this.entities) {
this.entities = [];
}
this.entities.push({
type: "quotedReply",
quotedReply: { messageId }
});
const placeholder = `<quoted messageId="${messageId}"/>`;
const hasText = !!this.text?.trim();
this.text = hasText ? `${placeholder} ${this.text}` : placeholder;
return this;
}
}
exports.MessageActivity = MessageActivity;
exports.MessageActivityInput = MessageActivityInput;
//# sourceMappingURL=message.js.map
//# sourceMappingURL=message.js.map