Skip to content

Instantly share code, notes, and snippets.

@tyoshikawa1106
Created January 5, 2026 21:48
Show Gist options
  • Select an option

  • Save tyoshikawa1106/37bdfd3159dfb5bb8a651f85e0b32ba1 to your computer and use it in GitHub Desktop.

Select an option

Save tyoshikawa1106/37bdfd3159dfb5bb8a651f85e0b32ba1 to your computer and use it in GitHub Desktop.
TrailheadのApexでエージェントをカスタマイズ
public with sharing class CheckWeather {
@InvocableMethod(
label='Check Weather'
description='Check weather at Coral Cloud Resorts at a specific date'
)
public static List<WeatherResponse> getWeather(
List<WeatherRequest> requests
) {
// Retrieve the date for which we want to check the weather
Datetime dateToCheck = (Datetime) requests[0].dateToCheck;
WeatherService.Weather weather = WeatherService.getResortWeather(
dateToCheck
);
// Create the response for Copilot
WeatherResponse response = new WeatherResponse();
response.minTemperature = weather.minTemperatureC;
response.maxTemperature = weather.maxTemperatureC;
response.temperatureDescription =
'Temperatures will be between ' +
weather.minTemperatureC +
'°C (' +
weather.minTemperatureF +
'°F) and ' +
weather.maxTemperatureC +
'°C (' +
weather.maxTemperatureF +
'°F) at Coral Cloud.';
return new List<WeatherResponse>{ response };
}
public class WeatherRequest {
@InvocableVariable(
required=true
description='Date for which we want to check the temperature. The variable needs to be an Apex Date type with format yyyy-MM-dd.'
)
public Date dateToCheck;
}
public class WeatherResponse {
@InvocableVariable(
description='Minimum temperature in Celsius at Coral Cloud Resorts location for the provided date'
)
public Decimal minTemperature;
@InvocableVariable(
description='Maximum temperature in Celsius at Coral Cloud Resorts location for the provided date'
)
public Decimal maxTemperature;
@InvocableVariable(
description='Description of temperatures at Coral Cloud Resorts location for the provided date'
)
public String temperatureDescription;
}
}
public class WeatherService {
/**
* Gets the weather at Coral Cloud Resorts for the provided date
*/
public static Weather getResortWeather(Datetime dateToCheck) {
// Copilot was trained in 2023 so it will use 2023 as the default year if
// the user does not specify a year in their prompt. This means that we need
// to adjust the input date to be on the current year.
Integer currentYear = Date.today().year();
Integer yearDelta = currentYear - dateToCheck.year();
dateToCheck = dateToCheck.addYears(yearDelta);
String isoDate = dateToCheck.format('yyyy-MM-dd');
String dateString = dateToCheck.format('MMMM d');
// Prepare API request
HttpRequest req = new HttpRequest();
req.setEndpoint(
'callout:Weather_Endpoint/weather?lat=37.789782764570425&lon=-122.39723702244089&date=' +
isoDate
);
req.setMethod('GET');
// Make callout
Http http = new Http();
HttpResponse res = http.send(req);
if (res.getStatusCode() != 200) {
throw new CalloutException('Bad response: ' + res);
}
// The response contains a list of temperatures for different times of the day
// We parse the response and find the min and max temperatures
String body = res.getBody();
WeatherApiResponse weatherResponse = (WeatherApiResponse) JSON.deserialize(
body,
WeatherAPIResponse.class
);
List<Decimal> temperatures = new List<Decimal>();
for (TemperatureWrapper item : weatherResponse.weather) {
if (item.temperature != null) {
temperatures.add(item.temperature);
}
}
temperatures.sort();
// Prepare temperatures and description
Decimal minTempC = temperatures[0];
Decimal maxTempC = temperatures[temperatures.size() - 1];
Decimal minTempF = toFahrenheit(minTempC);
Decimal maxTempF = toFahrenheit(maxTempC);
String description =
'On ' +
dateString +
', temperature should be between ' +
minTempC +
'°C (' +
minTempF +
'°F) and ' +
maxTempC +
'°C (' +
maxTempF +
'°F) at Coral Cloud Resorts.';
// Return weather info
Weather weather = new Weather();
weather.minTemperatureC = minTempC;
weather.minTemperatureF = minTempF;
weather.maxTemperatureC = maxTempC;
weather.maxTemperatureF = maxTempF;
weather.description = description;
return weather;
}
private static Decimal toFahrenheit(Decimal celsius) {
return (celsius * 9 / 5 + 32).setScale(1);
}
private class WeatherApiResponse {
public List<TemperatureWrapper> weather;
}
private class TemperatureWrapper {
public Decimal temperature;
}
public class Weather {
public Decimal minTemperatureC;
public Decimal minTemperatureF;
public Decimal maxTemperatureC;
public Decimal maxTemperatureF;
public String description;
}
}
@isTest
private class WeatherServiceTest {
@isTest
static void getResortWeather_works() {
// Set up test data
Datetime dateToCheck = Datetime.newInstance(2024, 7, 14);
// Set up mock HTTP response
String mockResponse = '{"weather": [{"temperature": 10.0},{"temperature": 30.0}]}';
Test.setMock(
HttpCalloutMock.class,
new MockHttpResponse(200, mockResponse)
);
// Call the method to be tested
Test.startTest();
WeatherService.Weather weather = WeatherService.getResortWeather(
dateToCheck
);
Test.stopTest();
// Assert the results
Assert.areEqual(10.0, weather.minTemperatureC);
Assert.areEqual(50.0, weather.minTemperatureF);
Assert.areEqual(30.0, weather.maxTemperatureC);
Assert.areEqual(86.0, weather.maxTemperatureF);
Assert.areEqual(
'On July 14, temperature should be between 10.0°C (50.0°F) and 30.0°C (86.0°F) at Coral Cloud Resorts.',
weather.description
);
}
@isTest
static void getResortWeather_failsWithError() {
// Set up mock HTTP response
Test.setMock(HttpCalloutMock.class, new MockHttpResponse(404, ''));
// Call the method to be tested
Test.startTest();
try {
WeatherService.getResortWeather(Datetime.newInstance(2024, 7, 14));
Assert.fail('Expected CalloutException');
} catch (CalloutException e) {
System.assert(e.getMessage().startsWith('Bad response'));
}
Test.stopTest();
}
private class MockHttpResponse implements HttpCalloutMock {
private Integer statusCode;
private String body;
public MockHttpResponse(Integer statusCode, String body) {
this.statusCode = statusCode;
this.body = body;
}
public HttpResponse respond(HttpRequest request) {
HttpResponse res = new HttpResponse();
res.setBody(body);
res.setStatusCode(statusCode);
return res;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment