GPAL.yaml is created and loaded automatically every run. A handful of optional config files -- credentialsConfig.json, LLMDigestRules.yaml, googleDorkingConfig.json -- follow the same Load/Save pattern but are only written when you call Save(). GPALRESTAPI also keeps a single emergency crash log.
The first time your program runs in a given directory, GPAL.yaml does not exist, so GPAL creates it next to your executable with default settings and publishes a warning event telling you it did so. On every run after that, GPAL loads the file automatically and confirms it with an info event. GPAL.yaml holds the same settings you can configure in code -- things like typing delays, match thresholds, and driver behavior. If the file's version does not match the running GPAL version, GPAL updates it automatically. Edit GPAL.yaml by hand to change your defaults, or call GPAL.SaveSettings() to persist settings you changed at runtime.
GPAL.InformationHandler += (sender, e) => Console.WriteLine(e.Message);
// First run in this directory: GPAL.yaml does not exist yet, so GPAL
// creates it with default settings and publishes a WARNING.
// Every later run: GPAL.yaml exists, so GPAL loads it and publishes an INFO.
GPAL.WithMatchingPercentage(90)
.WithDownloadTimeoutInSec(30);
// Persist the settings above back to GPAL.yaml
GPAL.SaveSettings();
Beyond GPAL.yaml, a small set of optional config files can be written to disk when you want to tune behavior without recompiling -- for credential OAuth endpoints, LLM page digest cleanup rules, and Google search API settings. All of them follow the same pattern: loading one returns built-in defaults in memory without writing anything to disk. Only an explicit Save() creates the file, so a fresh machine has none of them until you or your code decides to generate one.
// LLMDigestRules.yaml does not exist on disk until you save it
DigestRulesConfig digestRules = DigestRulesConfig.Default();
digestRules.Save();
// credentialsConfig.json works the same way - Load() returns
// defaults in memory, Save() writes them out for hand-editing
CredentialsConfig credentials = CredentialsConfig.Load();
credentials.GoogleRestRedirectUri = "http://localhost:3000/access-token";
credentials.Save();
Unlike GPAL.yaml, these three files are entirely optional. If they are missing, Load() quietly returns built-in defaults and your code keeps running. Only an explicit Save() writes the file, so a fresh checkout of your project has none of them until you. Or your code. Decides to create one.
GPALRESTAPI. The REST API host used by OttoMagic. Keeps a single emergency log at C: empGPALRestApiCrash.log. It is only written when something goes wrong before or outside the normal GPAL event system: an exception during startup, or an unhandled exception that would otherwise crash the process with no record. Each entry appends a timestamp, the exception, and its stack trace to the file. Older entries are never removed automatically. When an unhandled exception is caught, GPALRESTAPI also shows a desktop toast notification pointing you at the file.
Plain GPAL library code never writes C: empGPALRestApiCrash.log -- only the GPALRESTAPI host process does, as a last resort when something has gone wrong before, or outside of, the normal event system. For ordinary errors in your own GPAL code, subscribe to GPAL.ExceptionHandler as described in the event system concepts -- GPAL does not write files or logs on its own otherwise.
Showing off some plain text in these paragraphs eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Here you can find different accents and emphasis sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
This is a link and how it could look like bestlinkinthebeautifulworld. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Here's just some classic bold text adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam notBoldSecondbestlinkinthebeautifulworld illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at adipisicing elit libero vel voluptas? Expedita, adipisicing facere dolores voluptatem ad ab rem assumenda soluta!
Other cuple of colors in case we want to emphasize several ways adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at voluptatem libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Repudiandae quas consequuntur illo numquam assumenda autem exercitationem distinctio perspiciatis in natus. Eius dicta similique ipsam ipsa minima, nemo quae enim tempore.
GPAL
.CallIfNotFound(GenericCallIfNotFound)
.WithPublishToConsole();
//System.Drawing.Rectangle windowSize = new System.Drawing.Rectangle(10, 10, 1500, 1024);
// NOTE: we have to set browser = before we execute any steps
// this is due to the 'GenericCallIfNotFound' which might throw an exception, and BankScraper will not have the browser set when it calls scraper.Close()
// until the complete fluent line gets executed (meaning every step, meaning browser is not set until everything else succeeds)
browser = GPAL.Browser
.WithBrowserType(Enums.BrowserType.Chrome)
.WithProfileDataDirectory(ChromeProfileLocation)
.WithUseAutomationEngine(AutomationEngine.Selenium)
.WithWindowSize(new System.Drawing.Rectangle(0,0,1920,1080))
.ToGPALObject();