Mercurial > prosody-modules
view mod_tweet_data/mod_tweet_data.lua @ 5298:12f7d8b901e0
mod_audit: Support for adding location (GeoIP) to audit events
This can be more privacy-friendly than logging full IP addresses, and also
more informative to a user - IP addresses don't mean much to the average
person, however if they see activity from outside their expected country, they
can immediately identify suspicious activity.
As with IPs, this field is configurable for deployments that would like to
disable it. Location is also not logged when the geoip library is not
available.
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sat, 01 Apr 2023 13:11:53 +0100 |
parents | efdc3e4dc5df |
children |
line wrap: on
line source
local mod_muc = module:depends("muc") local http = require "net.http" local st = require "util.stanza" local json = require "util.json" local url_pattern = [[https://twitter.com/%S+/status/%S+]] local xmlns_fasten = "urn:xmpp:fasten:0" local xmlns_xhtml = "http://www.w3.org/1999/xhtml" local twitter_apiv2_bearer_token = module:get_option_string("twitter_apiv2_bearer_token"); local function fetch_tweet_data(room, url, tweet_id, origin_id) if not url then return; end local options = { method = "GET"; headers = { Authorization = "Bearer "..twitter_apiv2_bearer_token; }; }; http.request( 'https://api.twitter.com/2/tweets/'..tweet_id..'?expansions=author_id&tweet.fields=created_at,text&user.fields=id,name,username,profile_image_url', options, 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 response = json.decode(response_body); if not response then return; end if not response['data'] or not response['includes'] then return; end local tweet = response['data']; local author = response['includes']['users'][1]; 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}) fastening:tag( "meta", { xmlns = xmlns_xhtml, property = 'og:article:author', content = author['username'] } ):up() fastening:tag( "meta", { xmlns = xmlns_xhtml, property = 'og:article:published_time', content = tweet['created_at'] } ):up() fastening:tag( "meta", { xmlns = xmlns_xhtml, property = 'og:description', content = tweet['text'] } ):up() fastening:tag( "meta", { xmlns = xmlns_xhtml, property = 'og:image', content = author['profile_image_url'] } ):up() fastening:tag( "meta", { xmlns = xmlns_xhtml, property = 'og:title', content = author['username'] } ):up() fastening:tag( "meta", { xmlns = xmlns_xhtml, property = 'og:type', content = 'tweet' } ):up() fastening:tag( "meta", { xmlns = xmlns_xhtml, property = 'og:url', content = 'https://twitter.com/'..author['username']..'/status/'..tweet['id'] } ):up() mod_muc.get_room_from_jid(room.jid):broadcast_message(fastening) module:log("debug", tostring(fastening)) end ) end local function tweet_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 local _, _, _, tweet_id = string.find(url, "https://twitter.com/(%S+)/status/(%S+)"); fetch_tweet_data(room, url, tweet_id, origin_id); end end module:hook("muc-occupant-groupchat", tweet_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);