-- Send clipboard contents as an email to {name} via Outlook COM. The recipient -- is resolved against the Global Address List + Contacts (Outlook's Recipient -- .Resolve API). Subject = first line of the body truncated to 60 chars, or -- "From J.A.R.V.I.S." for an empty clipboard. local lang = jarvis.context.language local slots = jarvis.context.slots or {} local recipient = slots.name or "" recipient = tostring(recipient):gsub("^%s+", ""):gsub("%s+$", "") if recipient == "" then return jarvis.cmd.not_found(lang == "ru" and "Кому отправить? Назови имя." or "Whom to send to? Please name them.") end local body = jarvis.system.clipboard.get() or "" body = body:gsub("^%s+", ""):gsub("%s+$", "") -- Write the body to a temp file so we don't have to escape it through the -- PowerShell command-line. The PS helper reads it back via -Body parameter -- value (passed as an arg). For very large bodies (>32 KB) the cmd-line -- approach would break; in that case we read the file from inside PS. local temp = jarvis.system.env("TEMP") or jarvis.system.env("TMP") or "C:\\Windows\\Temp" local ts = jarvis.context.time.year .. jarvis.context.time.month .. jarvis.context.time.day .. "_" .. jarvis.context.time.hour .. jarvis.context.time.minute .. jarvis.context.time.second local body_path = temp .. "\\jarvis_outlook_body_" .. ts .. ".txt" jarvis.fs.write(body_path, body) -- Pass body via the file: the helper reads $Body if set, else falls back to -- reading the saved file. To keep the helper simple we just inline the body -- through -Body only when small; otherwise we still pass via -Body but quote -- the path and let PS read it. We use the latter: PS reads its arg literally. -- We instead encode the body so passing through args is safe. local helper = jarvis.context.command_path .. "\\_outlook.ps1" -- Build a single-line PowerShell expression that reads the body from the -- temp file and invokes the helper. This avoids any shell-escape issues -- with quotes/newlines in the clipboard. local body_path_ps = body_path:gsub("'", "''") local recipient_ps = recipient:gsub("'", "''") local helper_ps = helper:gsub("'", "''") local ps_expr = string.format( "$b = Get-Content -LiteralPath '%s' -Raw -Encoding UTF8; if (-not $b) { $b = '' } else { $b = $b.TrimEnd() }; & '%s' -Action send_clipboard -Recipient '%s' -Body $b", body_path_ps, helper_ps, recipient_ps ) local cmd = string.format( 'powershell -NoProfile -ExecutionPolicy Bypass -Command "%s"', ps_expr:gsub('"', '\\"') ) local res = jarvis.system.exec(cmd) jarvis.fs.remove(body_path) local out = (res.stdout or ""):gsub("\r", "") if not res.success or out == "" then jarvis.log("error", "outlook send_clipboard exec failed: " .. tostring(res.stderr)) return jarvis.cmd.error(lang == "ru" and "Outlook недоступен — запусти Outlook сначала." or "Outlook is unavailable — start Outlook first.") end local lines = {} for line in out:gmatch("[^\n]+") do table.insert(lines, line) end local status = lines[1] or "" if status:sub(1, 3) == "ERR" then if status:find("unresolved", 1, true) then return jarvis.cmd.not_found(lang == "ru" and (string.format("Не нашёл контакт «%s».", recipient)) or (string.format("Could not find contact '%s'.", recipient))) elseif status:find("no_recipient", 1, true) then return jarvis.cmd.not_found(lang == "ru" and "Кому отправить? Назови имя." or "Whom to send to? Please name them.") end jarvis.log("warn", "outlook send_clipboard: " .. status) return jarvis.cmd.error(lang == "ru" and "Не получилось отправить — Outlook отказал." or "Send failed — Outlook refused.") end local to_name, addr, subject = "", "", "" for i = 2, #lines do local key, val = lines[i]:match("^([A-Z]+)\t(.*)$") if key == "TO" then to_name = val or "" end if key == "ADDR" then addr = val or "" end if key == "SUBJECT" then subject = val or "" end end local speech if lang == "ru" then speech = string.format("Отправил %s. Тема: %s.", to_name ~= "" and to_name or recipient, subject) else speech = string.format("Sent to %s. Subject: %s.", to_name ~= "" and to_name or recipient, subject) end jarvis.system.notify( lang == "ru" and "Письмо отправлено" or "Email sent", string.format("%s <%s>\n%s", to_name, addr, subject) ) return jarvis.cmd.ok(speech)