mirror of
https://github.com/sky-systems/sky_phone.git
synced 2026-09-02 03:08:54 +00:00
ADD - share contacts and rich content in chats
This commit is contained in:
@@ -97,9 +97,59 @@ local function current_device(source)
|
||||
return device
|
||||
end
|
||||
|
||||
local function shared_contact(device, contact_id)
|
||||
if type(contact_id) ~= "string" or contact_id == "" or #contact_id > 36 then
|
||||
return nil, "invalid_contact"
|
||||
end
|
||||
local condition
|
||||
local params
|
||||
if device.account_id then
|
||||
condition = "contact.`account_id` = ?"
|
||||
params = { contact_id, tonumber(device.account_id) }
|
||||
else
|
||||
condition = "contact.`account_id` IS NULL AND contact.`device_imei` = ?"
|
||||
params = { contact_id, device.imei }
|
||||
end
|
||||
local rows = Bridge.Database.Query(([[
|
||||
SELECT contact.`name`, contact.`organization`, contact.`phone_number`, media.`url` AS `avatar_url`
|
||||
FROM `sky_phone_contacts` contact
|
||||
LEFT JOIN `sky_phone_media` media ON media.`id` = contact.`avatar_media_id`
|
||||
WHERE contact.`contact_id` = ? AND %s
|
||||
LIMIT 1
|
||||
]]):format(condition), params)
|
||||
local contact = rows[1]
|
||||
if not contact then
|
||||
return nil, "contact_not_found"
|
||||
end
|
||||
local name = trim(contact.name)
|
||||
local organization = trim(contact.organization)
|
||||
local number = SkyPhoneSimNumber.Normalize(
|
||||
contact.phone_number,
|
||||
Config.Sim.NumberLength,
|
||||
Config.Sim.NumberPrefix
|
||||
)
|
||||
if not name or name == "" or #name > Config.Calls.ContactNameMaxLength
|
||||
or (organization and #organization > Config.Calls.ContactNameMaxLength) or not number
|
||||
then
|
||||
error(("[sky_phone] Contact %s cannot be shared because its stored data is invalid."):format(contact_id))
|
||||
end
|
||||
local snapshot = {
|
||||
avatar_url = contact.avatar_url,
|
||||
name = name,
|
||||
organization = organization ~= "" and organization or nil,
|
||||
phone_number = number,
|
||||
}
|
||||
return {
|
||||
data = snapshot,
|
||||
payload = json.encode(snapshot),
|
||||
}
|
||||
end
|
||||
|
||||
local function format_message(row)
|
||||
row.media_duration_ms = tonumber(row.media_duration_ms)
|
||||
row.media_asset_id = nil
|
||||
row.contact = nil
|
||||
row.share = nil
|
||||
if row.message_type == "voice" then
|
||||
local waveform = row.media_waveform and json.decode(row.media_waveform) or nil
|
||||
if type(waveform) ~= "table" then
|
||||
@@ -107,6 +157,33 @@ local function format_message(row)
|
||||
end
|
||||
row.media_waveform = waveform
|
||||
row.media_payload = nil
|
||||
elseif row.message_type == "contact" then
|
||||
local contact = row.media_payload and json.decode(row.media_payload) or nil
|
||||
if type(contact) ~= "table" or type(contact.name) ~= "string"
|
||||
or type(contact.phone_number) ~= "string"
|
||||
or (contact.avatar_url ~= nil and type(contact.avatar_url) ~= "string")
|
||||
or (contact.organization ~= nil and type(contact.organization) ~= "string")
|
||||
then
|
||||
error(("[sky_phone] Message %s has an invalid contact payload."):format(tostring(row.id)))
|
||||
end
|
||||
row.contact = contact
|
||||
row.media_payload = nil
|
||||
row.media_duration_ms = nil
|
||||
row.media_mime = nil
|
||||
row.media_waveform = nil
|
||||
elseif row.message_type == "share" then
|
||||
local share = row.media_payload and json.decode(row.media_payload) or nil
|
||||
if type(share) ~= "table" or type(share.appId) ~= "string"
|
||||
or type(share.kind) ~= "string" or type(share.title) ~= "string"
|
||||
or type(share.copyText) ~= "string"
|
||||
then
|
||||
error(("[sky_phone] Message %s has an invalid share payload."):format(tostring(row.id)))
|
||||
end
|
||||
row.share = share
|
||||
row.media_payload = nil
|
||||
row.media_duration_ms = nil
|
||||
row.media_mime = nil
|
||||
row.media_waveform = nil
|
||||
elseif attachment_assets[row.message_type] then
|
||||
if not valid_stored_attachment(row.message_type, row.media_payload) then
|
||||
error(("[sky_phone] Message %s has an invalid attachment asset."):format(tostring(row.id)))
|
||||
@@ -414,6 +491,8 @@ Bridge.Callbacks.Register("sky_phone:messages:send", function(source, data)
|
||||
local body = trim(data.body) or ""
|
||||
local voice = nil
|
||||
local attachment = nil
|
||||
local contact = nil
|
||||
local share = nil
|
||||
if message_type == "text" then
|
||||
if body == "" or #body > Config.Messages.BodyMaxLength then
|
||||
return { success = false, error = "invalid_message" }
|
||||
@@ -424,6 +503,25 @@ Bridge.Callbacks.Register("sky_phone:messages:send", function(source, data)
|
||||
return { success = false, error = "invalid_voice" }
|
||||
end
|
||||
body = ""
|
||||
elseif message_type == "contact" then
|
||||
local contact_error
|
||||
contact, contact_error = shared_contact(device, data.contactId)
|
||||
if not contact then
|
||||
return { success = false, error = contact_error }
|
||||
end
|
||||
body = contact.data.name
|
||||
elseif message_type == "share" then
|
||||
local share_error
|
||||
local encoded
|
||||
share, share_error, encoded = SkyPhoneEasyShare.SanitizeChatPayload(source, data.sharePayload)
|
||||
if not share then
|
||||
return { success = false, error = share_error or "invalid_payload" }
|
||||
end
|
||||
if body ~= "" and #body > Config.Messages.BodyMaxLength then
|
||||
return { success = false, error = "invalid_message" }
|
||||
end
|
||||
share = { data = share, payload = encoded }
|
||||
body = body ~= "" and body or share.data.title
|
||||
elseif attachment_assets[message_type] then
|
||||
attachment = validate_attachment(source, device, message_type, data)
|
||||
if not attachment then
|
||||
@@ -459,7 +557,8 @@ Bridge.Callbacks.Register("sky_phone:messages:send", function(source, data)
|
||||
number,
|
||||
message_type,
|
||||
body,
|
||||
voice and voice.payload or attachment and attachment.payload or nil,
|
||||
voice and voice.payload or attachment and attachment.payload or contact and contact.payload
|
||||
or share and share.payload or nil,
|
||||
voice and voice.mime or attachment and attachment.mime or nil,
|
||||
voice and voice.duration or attachment and attachment.duration or nil,
|
||||
voice and voice.waveform or nil,
|
||||
|
||||
Reference in New Issue
Block a user