Page MenuHomePhabricator (Chris)

search.lua
No OneTemporary

Authored By
Unknown
Size
4 KB
Referenced Files
None
Subscribers
None

search.lua

--[[
mattata v2.0 - Search Plugin
Web search using DuckDuckGo Instant Answers API.
]]
local plugin = {}
plugin.name = 'search'
plugin.category = 'utility'
plugin.description = 'Search the web using DuckDuckGo'
plugin.commands = { 'search', 'ddg', 'google' }
plugin.help = '/search <query> - Search the web using DuckDuckGo Instant Answers.'
local https = require('ssl.https')
local json = require('dkjson')
local url = require('socket.url')
local ltn12 = require('ltn12')
local tools = require('telegram-bot-lua.tools')
local function search(query)
local encoded = url.escape(query)
local request_url = 'https://api.duckduckgo.com/?q=' .. encoded .. '&format=json&no_redirect=1&no_html=1&skip_disambig=1'
local body = {}
local _, code = https.request({
url = request_url,
sink = ltn12.sink.table(body),
headers = {
['User-Agent'] = 'mattata-telegram-bot/2.0'
}
})
if code ~= 200 then
return nil, 'Search request failed (HTTP ' .. tostring(code) .. ').'
end
local data = json.decode(table.concat(body))
if not data then
return nil, 'Failed to parse search results.'
end
return data
end
local function format_results(data, query)
local lines = {}
-- Abstract (instant answer)
if data.AbstractText and data.AbstractText ~= '' then
table.insert(lines, '<b>' .. tools.escape_html(data.Heading or query) .. '</b>')
table.insert(lines, '')
local abstract = data.AbstractText
if #abstract > 500 then
abstract = abstract:sub(1, 497) .. '...'
end
table.insert(lines, tools.escape_html(abstract))
if data.AbstractURL and data.AbstractURL ~= '' then
table.insert(lines, '')
table.insert(lines, '<a href="' .. tools.escape_html(data.AbstractURL) .. '">Read more</a>')
end
return table.concat(lines, '\n')
end
-- Answer (calculations, conversions, etc.)
if data.Answer and data.Answer ~= '' then
local answer = data.Answer:gsub('<[^>]+>', '') -- strip HTML tags
table.insert(lines, '<b>Answer:</b> ' .. tools.escape_html(answer))
return table.concat(lines, '\n')
end
-- Definition
if data.Definition and data.Definition ~= '' then
table.insert(lines, '<b>Definition:</b>')
table.insert(lines, tools.escape_html(data.Definition))
if data.DefinitionSource and data.DefinitionSource ~= '' then
table.insert(lines, '<i>Source: ' .. tools.escape_html(data.DefinitionSource) .. '</i>')
end
return table.concat(lines, '\n')
end
-- Related topics
if data.RelatedTopics and #data.RelatedTopics > 0 then
table.insert(lines, '<b>Results for:</b> ' .. tools.escape_html(query))
table.insert(lines, '')
local count = 0
for _, topic in ipairs(data.RelatedTopics) do
if count >= 5 then break end
if topic.Text and topic.Text ~= '' then
local text = topic.Text
if #text > 200 then
text = text:sub(1, 197) .. '...'
end
if topic.FirstURL and topic.FirstURL ~= '' then
table.insert(lines, '<a href="' .. tools.escape_html(topic.FirstURL) .. '">' .. tools.escape_html(text) .. '</a>')
else
table.insert(lines, tools.escape_html(text))
end
count = count + 1
end
end
if count > 0 then
return table.concat(lines, '\n')
end
end
-- Redirect (bang or direct answer)
if data.Redirect and data.Redirect ~= '' then
return '<b>Redirect:</b> <a href="' .. tools.escape_html(data.Redirect) .. '">' .. tools.escape_html(query) .. '</a>'
end
return nil
end
function plugin.on_message(api, message, ctx)
local input = message.args
if not input or input == '' then
return api.send_message(
message.chat.id,
'Please provide a search query.\nUsage: <code>/search your query here</code>',
'html'
)
end
local data, err = search(input)
if not data then
return api.send_message(message.chat.id, err)
end
local output = format_results(data, input)
if not output then
local ddg_url = 'https://duckduckgo.com/?q=' .. url.escape(input)
return api.send_message(
message.chat.id,
'No instant answers found. <a href="' .. tools.escape_html(ddg_url) .. '">Search on DuckDuckGo</a>',
'html',
true
)
end
return api.send_message(message.chat.id, output, 'html', true)
end
return plugin

File Metadata

Mime Type
text/html
Expires
Sat, Nov 14, 11:25 PM (1 d, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
136918
Default Alt Text
search.lua (4 KB)

Event Timeline