@sinch/mcp
Version:
Sinch MCP server
154 lines • 7.07 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.sendCardOrChoiceMessageHandler = exports.registerSendCardOrChoiceMessage = void 0;
const zod_1 = require("zod");
const conversation_service_helper_1 = require("./utils/conversation-service-helper");
const conversation_tools_helper_1 = require("./utils/conversation-tools-helper");
const send_message_builder_1 = require("./utils/send-message-builder");
const geocoding_1 = require("./utils/geocoding");
const prompt_schemas_1 = require("./prompt-schemas");
const utils_1 = require("../../utils");
const types_1 = require("../../types");
const choiceMessage = zod_1.z.object({
// Call
phone_number: zod_1.z.string().optional().describe('E.164 format'),
// Location
lat: zod_1.z.number().optional(),
long: zod_1.z.number().optional(),
address: zod_1.z.string().optional(),
// Text
text: zod_1.z.string().optional(),
// URL
url: zod_1.z.string().url().optional(),
// Common
title: zod_1.z.string().optional()
}).refine(data => Number(!!data.text) +
Number(!!data.url) +
Number(!!data.phone_number) +
Number((!!data.lat && !!data.long) || !!data.address) === 1, { message: 'Must provide exactly one type of choice: call, location, text, or URL' }).describe('Choice message that can be a call, location, text, or URL. Exactly one must be provided. The "title" parameter must not be provided is case of text choice.');
const TOOL_KEY = 'sendCardOrChoiceMessage';
const TOOL_NAME = (0, conversation_tools_helper_1.getToolName)(TOOL_KEY);
const registerSendCardOrChoiceMessage = (server, tags) => {
if (!(0, utils_1.matchesAnyTag)(tags, conversation_tools_helper_1.toolsConfig[TOOL_KEY].tags))
return;
server.tool(TOOL_NAME, 'Send a choice message to the user. The choice message can contain up to 3 choices if not text or up to 10 message if text only. Each choice can be a call message (phone number + title to display next to it), a location message (latitude / longitude + title to display next to it), a text message or a URL message (the URL to click on + title to display next to it). The contact can be a phone number in E.164 format, or the identifier for the specified channel.', {
recipient: prompt_schemas_1.Recipient,
choiceContent: zod_1.z.array(choiceMessage).max(10).optional().describe('The list of choices to send to the user'),
text: zod_1.z.string().describe('The text to be sent along the choice array'),
mediaUrl: zod_1.z.string().optional().describe('The media URL to be sent along the choice array'),
channel: prompt_schemas_1.ConversationChannel,
appId: prompt_schemas_1.ConversationAppIdOverride,
sender: prompt_schemas_1.MessageSenderNumberOverride,
region: prompt_schemas_1.ConversationRegionOverride,
}, exports.sendCardOrChoiceMessageHandler);
};
exports.registerSendCardOrChoiceMessage = registerSendCardOrChoiceMessage;
const sendCardOrChoiceMessageHandler = async ({ recipient, channel, choiceContent, text, mediaUrl, appId, sender, region }) => {
const maybeAppId = (0, conversation_service_helper_1.getConversationAppId)(appId);
if ((0, utils_1.isPromptResponse)(maybeAppId)) {
return maybeAppId.promptResponse;
}
const conversationAppId = maybeAppId;
const maybeService = (0, conversation_service_helper_1.getConversationService)(TOOL_NAME);
if ((0, utils_1.isPromptResponse)(maybeService)) {
return maybeService.promptResponse;
}
const conversationService = maybeService;
const usedRegion = (0, conversation_service_helper_1.setConversationRegion)(region, conversationService);
const choices = [];
for (const choice of choiceContent || []) {
if ('phone_number' in choice) {
choices.push({
call_message: {
phone_number: choice.phone_number,
title: choice.title
}
});
}
else if ('lat' in choice && 'long' in choice) {
choices.push({
location_message: {
coordinates: {
latitude: choice.lat,
longitude: choice.long
},
title: choice.title
}
});
}
else if ('address' in choice && choice.address) {
const coordinates = await (0, geocoding_1.getLatitudeLongitudeFromAddress)(choice.address);
choices.push({
location_message: {
coordinates: {
latitude: coordinates.latitude,
longitude: coordinates.longitude
},
title: coordinates.formattedAddress
}
});
}
else if ('text' in choice) {
choices.push({
text_message: {
text: choice.text
}
});
}
else if ('url' in choice) {
choices.push({
url_message: {
url: choice.url,
title: choice.title
}
});
}
}
const requestBase = await (0, send_message_builder_1.buildMessageBase)(conversationService, conversationAppId, recipient, channel, sender);
try {
let response;
if (mediaUrl) {
response = await conversationService.messages.sendCardMessage({
sendMessageRequestBody: {
...requestBase,
message: {
card_message: {
choices,
title: text,
media_message: {
url: mediaUrl
}
}
}
}
});
}
else {
response = await conversationService.messages.sendChoiceMessage({
sendMessageRequestBody: {
...requestBase,
message: {
choice_message: {
choices,
text_message: {
text
}
}
}
}
});
}
return new types_1.PromptResponse(JSON.stringify({
success: true,
message_id: response.message_id
})).promptResponse;
}
catch (error) {
return new types_1.PromptResponse(JSON.stringify({
success: false,
error: (error instanceof Error ? error.message : String(error)) + `. Are you sure you are using the right region to send your message? The current region is ${usedRegion}.`
})).promptResponse;
}
};
exports.sendCardOrChoiceMessageHandler = sendCardOrChoiceMessageHandler;
//# sourceMappingURL=send-card-or-choice-message.js.map