104 lines
4.5 KiB
Lua
104 lines
4.5 KiB
Lua
|
|
-- 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)
|