File

mod_ogp/mod_ogp.lua @ 6297:502963b86fbc

:multble modules: fix tab-> space diff --git a/mod_admin_blocklist/README.md b/mod_admin_blocklist/README.md --- a/mod_admin_blocklist/README.md +++ b/mod_admin_blocklist/README.md @@ -24,9 +24,9 @@ admin_blocklist_roles = { "prosody:opera # Compatibility Prosody-Version Status - -------------- ------ - trunk* Works - 13 Works - 0.12 Works + ------------ ------ + trunk* Works + 13 Works + 0.12 Works *as of 2025-06-13 diff --git a/mod_csi_grace_period/README.md b/mod_csi_grace_period/README.md --- a/mod_csi_grace_period/README.md +++ b/mod_csi_grace_period/README.md @@ -16,9 +16,9 @@ pocket is not the best use of radio time Works with [mod_csi_simple][doc:modules:mod_csi_simple] which is included with Prosody. - ------- ------- - trunk* Works - 13 Works - 0.12 Works + ------- ------- + trunk* Works + 13 Works + 0.12 Works *as of 2025-06-13 diff --git a/mod_http_upload_external/README.md b/mod_http_upload_external/README.md --- a/mod_http_upload_external/README.md +++ b/mod_http_upload_external/README.md @@ -87,10 +87,10 @@ Compatibility ============= Prosody-Version Status - ---------------- -------------------- - trunk Works as of 25-06-13 - 13 Works - 0.12 Works + ---------------- -------------------- + trunk Works as of 25-06-13 + 13 Works + 0.12 Works Implementation ============== diff --git a/mod_muc_moderation/README.md b/mod_muc_moderation/README.md --- a/mod_muc_moderation/README.md +++ b/mod_muc_moderation/README.md @@ -27,11 +27,10 @@ modules_enabled = { # Compatibility - ------- --------------- - trunk Works^[as of 2025-06-13] - 13 Works - 0.12 Works - ------- --------------- + ------- --------------- + trunk Works^[as of 2025-06-13] + 13 Works + 0.12 Works ## XEP version diff --git a/mod_s2s_idle_timeout/README.md b/mod_s2s_idle_timeout/README.md --- a/mod_s2s_idle_timeout/README.md +++ b/mod_s2s_idle_timeout/README.md @@ -25,10 +25,9 @@ Compatibility ============= Prosody Version Status - ----------------- ----------- - trunk[^1] Works - 13 Works - 0.12 Works - ----------------- ----------- + ----------------- ----------- + trunk[^1] Works + 13 Works + 0.12 Works [^1]: as of 2025-06-13 diff --git a/mod_s2s_keepalive/README.md b/mod_s2s_keepalive/README.md --- a/mod_s2s_keepalive/README.md +++ b/mod_s2s_keepalive/README.md @@ -34,10 +34,9 @@ Compatibility ============= Prosody Version Status - ----------------- ----------- - trunk[^1] Works - 13 Works - 0.12 Works - ----------------- ----------- + ----------------- ----------- + trunk[^1] Works + 13 Works + 0.12 Works [^1]: as of 2025-06-13
author Menel <menel@snikket.de>
date Fri, 13 Jun 2025 09:58:51 +0200
parent 4598:09f0911c735d
line wrap: on
line source

local mod_muc = module:depends("muc")
local http = require "net.http"
local st = require "util.stanza"
local url_pattern = [[https?://%S+]]
local domain_pattern = '^%w+://([^/]+)'
local xmlns_fasten = "urn:xmpp:fasten:0"
local xmlns_xhtml = "http://www.w3.org/1999/xhtml"
local allowlist = module:get_option_set("ogp_domain_allowlist", module:get_option_set("ogp_domain_whitelist", {}))
local denylist = module:get_option_set("ogp_domain_denylist", {})


local function is_allowed(domain)
	if allowlist:empty() then
		return true
	end
	if allowlist:contains(domain) then
		return true
	end
	return false
end

local function is_denied(domain)
	if denylist:empty() then
		return false
	end
	if denylist:contains(domain) then
		return true
	end
	return false
end


local function fetch_ogp_data(room, url, origin_id)
	if not url then
		return;
	end

	local domain = url:match(domain_pattern);
	if is_denied(domain) or not is_allowed(domain) then
		return;
	end

	http.request(
		url,
		nil,
		function(response_body, response_code, _)
			if response_code ~= 200 then
				module:log("debug", "Call to %s returned code %s and body %s", url, response_code, response_body)
				return
			end

			local to = room.jid
			local from = room and room.jid or module.host
			local fastening = st.message({to = to, from = from, type = 'groupchat'}):tag("apply-to", {xmlns = xmlns_fasten, id = origin_id})
			local found_metadata = false
			local message_body = ""

			local meta_pattern = [[<meta (.-)/?>]]
			for match in response_body:gmatch(meta_pattern) do
				local property = match:match([[property=%s*["']?(og:.-)["']?%s]])
				if not property then
					property = match:match([[property=["']?(og:.-)["']$]])
				end

				local content = match:match([[content=%s*["'](.-)["']%s]])
				if not content then
					content = match:match([[content=["']?(.-)["']$]])
				end
				if not content then
					content = match:match([[content=(.-) property]])
				end
				if not content then
					content = match:match([[content=(.-)$]])
				end

				if property and content then
					module:log("debug", property .. "\t" .. content)
					fastening:tag(
						"meta",
						{
							xmlns = xmlns_xhtml,
							property = property,
							content = content
						}
					):up()
					found_metadata = true
					message_body = message_body .. property .. "\t" .. content .. "\n"
				end
			end

			if found_metadata then
				mod_muc.get_room_from_jid(room.jid):broadcast_message(fastening)
			end
			module:log("debug", tostring(fastening))
		end
	)
end

local function ogp_handler(event)
	local room, stanza = event.room, st.clone(event.stanza)
	local body = stanza:get_child_text("body")

	if not body then return; end

	local origin_id = stanza:find("{urn:xmpp:sid:0}origin-id@id")
	if not origin_id then return; end

	for url in body:gmatch(url_pattern) do
		fetch_ogp_data(room, url, origin_id);
	end
end

module:hook("muc-occupant-groupchat", ogp_handler)


module:hook("muc-message-is-historic", function (event)
	local fastening = event.stanza:get_child('apply-to', xmlns_fasten)
	if fastening and fastening:get_child('meta', xmlns_xhtml) then
		return true
	end
end);