function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Spencer Widman 9Spencer Widman 9 

High Level APEX Class for HTTP Callout

I am  writing my first APEX class and I need some high level help if anyone is willing.  This is what I am trying to accomplish:

Org is an NPSP org.  Using the Salesforce Labs Event package to house events.  Events have associated Registration records. There is a custom field on the Contact record containing a Strava Member Id. I would like to build an APEX class that makes a call out to the Strava API and query the organization Strava Club with the Club Id Number. 

I would like to return Strava data for club members who have an active Registration for the Event. If they have a registration then I want to return Strava member data for the time period associated with the event. If the Strava Activity record exists, then update the record, if not create the record.  The record should be related with a master detail relationship with the Event Registration.

I anticipate this class being executed manually with a Lightning Component on the Event Lighting Page. 

I have attempted to write this but can't seem to pull it all together.  If anyone wants to take a look I can post the Strava Class and Helper classes that I have. 

I guess I am looking for Highlevel steps on what best practices are to accomplish this to make sure I am on the right track.  Hopefully this is detailed enough.  Thanks for any thoughts.
Best Answer chosen by Spencer Widman 9
Prateek Prasoon 25Prateek Prasoon 25
Create a new Apex class and define the necessary instance variables and methods to handle the data manipulation and the Strava API integration.
Define a method that will retrieve the necessary event and registration data. You can use SOQL queries to retrieve the event and registration data related to the Contact record.
Define a method that will make a callout to the Strava API using the Strava member ID and club ID. You can use the Http class in Apex to make the callout.
Parse the response from the Strava API to extract the necessary data, such as the Strava activity data.
Define a method that will update or create a new Strava Activity record associated with the Event Registration. You can use the Database class in Apex to perform the DML operation.
Add error handling and logging to ensure that any errors or issues are properly handled and logged for debugging purposes.
Finally, create a Lightning component that will allow the user to execute the Apex class manually on the Event page. You can use the lightning:button component to trigger the execution of the Apex class.
Here's some sample code to get you started:
public with sharing class StravaSync {
    public static void syncStravaData(Set<Id> registrationIds) {
        
        // First, query for all the registrations with the given Ids
        List<EventApi__EventRegistration__c> registrations = [
            SELECT Id, Contact__r.Strava_Member_Id__c, Event__r.Start_Date__c, Event__r.End_Date__c
            FROM EventApi__EventRegistration__c
            WHERE Id IN :registrationIds AND EventApi__Status__c = 'Active'
        ];
        
        // Then, for each registration, make a callout to the Strava API and fetch the member data
        for (EventApi__EventRegistration__c registration : registrations) {
            
            // Check if the Contact has a Strava Member Id
            if (String.isNotBlank(registration.Contact__r.Strava_Member_Id__c)) {
                
                // Make the callout to the Strava API
                String stravaMemberId = registration.Contact__r.Strava_Member_Id__c;
                String startDate = registration.Event__r.Start_Date__c.formatGMT('yyyy-MM-dd');
                String endDate = registration.Event__r.End_Date__c.formatGMT('yyyy-MM-dd');
                String stravaUrl = 'https://www.strava.com/api/v3/athlete/activities?after=' + startDate + '&before=' + endDate;
                HttpRequest req = new HttpRequest();
                req.setEndpoint(stravaUrl);
                req.setMethod('GET');
                req.setHeader('Authorization', 'Bearer ' + getStravaAccessToken());
                Http http = new Http();
                HttpResponse res = http.send(req);
                
                // Parse the JSON response and create/update Strava Activity records as necessary
                List<StravaActivity> activities = (List<StravaActivity>) JSON.deserialize(res.getBody(), List<StravaActivity>.class);
                List<EventApi__StravaActivity__c> stravaActivities = new List<EventApi__StravaActivity__c>();
                for (StravaActivity activity : activities) {
                    if (activity.athlete.id == stravaMemberId) {
                        EventApi__StravaActivity__c stravaActivity = new EventApi__StravaActivity__c();
                        stravaActivity.Name = activity.name;
                        stravaActivity.Start_Date_Time__c = DateTime.parse(activity.start_date).addHours(7); // Adjust for time zone
                        stravaActivity.Distance__c = activity.distance;
                        stravaActivity.Max_Speed__c = activity.max_speed;
                        stravaActivity.Average_Speed__c = activity.average_speed;
                        stravaActivity.Elapsed_Time__c = activity.elapsed_time;
                        stravaActivity.Event_Registration__c = registration.Id;
                        stravaActivities.add(stravaActivity);
                    }
                }
                upsert stravaActivities EventApi__StravaActivity__c.Event_Registration__c;
            }
        }
    }
    
    private static String getStravaAccessToken() {
        // TODO: Implement this method to retrieve the Strava access token from a custom setting or configuration object
        return '';
    }
    
    private class StravaActivity {
        public String name;
        public StravaAthlete athlete;
        public String start_date;
        public Double distance;
        public Double max_speed;
        public Double average_speed;
        public Integer elapsed_time;
    }
    
    private class StravaAthlete {
        public String id;
    }
    
}

to make the callout to the Strava API, you'll need to create a new Apex class with a method that will handle the callout. Here's an example of what that might look like:
 
public with sharing class StravaAPI {
    public static String makeCallout(String clubId) {
        String endpoint = 'https://www.strava.com/api/v3/clubs/' + clubId + '/members';
        HttpRequest request = new HttpRequest();
        request.setEndpoint(endpoint);
        request.setMethod('GET');
        request.setHeader('Authorization', 'Bearer ' + '[your access token]');
        Http http = new Http();
        HttpResponse response = http.send(request);
        if (response.getStatusCode() == 200) {
            return response.getBody();
        } else {
            return 'Callout failed with response code ' + response.getStatusCode() + ' and message ' + response.getStatus();
        }
    }
}

