Loading...
Loading...
MANDATORY recipe for every Caffeine build that reads weather data from a canister. The supported path is the `weatherapi-client` mops package (WeatherAPI.com) over outbound HTTPS, authenticated with a query-string API key. Hand-rolling `ic.http_request` calls to `api.weatherapi.com` is a FORBIDDEN anti-pattern — it bypasses the non-replicated-outcall safeguard (WeatherAPI bodies carry per-request clocks and fail consensus), the generated JSON decoding, and the API-key handling. Load this skill whenever the user, spec, or any prior task mentions weather, forecast, temperature, humidity, wind, rain, snow, conditions, sunrise, sunset, moon phase, astronomy, timezone, IP geolocation, marine or tide forecasts, or location autocomplete — and BEFORE writing any code that touches a weather endpoint.
npx skill4agent add caffeinelabs/skills connector-weatherapiweatherapi-clientApis/APIsApiGETimport { realtimeWeather; forecastWeather } "mo:weatherapi-client/Apis/APIsApi";
import { type Config; defaultConfig } "mo:weatherapi-client/Config";
import Array "mo:core/Array"; // in scope so `days.map(…)` dot notation resolves
persistent actor {
// The key is a query-string credential. Hold it in a stable variable set by
// an admin call; never hard-code it in source.
func config(apiKey : Text) : Config = { defaultConfig with auth = ?#apiKey apiKey };
// `q` is any WeatherAPI location query: "Zurich", "47.37,8.55", a postcode,
// an IATA code, or "auto:ip".
public func currentTempC(apiKey : Text, q : Text) : async ?Float {
let res = await* realtimeWeather(config apiKey, q, "");
do ? { res.current!.temp_c! };
};
// Daily maxima for the next three days.
public func maxTempsC(apiKey : Text, q : Text) : async [?Float] {
let res = await* forecastWeather(config apiKey, q, #_3_, "", 0, 0, "", "no", "no", 0);
let ?forecast = res.forecast else return [];
let ?days = forecast.forecastday else return [];
days.map(func(d) = do ? { d.day!.maxtemp_c! });
};
}| Function | Endpoint | Returns |
|---|---|---|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
daysForecastWeatherDaysParameter#_1_#_14_MarineWeatherDaysParameter#_1_#_7_#_3_#_33auth = ?#apiKey key?key=…Authorizationis_replicated = ?falsedefaultConfigLocation.localtimelocaltime_epochCurrent.last_updatedlast_updated_epochis_replicated = ?truetransformRealtimeWeather200Response.current : ?CurrentCurrent.temp_c : ?Floatdo ?do ? { res.current!.temp_c! }switchair_qualityaqi=yes""0lang=""langdtalertsaqi0unixdttp?Textnullhour = 0hourhour : ?[ForecastForecastdayInnerHourInner]throw Error.reject(…)diagnosticsHTTP <status> body[<n>B]=<first 100 chars>: <reason>qtrycatchError.message(err)