@SuppressWarnings("PMD.NPathComplexity") // readability won't be improved upon split
    public static LogResult createLogTrackable(final TrackableLogEntry trackableLog, final Date date, final String log) {
        final String tbCode = trackableLog.geocode;

        if (StringUtils.isBlank(tbCode) || trackableLog == null || trackableLog.getAction() == LogTypeTrackable.DO_NOTHING) {
            generateLogError("Incomplete data for logging: " + trackableLog);
        }

        //1) Get CSRF Token
        final String csrfToken = getCsrfToken();
        if (csrfToken == null) {
            return generateLogError("Log Trackable Post: unable to extract CSRF Token in new Log Flow Page");
        }

        //2,) Fill Trackable Log Entry object and post it
        //  Exemplary JSOn to send: {"images":[],"logDate":"2023-09-08T23:13:36.414Z","logText":"Write a note for a trackable","logType":4,"trackingCode":null}
        final GCWebTrackableLogRequest logEntry = new GCWebTrackableLogRequest();
        logEntry.images = new String[0];
        logEntry.logDate = date;
        logEntry.logType = trackableLog.getAction().gcApiId;
        logEntry.logText = log;
        logEntry.trackingCode = trackableLog.trackingCode;

        // special case: if type is RETRIEVED, we need to fill reference code
        if (trackableLog.getAction() == LogTypeTrackable.RETRIEVED_IT) {
            //1.5) see if we find a geocache reference in the HTML from Trackable "Edit Log" page. URL is https://www.geocaching.com/live/trackable/TBxyz/log
            final String logPageHtml = httpReq().uri(getUrlForNewTrackableLog(tbCode)).request().blockingGet().getBodyString();
            final String geocacheReferenceJson = TextUtils.getMatch(logPageHtml, GCConstants.PATTERN_TB_CURRENT_GEOCACHE_JSON, null);
            if (geocacheReferenceJson != null) {
                final GCGeocacheReference gcRef = JsonUtils.readValueFailSilently("{" + geocacheReferenceJson + "}", GCGeocacheReference.class, null);
                if (gcRef != null) {
                    logEntry.geocacheReferenceCode = gcRef.referenceCode;
                }
            }
        }

        //URL: https://www.geocaching.com/api/live/v1/logs/TBxyz/trackableLog
        try (GCWebTrackableLogResponse response = websiteReq().uri("/api/live/v1/logs/" + tbCode + "/trackableLog")
                .method(HttpRequest.Method.POST)
                .headers(HTML_HEADER_CSRF_TOKEN, csrfToken)
                .bodyJson(logEntry)
                .requestJson(GCWebTrackableLogResponse.class).blockingGet()) {
            if (response.logReferenceCode == null) {
                return generateLogError("Problem pasting trackable log, response is: " + response + ", request was:" + HttpRequest.safeGetJsonBody(logEntry));
            }

            return LogResult.ok(response.logReferenceCode);
        }


    }
Provides methods to handle all aspects of creating, editing and deleting Log entries for GC.com (both caches and trackables)
main/src/main/java/cgeo/geocaching/connector/gc/GCLogAPI.java