How would I automate several delayed commands in AppleScript? Let's say I want to automate the following tasks:
Send the letter &quot;a&quot; twice every 2 minutes
Send the letter &quot;b&quot; ever 30 minutes
and send the letter &quot;C&quot; every 1 hour.
If I make a loop with delays in it, then I won't be able to repeatedly send &quot;a&quot; - I can only send it once in the first 2 minute cycle, not every time.  What can I do to put together all these commands?  Do I just have to make several running scripts?
Not sure if you realize it but key stokes sent by System Events goes to the active front most window of the front most application and as such the target must remain front most and you basically cannot use the computer for anything else while the process is happening.
The example AppleScript code, shown below, was tested under macOS Catalina as an AppleScript stay open application, with Language &amp; Region settings in System Preferences set to English (US) — Primary and worked for me without issue1.

1  Assumes necessary and appropriate setting in System Preferences &gt; Security &amp; Privacy &gt; Privacy have been set/addressed as needed.

In Script Editor, copy and paste the example AppleScript code into a new document and change &quot;TextEdit&quot; and &quot;Untitled&quot; to the appropriate values for the target application and window you want the key stokes to go to. The existing values were for testing purposes.
When saving, on the Save As: sheet, change File Format: to [Application], and under Options: check the [√] Stay open after run handler checkbox.

Example AppleScript code:
property appName : &quot;TextEdit&quot;
property winName : &quot;Untitled&quot;

global theCounter

on run
    set theCounter to 0
    delay 60
end run

on idle
    my isItTimetoSendKeystroke()
    return 60
end idle

on isItTimetoSendKeystroke()
    set theCounter to theCounter + 1
    if (theCounter mod 2) = 0 then
        my sendKeystroke(&quot;a&quot;)
        my sendKeystroke(&quot;a&quot;)
    end if
    if (theCounter mod 30) = 0 then
        my sendKeystroke(&quot;b&quot;)
    end if
    if (theCounter mod 60) = 0 then
        my sendKeystroke(&quot;C&quot;)
    end if
end isItTimetoSendKeystroke

to sendKeystroke(thisKey)
    tell application &quot;System Events&quot;
        tell application process appName
            set frontmost to true
            perform action &quot;AXRaise&quot; of window winName
            keystroke thisKey
        end tell
    end tell
end sendKeystroke

on quit
    continue quit
end quit


Notes:
If you are just automating the typing of text into a text box or document, you can delete one of the my sendKeystroke(&quot;a&quot;) and change the other to my sendKeystroke(&quot;aa&quot;), otherwise if simulating a key press for, say a game, then you would probably want it as it's currently coded.
UI Scripting can be kludgy and prone to failure.
Some applications will not respond to keystroke and or key code commands of System Events, as they are designed not to respond this type of event in this manner. Games are the typical type of application that may not respond.
Personally, I do not like this type of UI Scripting and have posted this more just as a proof of concept. It has been my experience that some AppleScript stay open applications can over time consume more memory and eventually crash. They can also cause the fans to spin up and maintain high RPMs. This probably has to do more so with some of the code being run, however, as a general rule I try to accomplish the task in a different way that does not become resource intensive, if possible.
Credit to Tetsujin for his comment to the OP, which was the basis for this answer.

Note: The example AppleScript code is just that and sans any included error handling does not contain any additional error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.