If you find my answer helpful, please mark it as the best answer. Thanks!

All Answers

VinayVinay (Salesforce Developers) 
HI Spencer,

You can reach out to Salesforce nonprofit group on
https://trailhead.salesforce.com/trailblazer-community/groups/0F9300000001ocxCAA?tab=discussion&sort=LAST_MODIFIED_DATE_DESC

Please close the thread by selected as Best Answer so that we can keep our community clean

Thanks,
Prateek Prasoon 25Prateek Prasoon 25
Create a new Apex class and define the necessary instance variables and methods to handle the data manipulation and the Strava API integration.
Define a method that will retrieve the necessary event and registration data. You can use SOQL queries to retrieve the event and registration data related to the Contact record.
Define a method that will make a callout to the Strava API using the Strava member ID and club ID. You can use the Http class in Apex to make the callout.
Parse the response from the Strava API to extract the necessary data, such as the Strava activity data.
Define a method that will update or create a new Strava Activity record associated with the Event Registration. You can use the Database class in Apex to perform the DML operation.
Add error handling and logging to ensure that any errors or issues are properly handled and logged for debugging purposes.
Finally, create a Lightning component that will allow the user to execute the Apex class manually on the Event page. You can use the lightning:button component to trigger the execution of the Apex class.
Here's some sample code to get you started:
public with sharing class StravaSync {
    public static void syncStravaData(Set<Id> registrationIds) {
        
        // First, query for all the registrations with the given Ids
        List<EventApi__EventRegistration__c> registrations = [
            SELECT Id, Contact__r.Strava_Member_Id__c, Event__r.Start_Date__c, Event__r.End_Date__c
            FROM EventApi__EventRegistration__c
            WHERE Id IN :registrationIds AND EventApi__Status__c = 'Active'
        ];
        
        // Then, for each registration, make a callout to the Strava API and fetch the member data
        for (EventApi__EventRegistration__c registration : registrations) {
            
            // Check if the Contact has a Strava Member Id
            if (String.isNotBlank(registration.Contact__r.Strava_Member_Id__c)) {
                
                // Make the callout to the Strava API
                String stravaMemberId = registration.Contact__r.Strava_Member_Id__c;
                String startDate = registration.Event__r.Start_Date__c.formatGMT('yyyy-MM-dd');
                String endDate = registration.Event__r.End_Date__c.formatGMT('yyyy-MM-dd');
                String stravaUrl = 'https://www.strava.com/api/v3/athlete/activities?after=' + startDate + '&before=' + endDate;
                HttpRequest req = new HttpRequest();
                req.setEndpoint(stravaUrl);
                req.setMethod('GET');
                req.setHeader('Authorization', 'Bearer ' + getStravaAccessToken());
                Http http = new Http();
                HttpResponse res = http.send(req);
                
                // Parse the JSON response and create/update Strava Activity records as necessary
                List<StravaActivity> activities = (List<StravaActivity>) JSON.deserialize(res.getBody(), List<StravaActivity>.class);
                List<EventApi__StravaActivity__c> stravaActivities = new List<EventApi__StravaActivity__c>();
                for (StravaActivity activity : activities) {
                    if (activity.athlete.id == stravaMemberId) {
                        EventApi__StravaActivity__c stravaActivity = new EventApi__StravaActivity__c();
                        stravaActivity.Name = activity.name;
                        stravaActivity.Start_Date_Time__c = DateTime.parse(activity.start_date).addHours(7); // Adjust for time zone
                        stravaActivity.Distance__c = activity.distance;
                        stravaActivity.Max_Speed__c = activity.max_speed;
                        stravaActivity.Average_Speed__c = activity.average_speed;
                        stravaActivity.Elapsed_Time__c = activity.elapsed_time;
                        stravaActivity.Event_Registration__c = registration.Id;
                        stravaActivities.add(stravaActivity);
                    }
                }
                upsert stravaActivities EventApi__StravaActivity__c.Event_Registration__c;
            }
        }
    }
    
    private static String getStravaAccessToken() {
        // TODO: Implement this method to retrieve the Strava access token from a custom setting or configuration object
        return '';
    }
    
    private class StravaActivity {
        public String name;
        public StravaAthlete athlete;
        public String start_date;
        public Double distance;
        public Double max_speed;
        public Double average_speed;
        public Integer elapsed_time;
    }
    
    private class StravaAthlete {
        public String id;
    }
    
}

to make the callout to the Strava API, you'll need to create a new Apex class with a method that will handle the callout. Here's an example of what that might look like:
 
public with sharing class StravaAPI {
    public static String makeCallout(String clubId) {
        String endpoint = 'https://www.strava.com/api/v3/clubs/' + clubId + '/members';
        HttpRequest request = new HttpRequest();
        request.setEndpoint(endpoint);
        request.setMethod('GET');
        request.setHeader('Authorization', 'Bearer ' + '[your access token]');
        Http http = new Http();
        HttpResponse response = http.send(request);
        if (response.getStatusCode() == 200) {
            return response.getBody();
        } else {
            return 'Callout failed with response code ' + response.getStatusCode() + ' and message ' + response.getStatus();
        }
    }
}

If you find my answer helpful, please mark it as the best answer. Thanks!
This was selected as the best answer
Spencer Widman 9Spencer Widman 9
Thank you very much for taking the time Prateek.  This is exactly what I weas looking for and more.  I was close on some of it but off on others and your sample code really helped clarify when looking at the code I had written.  Thanks again for the insight and taking the time.