mod_tweet_data/mod_tweet_data.lua
author Kim Alvefur <zash@zash.se>
Sun, 03 Mar 2024 11:23:40 +0100
changeset 5857 97c9b76867ca
parent 4705 efdc3e4dc5df
permissions -rw-r--r--
mod_log_ringbuffer: Detach event handlers on logging reload (thanks Menel) Otherwise the global event handlers accumulate, one added each time logging is reoladed, and each invocation of the signal or event triggers one dump of each created ringbuffer.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4601
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
     1
local mod_muc = module:depends("muc")
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
     2
local http = require "net.http"
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
     3
local st = require "util.stanza"
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
     4
local json = require "util.json"
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
     5
local url_pattern = [[https://twitter.com/%S+/status/%S+]]
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
     6
local xmlns_fasten = "urn:xmpp:fasten:0"
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
     7
local xmlns_xhtml = "http://www.w3.org/1999/xhtml"
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
     8
local twitter_apiv2_bearer_token = module:get_option_string("twitter_apiv2_bearer_token");
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
     9
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    10
local function fetch_tweet_data(room, url, tweet_id, origin_id)
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    11
	if not url then return; end
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    12
	local options = {
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    13
		method = "GET";
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    14
		headers = { Authorization = "Bearer "..twitter_apiv2_bearer_token; };
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    15
	};
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    16
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    17
	http.request(
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    18
		'https://api.twitter.com/2/tweets/'..tweet_id..'?expansions=author_id&tweet.fields=created_at,text&user.fields=id,name,username,profile_image_url',
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    19
		options,
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    20
		function(response_body, response_code, _)
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    21
			if response_code ~= 200 then
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    22
				module:log("debug", "Call to %s returned code %s and body %s", url, response_code, response_body)
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    23
				return;
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    24
			end
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    25
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    26
			local response = json.decode(response_body);
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    27
			if not response then return; end
4705
efdc3e4dc5df mod_tweet_data: Return when no tweet data returned
JC Brand <jc@opkode.com>
parents: 4601
diff changeset
    28
			if not response['data'] or not response['includes'] then return; end
4601
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    29
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    30
			local tweet = response['data'];
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    31
			local author = response['includes']['users'][1];
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    32
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    33
			local to = room.jid
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    34
			local from = room and room.jid or module.host
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    35
			local fastening = st.message({to = to, from = from, type = 'groupchat'}):tag("apply-to", {xmlns = xmlns_fasten, id = origin_id})
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    36
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    37
			fastening:tag(
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    38
				"meta",
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    39
				{
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    40
					xmlns = xmlns_xhtml,
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    41
					property = 'og:article:author',
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    42
					content = author['username']
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    43
				}
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    44
			):up()
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    45
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    46
			fastening:tag(
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    47
				"meta",
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    48
				{
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    49
					xmlns = xmlns_xhtml,
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    50
					property = 'og:article:published_time',
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    51
					content = tweet['created_at']
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    52
				}
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    53
			):up()
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    54
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    55
			fastening:tag(
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    56
				"meta",
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    57
				{
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    58
					xmlns = xmlns_xhtml,
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    59
					property = 'og:description',
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    60
					content = tweet['text']
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    61
				}
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    62
			):up()
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    63
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    64
			fastening:tag(
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    65
				"meta",
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    66
				{
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    67
					xmlns = xmlns_xhtml,
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    68
					property = 'og:image',
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    69
					content = author['profile_image_url']
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    70
				}
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    71
			):up()
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    72
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    73
			fastening:tag(
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    74
				"meta",
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    75
				{
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    76
					xmlns = xmlns_xhtml,
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    77
					property = 'og:title',
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    78
					content = author['username']
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    79
				}
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    80
			):up()
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    81
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    82
			fastening:tag(
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    83
				"meta",
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    84
				{
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    85
					xmlns = xmlns_xhtml,
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    86
					property = 'og:type',
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    87
					content = 'tweet'
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    88
				}
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    89
			):up()
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    90
			fastening:tag(
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    91
				"meta",
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    92
				{
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    93
					xmlns = xmlns_xhtml,
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    94
					property = 'og:url',
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    95
					content = 'https://twitter.com/'..author['username']..'/status/'..tweet['id']
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    96
				}
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    97
			):up()
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    98
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
    99
			mod_muc.get_room_from_jid(room.jid):broadcast_message(fastening)
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   100
			module:log("debug", tostring(fastening))
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   101
		end
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   102
	)
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   103
end
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   104
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   105
local function tweet_handler(event)
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   106
	local room, stanza = event.room, st.clone(event.stanza)
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   107
	local body = stanza:get_child_text("body")
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   108
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   109
	if not body then return; end
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   110
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   111
	local origin_id = stanza:find("{urn:xmpp:sid:0}origin-id@id")
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   112
	if not origin_id then return; end
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   113
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   114
	for url in body:gmatch(url_pattern) do
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   115
		local _, _, _, tweet_id = string.find(url, "https://twitter.com/(%S+)/status/(%S+)");
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   116
		fetch_tweet_data(room, url, tweet_id, origin_id);
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   117
	end
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   118
end
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   119
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   120
module:hook("muc-occupant-groupchat", tweet_handler)
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   121
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   122
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   123
module:hook("muc-message-is-historic", function (event)
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   124
	local fastening = event.stanza:get_child('apply-to', xmlns_fasten)
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   125
	if fastening and fastening:get_child('meta', xmlns_xhtml) then
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   126
		return true
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   127
	end
c858c76d0845 mod_tweet_data: New module that fetches and sends tweet data
JC Brand <jc@opkode.com>
parents:
diff changeset
   128
end);