UNPKG

imessage-ts

Version:

TypeScript library for interacting with iMessage on macOS - send messages, monitor chats, and automate responses

122 lines 5.77 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MessageSender = void 0; const child_process_1 = require("child_process"); const util_1 = require("util"); const types_1 = require("../types"); const fs_extra_1 = __importDefault(require("fs-extra")); const path_1 = __importDefault(require("path")); const os_1 = __importDefault(require("os")); const execAsync = (0, util_1.promisify)(child_process_1.exec); /** * Service to send messages via iMessage using AppleScript */ class MessageSender { /** * Send a message to a recipient or group */ async sendMessage(options) { const { text, to, subject, attachments, service = types_1.MessageService.IMESSAGE } = options; if (!text && (!attachments || attachments.length === 0)) { throw new Error('Message must have text or attachments'); } if (!to || (Array.isArray(to) && to.length === 0)) { throw new Error('Recipient(s) required'); } // Validate attachment files exist if (attachments && attachments.length > 0) { for (const attachment of attachments) { if (!await fs_extra_1.default.pathExists(attachment)) { throw new Error(`Attachment file not found: ${attachment}`); } } } const recipients = Array.isArray(to) ? to : [to]; try { // Build the AppleScript - using a simpler approach let script = `tell application "Messages"\n`; // Get the service ID first const serviceType = service === types_1.MessageService.SMS ? 'SMS' : 'iMessage'; script += ` set targetService to id of 1st service whose service type = ${serviceType}\n`; // For each recipient for (const recipient of recipients) { // Create the buddy reference script += ` set theBuddy to buddy "${escapeAppleScriptString(recipient)}" of service id targetService\n`; // If we have both text and attachments if (text && attachments && attachments.length > 0 && service === types_1.MessageService.IMESSAGE) { // Send text first script += ` send "${escapeAppleScriptString(text)}" to theBuddy\n`; // Then send each attachment separately with a delay for (const attachment of attachments) { script += ` delay 1\n`; // Small delay to ensure messages are sent in order script += ` set theAttachment to POSIX file "${escapeAppleScriptString(attachment)}"\n`; script += ` send theAttachment to theBuddy\n`; } } else if (text) { // Just text message script += ` send "${escapeAppleScriptString(text)}" to theBuddy\n`; } else if (attachments && attachments.length > 0 && service === types_1.MessageService.IMESSAGE) { // Just attachments for (const attachment of attachments) { script += ` set theAttachment to POSIX file "${escapeAppleScriptString(attachment)}"\n`; script += ` send theAttachment to theBuddy\n`; } } if (attachments && attachments.length > 0 && service === types_1.MessageService.SMS) { console.warn('Warning: SMS service has limited attachment support. Some attachments may not send properly.'); } } script += `end tell\n`; // Debug: Log the script console.log('Generated AppleScript:'); console.log(script); // Write script to a temporary file to avoid shell escaping issues const tempFile = path_1.default.join(os_1.default.tmpdir(), `imessage-script-${Date.now()}.scpt`); await fs_extra_1.default.writeFile(tempFile, script); try { // Execute the AppleScript from the temp file await execAsync(`osascript "${tempFile}"`); } finally { // Clean up temp file await fs_extra_1.default.remove(tempFile).catch(() => { }); // Ignore errors on cleanup } } catch (error) { throw new Error(`Failed to send message: ${error.message}`); } } /** * Check if iMessage is available */ async isAvailable() { try { await execAsync('osascript -e \'tell application "Messages" to return name\''); return true; } catch (error) { return false; } } } exports.MessageSender = MessageSender; /** * Escape special characters in AppleScript strings */ function escapeAppleScriptString(str) { // In AppleScript, escape quotes by doubling them // Also handle Unicode quotes and other special characters return str .replace(/\\/g, '\\\\') // Escape backslashes first .replace(/"/g, '""') // Escape quotes by doubling them (AppleScript style) .replace(/'/g, "'") // Replace curly apostrophe with straight apostrophe .replace(/'/g, "'") // Replace other curly apostrophe with straight apostrophe .replace(/"/g, '""') // Replace left curly quote with escaped straight quote .replace(/"/g, '""'); // Replace right curly quote with escaped straight quote } //# sourceMappingURL=message-sender.js.map