87 lines · 2.8 KB · Lua
RawDownload
-- plugins/weather.lua-- Weather plugin using wttr.in (no API key required).-- Accepts a location (city name, airport code, zip, coordinates, etc.)-- and returns current conditions. clm.tool_register("get_weather", {    description = [[Get current weather for a location using wttr.in.If the user does not specify a location or just asks for the weather, use the empty string "".Accepts city names, airport codes (3 letters), zip/area codes,or GPS coordinates (e.g. '-78.46,106.79').]],    params_schema = {        type = "object",        properties = {            location = {                type = "string",                description = "city name, airport code, zip code, or "                    .. "GPS coordinates",            },        },        required = { "location" },    },    timeout_ms = 15000,    invoke = function(args, ctx)        local loc = args.location or ""        if loc ~= "" then            loc = string.gsub(loc, " ", "+")        end         local url = "https://wttr.in/" .. loc .. "?format=j1"         local resp, err = http.get(url)        if err then            ctx:fail("HTTP request failed: " .. err)            return        end         if resp.status ~= 200 then            ctx:fail("wttr.in returned status " .. tostring(resp.status))            return        end         local data = json.decode(resp.body)        if not data or not data.current_condition then            ctx:fail("unexpected response format from wttr.in")            return        end         local cc = data.current_condition[1]        if not cc then            ctx:fail("no current_condition in response")            return        end         -- Extract the weather description text.        local desc = "unknown"        if cc.weatherDesc and cc.weatherDesc[1] then            desc = cc.weatherDesc[1].value or "unknown"        end         -- Get the human-readable location name. The JSON API returns        -- junk areaNames for IP queries, but format=%l always works.        local area = args.location        local loc_url = "https://wttr.in/" .. loc .. "?format=%l"        local lr, lerr = http.get(loc_url)        if lr and lr.status == 200 and lr.body and lr.body ~= "" then            -- Trim trailing whitespace/newline.            area = string.gsub(lr.body, "%s+$", "")        end         local result = string.format(            "%s: %s\n"            .. "Temperature: %s°F (feels like %s°F)\n"            .. "Wind: %s mph %s\n"            .. "Humidity: %s%%\n"            .. "Cloud cover: %s%%\n"            .. "Visibility: %s miles",            area, desc,            cc.temp_F or "?", cc.FeelsLikeF or "?",            cc.windspeedMiles or "?", cc.winddir16Point or "",            cc.humidity or "?",            cc.cloudcover or "?",            cc.visibilityMiles or "?")         ctx:complete(result)    end,})