UNPKG

@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
'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