<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Marcus&#039; Macro Scheduler Blog</title>
	<atom:link href="https://www.mjtnet.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.mjtnet.com/blog</link>
	<description>Macro Recording and Automating Windows with Macro Scheduler - Tips &#38; News</description>
	<lastBuildDate>Sun, 25 Oct 2026 07:54:27 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.1.1</generator>
	<item>
	<title>The Week I Didn&#8217;t Get Much Software Development Done</title>
		<link>https://www.mjtnet.com/blog/2026/10/25/the-week-i-didnt-get-much-software-development-done/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Sun, 25 Oct 2026 07:54:01 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3304</guid>

					<description><![CDATA[I&#8217;ve been developing software for over 30 years. These days, as well as developing Windows software, I also build and maintain a number of cloud-based applications. Most of the time everything runs smoothly and I can get on with what I enjoy doing — writing code. Last week was a little different. Monday Morning At [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>I&#8217;ve been developing software for over 30 years. These days, as well as developing Windows software, I also build and maintain a number of cloud-based applications. Most of the time everything runs smoothly and I can get on with what I enjoy doing — writing code.</p>
<p>Last week was a little different.</p>
<h2>Monday Morning</h2>
<p>At around 7am on Monday, one of the applications I maintain stopped working. I checked the monitoring and discovered that the database was unavailable. Google Cloud SQL had initiated a failover.</p>
<p>Oh, here we go.</p>
<p>The database runs in a high-availability configuration, with a standby instance ready to take over if the primary fails. I&#8217;ve paid for that extra redundancy precisely because I don&#8217;t want an application going offline every time Google has a problem with a server.</p>
<p>Except it wasn&#8217;t failing over.</p>
<p>The Google Cloud console showed the failover operation in progress, but nothing seemed to be happening. I checked the logs, looked at the database metrics and tried to work out whether something in the application had triggered it.</p>
<p>Meanwhile, the application was down and there wasn&#8217;t much I could do.</p>
<p>After about an hour, the operation was still stuck. Google&#8217;s documentation suggested that failovers should normally complete in a matter of minutes, so I was beginning to suspect something had gone rather badly wrong.</p>
<p>It had.</p>
<p>The database finally came back online after 99 minutes.</p>
<p>I then spent much of the day trying to establish what had happened. Google eventually explained that the host had experienced a storage I/O stall, which triggered the failover. But the storage couldn&#8217;t immediately be detached from the original host because of a safety mechanism designed to prevent data corruption. The failover operation eventually timed out.</p>
<p>So much for high availability.</p>
<p>While digging through the logs, I also noticed that one of our database queries was doing rather more work than it needed to. It was scanning hundreds of thousands of rows when it should only have needed a few hundred. I added a composite index, which made a considerable difference, and took the opportunity to review the database monitoring and add some better alerts.</p>
<p>I also increased the storage allocation, partly because I&#8217;d been investigating whether disk performance might have contributed to the problem.</p>
<p>A productive morning, then. Just not in the way I&#8217;d intended.</p>
<p>Later, I discovered that Google had suffered a power outage affecting infrastructure in our region. There had been widespread disruption to cloud services across the UK, with news reports about major websites and applications going offline.</p>
<p>I&#8217;d been so busy investigating my own database that I hadn&#8217;t noticed.</p>
<p>At least that explained why Google had decided to move things around in the first place. It also made me a little more confident that the failure wasn&#8217;t caused by anything we&#8217;d done.</p>
<p>Still, 99 minutes is a long time to be offline when you&#8217;re paying for high availability.</p>
<h2>Tuesday: PHP</h2>
<p>The following day, a critical vulnerability in PHP was reported.</p>
<p>I&#8217;ve been using PHP for years, and while much of my newer development uses other technologies, I still have several applications and services that depend on it. Some run in Docker containers using PHP 8.3. Others are rather older.</p>
<p>So I needed to find out whether we were affected.</p>
<p>The initial reports were alarming. A vulnerability potentially allowing remote code execution, urgent recommendations to patch, warnings about exposed servers and plenty of discussion about taking applications offline until fixes were available.</p>
<p>I started looking into the actual conditions required to exploit it.</p>
<p>There&#8217;s a big difference between a vulnerability existing in a particular version of PHP and an attacker being able to exploit it in a real application. In this case, the attack required specific conditions, and I wanted to understand which of our applications, if any, met them.</p>
<p>That took some digging.</p>
<p>I reviewed the configurations, checked how requests were being handled and applied some temporary restrictions where they made sense. For services that didn&#8217;t need multipart form submissions, for example, I could disable that functionality without affecting anything useful.</p>
<p>I also adjusted some Cloud Armor rules to reduce exposure while waiting for an updated runtime.</p>
<p>Then the patched PHP 8.3 image became available. I rebuilt the Docker images, deployed the updated services and removed the temporary restrictions that were no longer needed.</p>
<p>Job done.</p>
<p>Well, nearly.</p>
<p>There was still the matter of an old server running PHP 7.4.</p>
<p>Yes, I know.</p>
<p>That server had been around for years and was well overdue for replacement. We&#8217;d already moved some of the applications away from it, but there were still a few things running there that made migration awkward.</p>
<p>I&#8217;d been putting it off.</p>
<p>I applied some additional restrictions to the old server, including disabling file uploads and functionality that wasn&#8217;t required. That reduced the immediate exposure, but it was becoming increasingly difficult to justify keeping an unsupported PHP version running.</p>
<p>Two days later, we&#8217;d built a replacement server running PHP 8.3 and spent the day migrating everything across.</p>
<p>There were configuration changes, compatibility issues and all the usual little surprises you discover when moving software that&#8217;s been happily running in the same environment for years.</p>
<p>But we got there.</p>
<p>The old server is now retired, which is something I&#8217;d wanted to achieve for quite some time. It just took a security scare to move it to the top of the list.</p>
<p>Another day gone.</p>
<h2>And Then Railway</h2>
<p>In the middle of all this, a friend contacted me about an application he hosts on Railway.</p>
<p>He&#8217;d discovered that an API key had been exposed and was trying to work out how it had happened. We discussed what might have been compromised and what he needed to do about it.</p>
<p>At the time, there wasn&#8217;t much information available.</p>
<p>The following morning, Railway disclosed a security incident.</p>
<p>Interesting timing.</p>
<p>I don&#8217;t know whether the incident was directly responsible for his exposed credentials, but it certainly gave him something else to investigate. He had to replace the affected credentials and make sure nothing had been misused.</p>
<p>I wasn&#8217;t involved in running that application, but it was another example of a developer having to drop everything because of something that might have happened elsewhere in the infrastructure.</p>
<p>By this point, I&#8217;d had enough of infrastructure problems for one week.</p>
<h2>I Remember When Software Was Simpler</h2>
<p>I started developing Macro Scheduler in 1997.</p>
<p>Back then, I wrote Windows software. I&#8217;d write the code, compile it, build an installer and upload it to my website. Customers downloaded the software, installed it on their PCs and got on with using it.</p>
<p>There were problems, of course. Windows compatibility issues, antivirus false positives, installation problems and the occasional bug that somehow escaped testing.</p>
<p>But once the software was installed and working, it generally stayed that way.</p>
<p>I didn&#8217;t have to worry about whether a database in a Google data centre was available. There were no cloud services to monitor, no containers to rebuild every time a vulnerability was discovered in a dependency, and no third-party platform that could suddenly stop an application working.</p>
<p>If something broke, there was a reasonable chance I&#8217;d caused it myself.</p>
<p>Which at least meant I could fix it.</p>
<p>I&#8217;m not pretending everything was wonderful in 1997. The tools were more limited, distributing software was harder and there were plenty of things we can do today that would have been impractical or prohibitively expensive back then.</p>
<p>I rather like modern cloud development, actually.</p>
<p>I can build an application, deploy it to a managed platform, connect it to a database and make it available to customers around the world without buying a single server. If I need more capacity, I can usually increase it with a few clicks.</p>
<p>That&#8217;s pretty remarkable.</p>
<p>But it comes at a cost, and I don&#8217;t just mean the monthly bills.</p>
<p>Instead of maintaining our own hardware, we&#8217;re relying on somebody else to maintain it. Our applications depend on their networks, their storage, their security procedures and whatever internal systems they&#8217;ve built to keep everything running.</p>
<p>Most of the time, that&#8217;s fine.</p>
<p>Until it isn&#8217;t.</p>
<p>And when something goes wrong, you can find yourself trying to diagnose a problem in a system you can&#8217;t actually see, let alone fix.</p>
<h2>It&#8217;s Still Your Problem</h2>
<p>The thing about running software for customers is that it doesn&#8217;t really matter whose fault an outage is.</p>
<p>If an application I&#8217;ve developed stops working, the people using it aren&#8217;t particularly interested in whether Google has had a power failure or whether I&#8217;ve introduced a bug.</p>
<p>They just want it fixed.</p>
<p>Fair enough.</p>
<p>But when Google&#8217;s failover got stuck, I couldn&#8217;t do anything to make it complete. I could look at the logs, check the status, contact support and try to work out what was happening, but the actual problem was somewhere inside Google&#8217;s infrastructure.</p>
<p>I had no control over it.</p>
<p>That&#8217;s frustrating when you&#8217;re used to being able to investigate a problem, find the cause and fix it. With desktop software, I can usually reproduce a bug, step through the code and work out what&#8217;s wrong.</p>
<p>With a cloud infrastructure failure, sometimes all you can do is wait for somebody else.</p>
<p>And hope they know what they&#8217;re doing.</p>
<p>Of course, there are ways to make applications more resilient. We can add monitoring, keep backups, minimise dependencies, build in redundancy and make sure our software is kept up to date.</p>
<p>I do all those things.</p>
<p>But none of them guarantees that everything will keep working. Monday&#8217;s outage was a fairly good demonstration of that. The database had a standby instance in another zone, and the mechanism designed to switch between them still managed to leave us offline for 99 minutes.</p>
<p>I could have designed an entirely separate database infrastructure with additional redundancy, but then I&#8217;d have had more infrastructure to maintain, more things to monitor and another collection of things that could go wrong.</p>
<p>And presumably another bill from Google.</p>
<p>There&#8217;s a balance to be struck.</p>
<h2>Can I Get Back to Writing Software Now?</h2>
<p>Looking back, I did actually achieve quite a lot last week.</p>
<p>The database is running again, and one of its more demanding queries is now considerably more efficient. I&#8217;ve improved the monitoring, updated the PHP runtimes and finally replaced a server that should probably have been retired years ago.</p>
<p>None of that was wasted effort.</p>
<p>But very little of it was what I&#8217;d intended to spend the week doing.</p>
<p>I had features to develop, bugs to fix and other work planned. Instead, I spent most of my time investigating infrastructure failures, reading security advisories, updating Docker images and migrating an old server.</p>
<p>That&#8217;s part of the job, I suppose.</p>
<p>When I started writing software, most of my time was spent writing software. These days, an increasing amount seems to be spent making sure all the other bits and pieces that the software depends on are still working.</p>
<p>I wouldn&#8217;t want to give up the capabilities that modern cloud platforms provide. They&#8217;ve made it possible to build some fantastic things with relatively little infrastructure of our own.</p>
<p>But I do occasionally miss the days when I could compile an EXE, upload it to a website and consider the job done.</p>
<p>Although, thinking about it, someone would usually email to say their antivirus had deleted it.</p>
<p>So perhaps not much has changed after all.</p>
<p>Anyway, I&#8217;ve got some coding to catch up on.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>My son is still gaming on my dad&#8217;s PC</title>
		<link>https://www.mjtnet.com/blog/2026/09/18/my-son-is-still-gaming-on-my-dads-pc/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Fri, 18 Sep 2026 14:10:53 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3300</guid>

					<description><![CDATA[This morning my son, Jamie, asked me for help with his PC. He&#8217;d installed FC27, but it kept giving him a graphics driver warning and then refused to connect to the EA servers. The graphics driver turned out to be from 2024. Windows insisted it was completely up to date. It wasn&#8217;t. After a fair [&#8230;]]]></description>
										<content:encoded><![CDATA[<p dir="ltr">This morning my son, Jamie, asked me for help with his PC. He&#8217;d installed FC27, but it kept giving him a graphics driver warning and then refused to connect to the EA servers.</p>
<p dir="ltr">The graphics driver turned out to be from 2024. Windows insisted it was completely up to date.</p>
<p dir="ltr">It wasn&#8217;t.</p>
<p dir="ltr">After a fair amount of messing around, I discovered that his GeForce GTX 970 is now old enough that it no longer gets the normal NVIDIA Game Ready drivers. But NVIDIA does still provide security update drivers for it, and fortunately the latest one was exactly the minimum version FC27 wanted.</p>
<p dir="ltr">Driver updated. Warning gone.</p>
<p dir="ltr">Still wouldn&#8217;t connect to EA.</p>
<p dir="ltr">So followed an increasingly familiar sequence of IT troubleshooting: clear caches, repair the game, run things as administrator, check the firewall, try a completely different internet connection, swear at it a bit.</p>
<p dir="ltr">Nothing.</p>
<p dir="ltr">Eventually we gave up.</p>
<p dir="ltr">A couple of hours later Jamie came downstairs.</p>
<p dir="ltr">&#8220;It&#8217;s working.&#8221;</p>
<p dir="ltr">Of course it is.</p>
<p dir="ltr">&#8220;What did you do?&#8221;</p>
<p dir="ltr">&#8220;I uninstalled the EA app and installed it again.&#8221;</p>
<p dir="ltr">Naturally.</p>
<p dir="ltr">But somewhere during all this faffing around, it struck me just how old Jamie&#8217;s PC actually is.</p>
<p dir="ltr">Because it wasn&#8217;t originally his.</p>
<p dir="ltr">It was my dad&#8217;s.</p>
<p dir="ltr">Dad built it when it was a pretty powerful machine. He was really into Microsoft Flight Simulator and had a fantastic setup &#8211; three monitors, flight controls, pedals, the lot. He was also a keen photographer, so the PC got plenty of use processing and editing his photos.</p>
<p dir="ltr">The GTX 970 that I was trying to coax into running a brand-new football game this morning was once driving three screens of Flight Simulator for Dad.</p>
<p dir="ltr">Dad died three years ago.</p>
<p dir="ltr">The PC eventually came to us, and now his grandson uses it for gaming.</p>
<p dir="ltr">There&#8217;s something I really like about that.</p>
<p dir="ltr">Computers aren&#8217;t supposed to get more valuable as they get older. They become obsolete remarkably quickly. CPUs get slower relative to everything else, graphics cards stop being supported and eventually some new piece of software comes along that they simply can&#8217;t run.</p>
<p dir="ltr">And this one is definitely getting there.</p>
<p dir="ltr">A GTX 970 was a serious graphics card when Dad bought it. More than a decade later, it&#8217;s hanging on remarkably well &#8211; although FC27 requiring a driver specifically maintained for older NVIDIA cards feels like a fairly substantial hint that retirement isn&#8217;t too far away.</p>
<p dir="ltr">At some point we&#8217;ll replace the PC.</p>
<p dir="ltr">But not today.</p>
<p dir="ltr">Today it got a new graphics driver. Jamie got FC27 working. And the computer my dad built for Flight Simulator and photography gets to spend a bit longer being used by his grandson.</p>
<p dir="ltr">I think Dad would have rather liked that.</p>
<p dir="ltr">Dad died from mesothelioma three years ago. Next April I&#8217;m running the London Marathon in his memory, raising money for <a href="https://www.mariecurie.org.uk/">Marie Curie</a>, who were there for him &#8211; and for us &#8211; towards the end.</p>
<p dir="ltr">So perhaps there was something particularly nice about being reminded of him this morning in such an ordinary, unexpected way.</p>
<p dir="ltr">If you&#8217;d like to support my London Marathon fundraising for Marie Curie, you can find my page at:</p>
<p dir="ltr"><a href="https://runfordad.co.uk">https://runfordad.co.uk</a></p>
<p dir="ltr">For Dad.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>AI Can Write the Script. But What Runs It?</title>
		<link>https://www.mjtnet.com/blog/2026/09/15/ai-can-write-the-script-but-what-runs-it/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Tue, 15 Sep 2026 13:26:01 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[Automation]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3298</guid>

					<description><![CDATA[AI Can Write the Script. But What Runs It? A few weeks ago I wrote about how AI is changing Windows automation. One of the most obvious changes is that it&#8217;s becoming remarkably easy to generate code. Need a PowerShell script to process a folder full of files? Ask an AI. Need some Python to [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>AI Can Write the Script. But What Runs It?</p>
<p>A few weeks ago I wrote about how AI is changing Windows automation.</p>
<p>One of the most obvious changes is that it&#8217;s becoming remarkably easy to generate code.</p>
<p>Need a PowerShell script to process a folder full of files? Ask an AI.</p>
<p>Need some Python to call an API and turn the response into a CSV? It can probably get you most of the way there in seconds.</p>
<p>Need a bit of VBScript, JavaScript or even Macro Scheduler code? Same thing.</p>
<p>For developers – and increasingly for people who aren&#8217;t developers – AI has dramatically lowered the barrier to creating small pieces of automation.</p>
<p>But there&#8217;s an important distinction which I think sometimes gets overlooked:</p>
<p>Writing the script isn&#8217;t the same as running the automation.</p>
<p><strong>THE SCRIPT IS ONLY PART OF THE JOB</strong></p>
<p>Imagine you&#8217;ve asked an AI to create a PowerShell script which downloads a report, processes it and saves the result somewhere.</p>
<p>Great. You now have a script.</p>
<p>But perhaps the actual requirement is:</p>
<p>&#8211; Run it every weekday at 6am<br />
&#8211; Run it unattended<br />
&#8211; Pass it the correct parameters<br />
&#8211; Capture the output<br />
&#8211; Know whether it succeeded<br />
&#8211; Do something else afterwards<br />
&#8211; Retry or take another action if something fails<br />
&#8211; Keep a log of what happened</p>
<p>At that point the problem isn&#8217;t really &#8220;how do I write this script?&#8221; any more.</p>
<p>It&#8217;s &#8220;how do I turn this script into a reliable automation?&#8221;</p>
<p>And those are two different problems.</p>
<p><strong>AI IS MAKING THE BUILDING BLOCKS EASIER</strong></p>
<p>I&#8217;ve been writing automation software for nearly 30 years, and one thing that has remained fairly constant is that useful automations tend to be made up of lots of different pieces.</p>
<p>A Macro Scheduler script might launch an application, interact with its user interface, run a command-line utility, execute some PowerShell, query a database, move some files and send an email.</p>
<p>It doesn&#8217;t particularly matter where those individual pieces came from.</p>
<p>You might have written them yourself.</p>
<p>A colleague might have written them ten years ago.</p>
<p>You might have copied and adapted something from Stack Overflow.</p>
<p>Or, increasingly, you might have asked an AI to create them five minutes ago.</p>
<p>The interesting thing about AI is that it makes many of those building blocks much easier to create.</p>
<p>That doesn&#8217;t necessarily remove the need for automation tools.</p>
<p>Arguably, it gives us more things to automate.</p>
<p><strong>ORCHESTRATION STILL MATTERS</strong></p>
<p>This is where I think traditional automation tools still have an important role.</p>
<p>Something needs to join all those pieces together.</p>
<p>Something needs to decide when they run, in what order, with what parameters and what happens when something goes wrong.</p>
<p>And sometimes the thing you&#8217;re trying to automate doesn&#8217;t have an API or a convenient command-line interface at all.</p>
<p>It&#8217;s still a Windows application with buttons, menus, dialogs and fields that somebody would otherwise have to operate manually.</p>
<p>AI can help you write code.</p>
<p>But code generation doesn&#8217;t magically make every application programmable, nor does it automatically give you reliable unattended execution.</p>
<p><strong>USE AI AND AUTOMATION TOGETHER</strong></p>
<p>I don&#8217;t see this as AI versus traditional automation.</p>
<p>The more interesting combination is AI plus automation.</p>
<p>Use AI to help create scripts, regular expressions, SQL, PowerShell, Python or whatever other building blocks you need.</p>
<p>Then use the appropriate automation tools to put those pieces together and run them reliably.</p>
<p>That might be Macro Scheduler. It might be Windows Task Scheduler. It might be a CI system, a cloud service or something else entirely.</p>
<p>Use the simplest tool that solves the problem.</p>
<p>But don&#8217;t confuse generating a piece of code with solving the whole automation problem.</p>
<p>AI can write the script.</p>
<p>Something still has to run it.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>AI Is Changing Windows Automation &#8211; But Not in the Way You Might Think</title>
		<link>https://www.mjtnet.com/blog/2026/08/04/ai-is-changing-windows-automation-but-not-in-the-way-you-might-think/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Tue, 04 Aug 2026 13:21:15 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Scripting]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3292</guid>

					<description><![CDATA[If you&#8217;ve worked in IT over the past year, you&#8217;ve probably asked ChatGPT, Claude or Cursor to write some code for you. I certainly have. AI has become an incredibly useful programming assistant. Need a Python script to rename files? Ask AI. Need to scrape a website? AI can usually get you most of the [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>If you&#8217;ve worked in IT over the past year, you&#8217;ve probably asked ChatGPT, Claude or Cursor to write some code for you. I certainly have.</p>
<p>AI has become an incredibly useful programming assistant. Need a Python script to rename files? Ask AI. Need to scrape a website? AI can usually get you most of the way there in seconds. Even experienced developers are finding themselves writing less code from scratch and spending more time reviewing, refining and testing code generated by AI.</p>
<p>So does that mean traditional automation tools like Macro Scheduler are becoming obsolete?</p>
<p>I don&#8217;t think so.</p>
<p>What AI has changed is <strong>how we create automation</strong>, not necessarily <strong>how automation gets done</strong>.</p>
<h2>The hard part isn&#8217;t writing the code</h2>
<p class="PDq2pG_selectionAnchorContainer" data-start="461" data-end="557">When people think about automation, they often assume writing the code is the biggest challenge.</p>
<p data-start="562" data-end="589">In reality, it often isn&#8217;t.</p>
<p data-start="594" data-end="667">The hard part is understanding the application you&#8217;re trying to automate.</p>
<p>If you&#8217;re automating a modern web application with well-structured HTML and APIs, AI has an enormous advantage. It can reason about the page, generate Playwright or Selenium code, and often produce something that works remarkably well.</p>
<p>But many businesses don&#8217;t live entirely in the browser.</p>
<p>They still rely on Windows desktop software that may have been written ten, fifteen or even twenty years ago. Internal tools. Accounting systems. Manufacturing software. Medical applications. Legacy databases. Remote desktop sessions. Software where there is no API, no documentation, and no obvious way to automate anything.</p>
<p>That&#8217;s where the real challenge begins.</p>
<h2>Desktop automation is often an investigation</h2>
<p>Anyone who has automated Windows applications knows that the process is rarely as simple as writing a few lines of code.</p>
<p>Can the button be identified directly?</p>
<p>If not, can it be found using OCR?</p>
<p>Would image recognition be more reliable?</p>
<p>Has Windows scaling changed?</p>
<p>What happens if the dialog appears a second later than expected?</p>
<p>What if the application has been updated and the button has moved?</p>
<p>These aren&#8217;t really coding problems.</p>
<p>They&#8217;re automation problems.</p>
<p>And solving them is usually an iterative process. You try an approach, test it, refine it and gradually build a reliable solution.</p>
<h2>AI is becoming a brilliant assistant</h2>
<p>Ironically, AI makes this process easier rather than replacing it.</p>
<p>Today I regularly use AI to:</p>
<ul>
<li>Explain existing Macro Scheduler scripts.</li>
<li>Suggest cleaner or more reliable approaches.</li>
<li>Help debug automation that isn&#8217;t behaving as expected.</li>
<li>Generate code snippets that I can adapt and test.</li>
</ul>
<p>It&#8217;s like having another experienced developer sitting beside you.</p>
<p>The important word there is <strong>assist</strong>.</p>
<p>AI still needs context. It often needs screenshots, recorded steps, snippets of code or descriptions of what you&#8217;re trying to achieve. Building reliable desktop automation remains a collaborative process.</p>
<h2>Where we&#8217;re experimenting</h2>
<p>This is exactly why we&#8217;ve been experimenting with AI ourselves.</p>
<p>Our experimental tool, <a href="https://agent.mjtnet.com">Macro Scheduler Agent</a>, can already help explain Macro Scheduler code, identify bugs, answer scripting questions and even generate scripts from screenshots.</p>
<p>It&#8217;s still early days, and we&#8217;re deliberately taking a cautious approach. AI is incredibly capable, but we also know that reliable desktop automation depends on understanding the environment it&#8217;s working in.</p>
<p>Rather than trying to replace Macro Scheduler, we see AI as something that makes Macro Scheduler easier to use.</p>
<h2>Nearly 30 years later&#8230;</h2>
<p>Macro Scheduler was first released back in 1997.</p>
<p>The technology landscape has changed dramatically since then.</p>
<p>Windows has changed.</p>
<p>The web has changed.</p>
<p>Programming languages have come and gone.</p>
<p>And now AI is changing software development again.</p>
<p>But one thing hasn&#8217;t changed.</p>
<p>People still have repetitive tasks.</p>
<p>Businesses still rely on software that wasn&#8217;t designed to be automated.</p>
<p>And there&#8217;s still enormous value in having a reliable tool that can automate almost anything you can do with a keyboard and mouse.</p>
<p>AI is changing the future of automation.</p>
<p>We&#8217;re excited to be part of that future &#8211; not by competing with AI, but by embracing it where it genuinely helps.</p>
<p>Because the goal has never been to write more code.</p>
<p>The goal has always been to help people get work done faster.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Macro Scheduler 15.5.07: SMTPSendMail Now Supports OAuth2</title>
		<link>https://www.mjtnet.com/blog/2026/03/16/macro-scheduler-15-5-07-smtpsendmail-now-supports-oauth2/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Mon, 16 Mar 2026 13:58:57 +0000</pubDate>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3281</guid>

					<description><![CDATA[Macro Scheduler 15.5.07 introduces an important update to the&#160;SMTPSendMail&#160;command, adding support for&#160;OAuth2 authentication&#160;and improving timeout handling for more reliable email automation. These changes help ensure Macro Scheduler scripts continue working with modern email services as providers increasingly move away from basic username/password authentication. Why OAuth2 Support Matters Many email providers — including&#160;Microsoft 365, Outlook.com and [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Macro Scheduler 15.5.07 introduces an important update to the&nbsp;<strong>SMTPSendMail</strong>&nbsp;command, adding support for&nbsp;<strong>OAuth2 authentication</strong>&nbsp;and improving timeout handling for more reliable email automation.</p>



<p>These changes help ensure <a href="https://www.mjtnet.com/macro-scheduler.htm">Macro Scheduler</a> scripts continue working with modern email services as providers increasingly move away from basic username/password authentication.</p>



<h2>Why OAuth2 Support Matters</h2>



<p>Many email providers — including&nbsp;<strong>Microsoft 365, Outlook.com and Gmail</strong>&nbsp;— are gradually disabling&nbsp;<strong>SMTP Basic Authentication</strong>. Instead they require&nbsp;<strong>OAuth2-based authentication</strong>.</p>



<p>Without OAuth2 support, automated scripts that send email via SMTP may stop working when basic auth is disabled.</p>



<p>With version&nbsp;<strong>15.5.07</strong>, Macro Scheduler’s SMTPSendMail command now supports OAuth2 tokens, allowing scripts to authenticate securely with modern email providers.</p>



<h2>Using OAuth2 with SMTPSendMail</h2>



<p>To enable OAuth2 authentication simply set:</p>



<ul>
<li><code>SMTP_OAUTH2 = 1</code></li>



<li><code>SMTP_OAUTH2_TOKEN = &lt;access token&gt;</code></li>
</ul>



<p>Example:</p>



<pre class="wp-block-preformatted">Let&gt;SMTP_OAUTH2=1<br>Let&gt;SMTP_OAUTH2_TOKEN=ya29.a0AfH6SMBx...<br>Let&gt;SMTP_USERID=yourname@gmail.com<br>Let&gt;SMTP_SSL=1<br>Let&gt;SMTP_PORT=465SMTPSendMail&gt;recipient@example.com,smtp.gmail.com,yourname@gmail.com,Your Name,Test subject,Test body,</pre>



<p>Macro Scheduler expects a&nbsp;<strong>valid OAuth2 access token</strong>&nbsp;in&nbsp;<code>SMTP_OAUTH2_TOKEN</code>.</p>



<p>Token retrieval itself is&nbsp;<strong>not handled automatically</strong>&nbsp;by SMTPSendMail. Your script (or another process) must obtain the access token from the provider first. This typically involves:</p>



<ol>
<li>Creating an application with your email provider (e.g. Azure AD or Google Cloud).</li>



<li>Obtaining a&nbsp;<strong>client ID</strong>&nbsp;and&nbsp;<strong>client secret</strong>.</li>



<li>Using these credentials to obtain a&nbsp;<strong>refresh token</strong>.</li>



<li>Exchanging the refresh token for an&nbsp;<strong>access token</strong>.</li>



<li>Passing the access token to SMTPSendMail via&nbsp;<code>SMTP_OAUTH2_TOKEN</code>.</li>
</ol>



<p>You can use Macro Scheduler’s&nbsp;<strong>HTTPRequest</strong>&nbsp;command to perform these token exchanges if needed.</p>



<h2>Improved SMTP Timeout Handling</h2>



<p>Version 15.5.07 also improves the behaviour of the&nbsp;<code>SMTP_TIMEOUT</code>&nbsp;variable.</p>



<p>Previously this timeout applied&nbsp;<strong>only to the initial connection</strong>&nbsp;to the SMTP server. In some environments this could still leave scripts waiting indefinitely if a later SMTP operation stalled.</p>



<p>Now the timeout applies to&nbsp;<strong>all SMTP operations</strong>, including:</p>



<ul>
<li>Authentication</li>



<li>Message transfer</li>



<li>Server responses</li>
</ul>



<p>This results in more predictable behaviour when network issues or server delays occur.</p>



<h2>Existing Scripts Continue to Work</h2>



<p>If your SMTP server still supports&nbsp;<strong>username/password authentication</strong>, existing scripts will continue to work exactly as before using:</p>



<pre class="wp-block-preformatted">Let&gt;SMTP_AUTH=1<br>Let&gt;SMTP_USERID=myuser<br>Let&gt;SMTP_PASSWORD=mypassword</pre>



<p>OAuth2 is simply an&nbsp;<strong>additional authentication option</strong>&nbsp;for providers that require it.</p>



<h2>Full Documentation</h2>



<p>You can find the full SMTPSendMail documentation here:</p>



<p><a href="https://www.mjtnet.com/manuals/b/v15/topics/smtpsendmail.htm">https://www.mjtnet.com/manuals/b/v15/topics/smtpsendmail.htm</a></p>



<h2>Download Macro Scheduler 15.5.07</h2>



<p>If you rely on SMTP automation in your scripts, we recommend upgrading to <strong>Macro Scheduler 15.5.07</strong> to ensure compatibility with modern email systems.<br><br><a href="https://www.mjtnet.com/macro-scheduler.htm">Trial Downloads</a> | <a href="https://www.mjtnet.com/ua.htm">Registered Updates</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Level Up Your Automation: XPath and JSONPath Explained (With Macro Scheduler Examples)</title>
		<link>https://www.mjtnet.com/blog/2026/02/01/level-up-your-automation-xpath-jsonpath-explained-with-macro-scheduler-examples/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Sun, 01 Feb 2026 16:38:10 +0000</pubDate>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3268</guid>

					<description><![CDATA[If you automate websites, APIs, or online services with Macro Scheduler, you’ll quickly run into two recurring challenges: Two technologies solve these problems: We’ve published two practical primer articles that go deep into both topics: &#x1f449;&#160;An XPath Primer for Web Automation (with Macro Scheduler examples)https://help.mjtnet.com/article/554-an-xpath-primer-for-web-automation-with-macro-scheduler-examples &#x1f449;&#160;A JSONPath Primer (with Macro Scheduler examples)https://help.mjtnet.com/article/555-a-jsonpath-primer-with-macro-scheduler-examples Below is a [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>If you automate websites, APIs, or online services with Macro Scheduler, you’ll quickly run into two recurring challenges:</p>



<ul>
<li>Finding the&nbsp;<strong>right element</strong>&nbsp;on a web page</li>



<li>Extracting the&nbsp;<strong>right value</strong>&nbsp;from structured JSON data</li>
</ul>



<p>Two technologies solve these problems:</p>



<ul>
<li><strong>XPath</strong>&nbsp;— for navigating and selecting HTML elements</li>



<li><strong>JSONPath</strong>&nbsp;— for querying and extracting values from JSON</li>
</ul>



<p>We’ve published two practical primer articles that go deep into both topics:</p>



<p><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f449.png" alt="👉" class="wp-smiley" style="height: 1em; max-height: 1em;" />&nbsp;<strong>An XPath Primer for Web Automation (with Macro Scheduler examples)</strong><br><a href="https://help.mjtnet.com/article/554-an-xpath-primer-for-web-automation-with-macro-scheduler-examples?utm_source=chatgpt.com">https://help.mjtnet.com/article/554-an-xpath-primer-for-web-automation-with-macro-scheduler-examples</a></p>



<p><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f449.png" alt="👉" class="wp-smiley" style="height: 1em; max-height: 1em;" />&nbsp;<strong>A JSONPath Primer (with Macro Scheduler examples)</strong><br><a href="https://help.mjtnet.com/article/555-a-jsonpath-primer-with-macro-scheduler-examples?utm_source=chatgpt.com">https://help.mjtnet.com/article/555-a-jsonpath-primer-with-macro-scheduler-examples</a></p>



<p>Below is a high-level overview of each, with real Macro Scheduler examples to show why these skills are so valuable.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> XPath — Find Web Elements Reliably</h2>



<p><a href="https://help.mjtnet.com/article/554-an-xpath-primer-for-web-automation-with-macro-scheduler-examples">https://help.mjtnet.com/article/554-an-xpath-primer-for-web-automation-with-macro-scheduler-examples</a></p>



<p>When automating Chrome using Macro Scheduler’s Chrome functions, element IDs and class names are often unreliable:</p>



<ul>
<li>IDs may be missing or dynamically generated</li>



<li>Class names may change between builds</li>



<li>Multiple elements may share the same attributes</li>
</ul>



<p>XPath lets you locate elements by describing their&nbsp;<strong>position and relationship</strong>&nbsp;within the page structure.</p>



<p>In Macro Scheduler, XPath is used with:</p>



<pre class="wp-block-code"><code>ChromeFindElements&gt;session_id,xpath,value,elements_array</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3>Example: Find an Input by Attribute</h3>



<pre class="wp-block-code"><code>ChromeFindElements&gt;session_id,xpath,//input&#91;@name='q'],elements
ChromeSetElementValue&gt;session_id,elements_1,macro scheduler</code></pre>



<p></p>



<p>This finds an&nbsp;<code>&lt;input&gt;</code>&nbsp;element whose&nbsp;<code>name</code>&nbsp;attribute equals&nbsp;<code>q</code>.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3>Using Partial Matches</h3>



<p>When values are dynamic:</p>



<pre class="wp-block-code"><code>ChromeFindElements&gt;session_id,xpath,//button&#91;contains(@id,'save')],elements</code></pre>



<p></p>



<p>This matches any button whose ID contains the word “save”.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3>Real-World Scenario: Clicking a Button Based on a Child Element</h3>



<p>HTML:</p>



<pre class="wp-block-code"><code>&lt;button&gt;
  &lt;label for="checkbox-123"&gt;Pacific Islander&lt;/label&gt;
  &lt;input id="checkbox-123"&gt;
&lt;/button&gt;</code></pre>



<p></p>



<p>You know the ID of the&nbsp;<code>input</code>, but need to click the surrounding&nbsp;<code>button</code>.</p>



<p>XPath:</p>



<pre class="wp-block-code"><code>ChromeFindElements&gt;session_id,xpath,//input&#91;@id='checkbox-123']/ancestor::button,btn
ChromeClickElement&gt;session_id,btn_1</code></pre>



<p>This moves up the DOM from the input to its parent button.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3>Real-World Scenario: Find a Button Based on Nearby Text</h3>



<p>HTML:</p>



<pre class="wp-block-code"><code>&lt;div class="option"&gt;
  &lt;h3&gt;Premium Plan&lt;/h3&gt;
  &lt;button&gt;Select&lt;/button&gt;
&lt;/div&gt;</code></pre>



<p></p>



<p>XPath:</p>



<pre class="wp-block-code"><code>ChromeFindElements&gt;session_id,xpath,//h3&#91;text()='Premium Plan']/following-sibling::button,btn
ChromeClickElement&gt;session_id,btn_1</code></pre>



<p></p>



<p>This selects the button associated with the “Premium Plan” heading.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3>XPath Best Practices</h3>



<ul>
<li>Prefer relative paths starting with&nbsp;<code>//</code></li>



<li>Use&nbsp;<code>contains()</code>&nbsp;for dynamic values</li>



<li>Avoid full&nbsp;<code>/html/body/...</code>&nbsp;absolute paths</li>



<li>Check&nbsp;<code>elements_array_count</code>&nbsp;before using results</li>
</ul>



<p>For a full walkthrough and many more patterns, see:<br><a href="https://help.mjtnet.com/article/554-an-xpath-primer-for-web-automation-with-macro-scheduler-examples?utm_source=chatgpt.com">https://help.mjtnet.com/article/554-an-xpath-primer-for-web-automation-with-macro-scheduler-examples</a></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> JSONPath — Extract Data from JSON</h2>



<p><a href="https://help.mjtnet.com/article/555-a-jsonpath-primer-with-macro-scheduler-examples">https://help.mjtnet.com/article/555-a-jsonpath-primer-with-macro-scheduler-examples</a></p>



<p>JSON is everywhere: APIs, cloud services, configuration files, and web responses.</p>



<p>Macro Scheduler’s&nbsp;<code>JSONParse</code>&nbsp;command uses JSONPath to pull specific values from JSON text.</p>



<pre class="wp-block-code"><code>JSONParse&gt;json_string,json_path,result_array</code></pre>



<p></p>



<p>Results are always returned as an array:</p>



<ul>
<li><code>result_array_1</code></li>



<li><code>result_array_2</code></li>



<li><code>result_array_count</code></li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3>Example: Extract a Simple Value</h3>



<p>JSON:</p>



<pre class="wp-block-code"><code>{ "uid": "1234" }</code></pre>



<p></p>



<p>Macro Scheduler:</p>



<pre class="wp-block-code"><code>JSONParse&gt;sJSON,$.uid,result
MessageModal&gt;UID is: %result_1%</code></pre>



<p></p>



<p>Note the required&nbsp;<code>$</code>&nbsp;at the start of the path.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3>Working with Arrays</h3>



<pre class="wp-block-code"><code>JSONParse&gt;sJSON,$.clients&#91;0],result</code></pre>



<p></p>



<p>Gets the first client.</p>



<pre class="wp-block-code"><code>JSONParse&gt;sJSON,$.clients&#91;*],result</code></pre>



<p></p>



<p>Gets all clients.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3>Using Filters</h3>



<p>Select only books cheaper than 10:</p>



<pre class="wp-block-code"><code>JSONParse&gt;json,$.store.book&#91;?@.price &lt; 10],cheapBooks</code></pre>



<p></p>



<p>Select books that contain an ISBN:</p>



<pre class="wp-block-code"><code>JSONParse&gt;json,$.store.book&#91;?@.isbn],withIsbn</code></pre>



<p></p>



<p>Get titles of books under 15:</p>



<pre class="wp-block-code"><code>JSONParse&gt;json,$.store.book&#91;?@.price &lt; 15].title,titles</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3>JSONPath Best Practices</h3>



<ul>
<li>Always start paths with&nbsp;<code>$</code></li>



<li>Remember results are arrays</li>



<li>Check&nbsp;<code>result_count</code>&nbsp;before using values</li>



<li>Build paths step by step</li>
</ul>



<p>For full explanations and more examples:<br><a href="https://help.mjtnet.com/article/555-a-jsonpath-primer-with-macro-scheduler-examples?utm_source=chatgpt.com">https://help.mjtnet.com/article/555-a-jsonpath-primer-with-macro-scheduler-examples</a></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2>Final Thoughts</h2>



<p>XPath and JSONPath solve two of the most common automation problems:</p>



<ul>
<li><strong>XPath</strong>&nbsp;→ finding the right element on a web page</li>



<li><strong>JSONPath</strong>&nbsp;→ extracting the right value from structured data</li>
</ul>



<p>Mastering these will make your Macro Scheduler scripts&nbsp;<strong>more reliable, more flexible, and easier to maintain</strong>.</p>



<p>If you regularly automate websites or APIs, these two primers are essential reading.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Macro Scheduler 15.5 Released</title>
		<link>https://www.mjtnet.com/blog/2026/01/31/macro-scheduler-15-5-released/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Sat, 31 Jan 2026 17:25:24 +0000</pubDate>
				<category><![CDATA[Announcements]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3262</guid>

					<description><![CDATA[Macro Scheduler 15.5 update is now available. Macro Recorder Web Automation New Commands &#38; Functions Improvements Fixes Registered Downloads/Upgrades &#124; Trial Downloads]]></description>
										<content:encoded><![CDATA[
<p>Macro Scheduler 15.5 update is now available.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3>Macro Recorder</h3>



<ul>
<li>Added ability to select an open window to activate</li>



<li>Added option to constrain mouse events to selected initial window when recording</li>



<li>Added SetFocus lines to macro recorder output when window activated</li>



<li>Updated layout of macro recorder</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3>Web Automation</h3>



<ul>
<li>Added ChromeWaitForText command</li>



<li>Added EdgeWaitForText command</li>



<li>Added &#8216;text&#8217; and &#8216;partial text&#8217; strategies to ChromeFindElements</li>



<li>Added &#8216;text&#8217; and &#8216;partial text&#8217; strategies to EdgeFindElements</li>



<li>Updated WebRecorder toolbar button to visit the Chrome WebRecorder Extension:<br><a href="https://www.mjtnet.com/webrecorder.htm">https://www.mjtnet.com/webrecorder.htm</a></li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3>New Commands &amp; Functions</h3>



<ul>
<li>Added PowerShell command to run PowerShell scripts and commands</li>



<li>Added GetWindowTitle command</li>



<li>Added GetISOTimeStamp command</li>



<li>Added StrContains function</li>



<li>Added StrStartsWith function</li>



<li>Added StrEndsWith function</li>



<li>Added GFL_RECURSIVE directive</li>



<li>Added MSG_TIMEOUT option</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3>Improvements</h3>



<ul>
<li>Updated JSONParse to handle &#8216;?&#8217; filters and &#8216;@&#8217; (Current) operator</li>



<li>Updated data path / OneDrive handling</li>



<li>Updated HTTPRequest, SMTP, POP3, and FTP functions to default to TLS 1.2 and removed deprecated SSLv2/SSLv3 support</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3>Fixes</h3>



<ul>
<li>Fixed ReadFile command to cope better with Unicode characters</li>



<li>Fixed minor issues in command definition file</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><a href="https://www.mjtnet.com/ua.htm">Registered Downloads/Upgrades</a> | <a href="https://www.mjtnet.com/macro-scheduler.htm">Trial Downloads</a><br></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>How to call REST APIs from Macro Scheduler (with JSON, headers, error handling)</title>
		<link>https://www.mjtnet.com/blog/2025/10/06/how-to-call-rest-apis-from-macro-scheduler-with-json-headers-error-handling/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Mon, 06 Oct 2025 13:03:07 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3257</guid>

					<description><![CDATA[TL;DR:&#160;Use&#160;HTTPRequest&#160;for GET/POST/PUT/PATCH/DELETE, set&#160;HTTP_POSTJSON=1&#160;for JSON bodies, add&#160;HTTP_CUSTOM_HEADERS&#160;for auth,&#160;HTTP_TIMEOUT&#160;for reliability, and parse responses with&#160;JSONParse. Why call APIs from Macro Scheduler? Everything below runs in plain Macro Scheduler—no external dependencies. Quick start: GET a JSON endpoint POST JSON (with Bearer token) Custom headers, SSL/TLS &#38; timeouts (reliability) Example: create a short link with a custom Open Graph preview [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p><strong>TL;DR:</strong>&nbsp;Use&nbsp;<code>HTTPRequest</code>&nbsp;for GET/POST/PUT/PATCH/DELETE, set&nbsp;<code>HTTP_POSTJSON=1</code>&nbsp;for JSON bodies, add&nbsp;<code>HTTP_CUSTOM_HEADERS</code>&nbsp;for auth,&nbsp;<code>HTTP_TIMEOUT</code>&nbsp;for reliability, and parse responses with&nbsp;<code>JSONParse</code>.</p>



<h2>Why call APIs from Macro Scheduler?</h2>



<ul>
<li>Pull or push data (orders, tickets, metrics) as part of a daily job</li>



<li>Trigger SaaS workflows without opening a browser</li>



<li>Glue apps together (cron-style) with simple, reliable scripts</li>
</ul>



<p>Everything below runs in plain Macro Scheduler—no external dependencies.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2>Quick start: GET a JSON endpoint</h2>



<pre class="wp-block-code"><code>// 1) Optional: set a timeout (seconds)
Let&gt;HTTP_TIMEOUT=15

// 2) Optional: custom headers (multiple lines use %CRLF%)
Let&gt;HTTP_CUSTOM_HEADERS=Accept: application/json

// 3) Make the request
HTTPRequest&gt;https://api.example.com/status,,GET,,RESP

// 4) Parse JSON (example path)
JSONParse&gt;RESP,$.service,result
If&gt;result_count&gt;0
  MessageModal&gt;Service: %result_1%
Else
  // Log full response if JSON path not found
  WriteLn&gt;%SCRIPT_DIR%\api_log.txt,WF_APPEND,Unexpected response: %RESP%
EndIf

HTTPRequest signature:
HTTPRequest&gt;URL,&#91;LocalFilename],Method,&#91;POST_Data],Result_Variable mjtnet.com</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2>POST JSON (with Bearer token)</h2>



<pre class="wp-block-code"><code>Let&gt;HTTP_TIMEOUT=20
Let&gt;HTTP_POSTJSON=1
Let&gt;HTTP_CUSTOM_HEADERS=Authorization: Bearer YOUR_API_KEY%CRLF%Accept: application/json

// JSON body (can be built up dynamically)
Let&gt;payload={"name":"Widget 42","price":19.99}

// POST it
HTTPRequest&gt;https://api.example.com/items,,POST,payload,RESP

// Extract a field from the JSON response
JSONParse&gt;RESP,$.id,itemId
If&gt;itemId_count=1
  MessageModal&gt;Created item id: %itemId_1%
Else
  WriteLn&gt;%SCRIPT_DIR%\api_log.txt,WF_APPEND,Create failed: %RESP%
EndIf</code></pre>



<ul>
<li>For JSON bodies, set&nbsp;<code>HTTP_POSTJSON=1</code>&nbsp;(Macro Scheduler sets the content type for you).&nbsp;<a href="https://www.mjtnet.com/manuals/b/v15/topics/httprequest.htm" target="_blank" rel="noreferrer noopener">mjtnet.com</a></li>



<li><code>JSONParse</code>&nbsp;returns an array (<code>result_1</code>,&nbsp;<code>result_2</code>, …) with a&nbsp;<code>*_count</code>—use JSONPath like&nbsp;<code>$.id</code>.&nbsp;<a href="https://www.mjtnet.com/manuals/b/v15/topics/jsonparse.htm" target="_blank" rel="noreferrer noopener">mjtnet.com</a></li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2>Custom headers, SSL/TLS &amp; timeouts (reliability)</h2>



<pre class="wp-block-code"><code>Let&gt;HTTP_TIMEOUT=30
Let&gt;HTTP_CUSTOM_HEADERS=Authorization: Bearer YOUR_API_KEY%CRLF%X-Trace: msched</code></pre>



<ul>
<li><strong>Timeouts:</strong>&nbsp;set&nbsp;<code>HTTP_TIMEOUT</code>&nbsp;(seconds) so a hung API doesn’t block your run.&nbsp;<a href="https://www.mjtnet.com/manuals/b/v15/topics/systemvariables.htm" target="_blank" rel="noreferrer noopener">mjtnet.com</a></li>



<li><strong>Headers:</strong>&nbsp;set multiple lines via&nbsp;<code>HTTP_CUSTOM_HEADERS</code>—great for auth, idempotency keys, etc.&nbsp;<a href="https://www.mjtnet.com/manuals/b/v15/topics/httprequest.htm" target="_blank" rel="noreferrer noopener">mjtnet.com</a></li>



<li><strong>HTTPS/TLS:</strong>&nbsp;Use an&nbsp;<code>https://</code>&nbsp;URL (or set&nbsp;<code>HTTP_SSL=1</code>). If you must pin a TLS version, set&nbsp;<code>TLS_VER</code>&nbsp;(<code>12</code>&nbsp;for TLS 1.2).&nbsp;</li>
</ul>



<h2>Example: create a short link with a custom Open Graph preview (ogli)</h2>



<p>Swap in your endpoint/headers if you’re using another service—the pattern is the same.</p>



<p>This example uses the <a href="https://app.ogli.sh">Ogli link shorter service</a>. Grab a free API key from <a href="https://app.ogli.sh">Ogli</a> to try out the code below.</p>



<pre class="wp-block-code"><code>// Go get a free API key from app.ogli.sh
Let&gt;OGLI_API_KEY=YOUR_API_KEY_HERE

// Timeouts &amp; JSON
Let&gt;HTTP_TIMEOUT=20
Let&gt;HTTP_POSTJSON=1

// Auth (Bearer) + accept JSON
Let&gt;HTTP_CUSTOM_HEADERS=Authorization: Bearer %OGLI_API_KEY%%CRLF%Accept: application/json

// Build the request body
/*
PAYLOAD:
{
"targetUrl":"https://example.com/product/1232",
"title":"SuperWidget — Launch Day"
}
*/
LabelToVar&gt;PAYLOAD,postBody

// POST
HTTPRequest&gt;https://api.ogli.sh/link,,POST,postBody,RESP

// Parse shortUrl from response
JSONParse&gt;RESP,$.url,short_link
If&gt;short_link_count&gt;0
  Let&gt;the_link=short_link_1
  MessageModal&gt;short link is %the_link%
Endif</code></pre>



<p>Later, PATCH the same link to swap the OG image and platforms will refresh the preview when reshared.</p>



<h2>Error handling &amp; logging pattern</h2>



<pre class="wp-block-code"><code>Let&gt;LOG=%SCRIPT_DIR%\api_log.txt

// After any HTTPRequest:
If&gt;RESP=
  // If you saved to a LocalFileName, RESP will be blank on success.
  // Otherwise blank usually means an error occurred – log it:
  WriteLn&gt;%LOG%,WF_APPEND,Blank response (check URL/timeout/SSL)
Else
  // Try to parse a known field; if none, log full response
  JSONParse&gt;RESP,$.status,status
  If&gt;status_count=0
    WriteLn&gt;%LOG%,WF_APPEND,Unexpected JSON: %RESP%
  EndIf
EndIf

</code></pre>



<p>Tip: when you&nbsp;<strong>save to a file</strong>&nbsp;(use the&nbsp;<code>LocalFilename</code>&nbsp;parameter), a successful call leaves the result variable blank by design; otherwise it contains the response or an error message.&nbsp;<a href="https://www.mjtnet.com/manuals/b/v15/topics/httprequest.htm" target="_blank" rel="noreferrer noopener">mjtnet.com</a></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2>Parse more JSON with JSONPath</h2>



<pre class="wp-block-code"><code>/*
RESP:
{
  "id":"lnk_abc123",
  "shortUrl":"https://ogli.sh/launch-123",
  "stats":{"clicks":42,"countries":&#91;"GB","US"]}
}
*/
JSONParse&gt;RESP,$.stats.clicks,c
If&gt;c_count=1
  Let&gt;clicks=%c_1%
EndIf

// Loop an array (countries)
JSONParse&gt;RESP,$.stats.countries&#91;*],cc
Let&gt;k=0
Repeat&gt;k
  Let&gt;k=k+1
  Let&gt;country=cc_%k%
  // do something with %country%
Until&gt;k=cc_count

</code></pre>



<p><code>JSONParse</code>&nbsp;returns an array and a&nbsp;<code>*_count</code>—loop over it with&nbsp;<code>Repeat/Until</code>.&nbsp;</p>



<h2>Common gotchas</h2>



<ul>
<li><strong>For JSON, always set&nbsp;<code>HTTP_POSTJSON=1</code></strong>&nbsp;(don’t hand-craft&nbsp;<code>Content-Type</code>).&nbsp;<a href="https://www.mjtnet.com/manuals/b/v15/topics/httprequest.htm" target="_blank" rel="noreferrer noopener">mjtnet.com</a></li>



<li><strong>Escape quotes</strong>&nbsp;inside JSON strings correctly.</li>



<li><strong>Use timeouts</strong>&nbsp;so a bad endpoint doesn’t hang your run (<code>Let&gt;HTTP_TIMEOUT=15</code>).&nbsp;<a href="https://www.mjtnet.com/manuals/b/v15/topics/systemvariables.htm" target="_blank" rel="noreferrer noopener">mjtnet.com</a></li>



<li>If an API returns HTML (error pages),&nbsp;<code>JSONParse</code>&nbsp;will fail—<strong>log&nbsp;<code>RESP</code></strong>&nbsp;to inspect.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2>Further reading</h2>



<ul>
<li>Macro Scheduler:&nbsp;<code><a href="https://www.mjtnet.com/manuals/b/v15/topics/httprequest.htm">HTTPRequest</a></code>&nbsp;(methods, headers, files, SSL, timeouts).&nbsp;<a rel="noreferrer noopener" href="https://www.mjtnet.com/manuals/b/v15/topics/httprequest.htm" target="_blank">mjtnet.com</a></li>



<li>Macro Scheduler:&nbsp;<code><a href="https://www.mjtnet.com/manuals/b/v15/topics/jsonparse.htm">JSONParse</a></code>&nbsp;(JSONPath, arrays, examples).&nbsp;</li>



<li>If you prefer you can use Python requests with <a href="https://www.mjtnet.com/manuals/b/v15/topics/pyexec.htm">PyExec</a>.</li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Let Us Automate It For You</title>
		<link>https://www.mjtnet.com/blog/2025/08/25/let-us-automate-it-for-you/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Mon, 25 Aug 2025 13:17:20 +0000</pubDate>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Scripting]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3252</guid>

					<description><![CDATA[At MJT Net we’ve been helping people automate Windows applications for more than 25 years with Macro Scheduler. Thousands of users have built their own scripts to save time, eliminate repetitive tasks, and connect systems that otherwise don’t talk to each other. But did you know we also offer&#160;done-for-you automation services? We understand that not [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>At MJT Net we’ve been helping people automate Windows applications for more than 25 years with <a href="https://www.mjtnet.com/macro-scheduler.htm"><strong>Macro Scheduler</strong>.</a> Thousands of users have built their own scripts to save time, eliminate repetitive tasks, and connect systems that otherwise don’t talk to each other.</p>



<p>But did you know we also offer&nbsp;<strong>done-for-you automation services</strong>?</p>



<p>We understand that not everyone has the time to dive into scripting, or sometimes the task at hand is a little too complex to tackle alone. That’s where our team comes in.</p>



<h2>Automation Built for You</h2>



<p>We’ve created custom automations for organizations of all sizes — from small businesses right through to the&nbsp;<strong>NHS and other major healthcare providers</strong>. Whether it’s:</p>



<ul>
<li>Filling out forms automatically</li>



<li>Extracting and processing data</li>



<li>Integrating with legacy systems</li>



<li>Or orchestrating complete workflows across multiple applications</li>
</ul>



<p>…our team can design, script, and deliver a solution that works seamlessly for you.</p>



<p>And if you already have a Macro Scheduler script — whether it’s partly built, needs fixing, or could do with enhancements — we can&nbsp;<strong>adapt, maintain, and improve your existing routines</strong>&nbsp;too.</p>



<h2>How It Works</h2>



<p>To automate something properly, we need to&nbsp;<strong>see the process in action</strong>. That means we’ll ask you to walk us through the steps, and in most cases we’ll need secure&nbsp;<strong>remote access</strong>&nbsp;to your system so we can interact directly with the applications involved.</p>



<p>Once we’ve observed the process, we’ll design and build a&nbsp;<strong>Macro Scheduler script or set of scripts</strong>&nbsp;that replicate your workflow reliably. These run inside Macro Scheduler — giving you flexibility to adapt, extend, and manage your automations over time.</p>



<p>From simple repetitive actions to complex multi-application workflows, our goal is to remove the manual effort so you can focus on more important things.</p>



<h2>Why Use Our Services?</h2>



<ul>
<li><strong>Save time quickly</strong>&nbsp;— no need to learn scripting from scratch.</li>



<li><strong>Tailored solutions</strong>&nbsp;— we adapt to your processes, not the other way around.</li>



<li><strong>Proven experience</strong>&nbsp;— decades of automation expertise across industries.</li>



<li><strong>Ongoing support</strong>&nbsp;— we can update and enhance scripts as your needs evolve.</li>
</ul>



<h2>Ready to Talk?</h2>



<p>If you’ve got a task in mind — whether it’s something you do dozens of times a day, or a regular process that eats into your team’s time — let’s discuss how we can automate it for you.</p>



<p><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f449.png" alt="👉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong><a href="/contact.htm">Contact us today</a></strong> and let’s see how much time we can save you.</p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Announcing &#8211; Macro Scheduler WebRecorder Extension &#8211; Beta</title>
		<link>https://www.mjtnet.com/blog/2025/06/11/announcing-macro-scheduler-webrecorder-extension-beta/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Wed, 11 Jun 2025 20:40:56 +0000</pubDate>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3246</guid>

					<description><![CDATA[Announcing the Macro Scheduler WebRecorder Chrome Extension. Old timers will remember the WebRecorder. Well it&#8217;s back. Kinda. What is it? A Chrome browser extension that records user interactions on web pages and generates Macro Scheduler automation scripts with Chrome WebDriver commands. Beta Installation Instructions Download here: https://www.mjtnet.com/software/macro-scheduler-extension-1-5-7.zip Since this extension is in beta testing and [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Announcing the Macro Scheduler WebRecorder Chrome Extension.  Old timers will remember the WebRecorder. Well it&#8217;s back. Kinda.</p>



<h2>What is it?</h2>



<p>A Chrome browser extension that records user interactions on web pages and generates Macro Scheduler automation scripts with Chrome WebDriver commands.</p>



<ul>
<li>Records user interactions such as clicks, typing and form submissions</li>



<li>Generates optimized Macro Scheduler scripts with proper syntax</li>



<li>Supports Chrome WebDriver commands (ChromeStart, ChromeNavigate, ChromeFindElements, etc.)</li>



<li>Smart duplicate event removal for cleaner scripts</li>



<li>One-click script download</li>
</ul>



<h2>Beta Installation Instructions</h2>



<p>Download here:</p>



<p><a href="https://www.mjtnet.com/software/macro-scheduler-extension-1-5-7.zip">https://www.mjtnet.com/software/macro-scheduler-extension-1-5-7.zip</a></p>



<p>Since this extension is in beta testing and not yet published to the Chrome Web Store, you&#8217;ll need to install it as an &#8220;unpacked extension&#8221;:</p>



<h3>Step 1: Extract the Extension</h3>



<ol>
<li>Download and extract the&nbsp;<code>macro-scheduler-extension.zip</code>&nbsp;file to a folder on your computer</li>



<li>Remember the location of this folder &#8211; you&#8217;ll need it in Step 3</li>
</ol>



<h3>Step 2: Enable Developer Mode in Chrome</h3>



<ol>
<li>Open Google Chrome</li>



<li>Click the three dots menu (⋮) in the top-right corner</li>



<li>Go to&nbsp;<strong>More tools</strong>&nbsp;→&nbsp;<strong>Extensions</strong></li>



<li>Or directly navigate to:&nbsp;<code>chrome://extensions/</code></li>



<li>Toggle&nbsp;<strong>&#8220;Developer mode&#8221;</strong>&nbsp;ON in the top-right corner of the Extensions page</li>
</ol>



<h3>Step 3: Load the Extension</h3>



<ol>
<li>Click&nbsp;<strong>&#8220;Load unpacked&#8221;</strong>&nbsp;button (appears after enabling Developer mode)</li>



<li>Navigate to and select the folder where you extracted the extension files</li>



<li>Click&nbsp;<strong>&#8220;Select Folder&#8221;</strong></li>



<li>The extension should now appear in your extensions list</li>
</ol>



<h3>Step 4: Pin the Extension (Optional but Recommended)</h3>



<ol>
<li>Click the puzzle piece icon (<img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f9e9.png" alt="🧩" class="wp-smiley" style="height: 1em; max-height: 1em;" />) in Chrome&#8217;s toolbar</li>



<li>Find &#8220;Macro Scheduler Recorder&#8221; in the list</li>



<li>Click the pin icon (<img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f4cc.png" alt="📌" class="wp-smiley" style="height: 1em; max-height: 1em;" />) next to it</li>



<li>The extension icon will now appear directly in your toolbar</li>
</ol>



<h2>How to Use</h2>



<ol>
<li><strong>Start Recording</strong>: Click the extension icon and press &#8220;Start Recording&#8221;</li>



<li><strong>Perform Actions</strong>: Navigate to any website and perform the actions you want to automate (clicking, typing, form submissions, etc.)</li>



<li><strong>Stop Recording</strong>: Click the extension icon again and press &#8220;Stop Recording&#8221;</li>



<li><strong>Download Script</strong>: Review the generated script and click &#8220;Download Script&#8221; to save it as a&nbsp;<code>.scp</code>&nbsp;file</li>
</ol>



<h2>Generated Script Requirements</h2>



<p><strong>Important</strong>: The generated scripts require Chrome for Testing to be installed on your system.</p>



<ul>
<li>Download and installation instructions:&nbsp;<a href="https://www.mjtnet.com/manuals/b/v15/topics/chromestart.htm" target="_blank" rel="noreferrer noopener">https://www.mjtnet.com/manuals/b/v15/topics/chromestart.htm</a></li>



<li>Make sure to update the&nbsp;<code>CHROMEDRIVER_EXE</code>&nbsp;path in the generated script to match your installation</li>
</ul>



<h2>Beta Testing Notes</h2>



<p>This is a beta version for testing purposes. Please report any issues or suggestions:</p>



<ul>
<li>Extension behavior problems</li>



<li>Script generation errors</li>



<li>UI/UX feedback</li>



<li>Feature requests</li>
</ul>



<p>This is early beta. And anyone who has ever dabbled with automating Chrome and websites will hopefully know how difficult it is to make one-size-fits-all rules. There are bound to be things this can&#8217;t automate. It might not always be able to find the best element selectors, or ones that are unique. So your mileage WILL vary. But we&#8217;ve tested a few thorny scenarios &#8211; frames, new tabs opening as well as forms and clicks and so far we&#8217;re happy with what it can do. Have a play. And drop your comments and feedback in the <a href="https://forum.mjtnet.com">forums</a> or <a href="https://www.mjtnet.com/contact">drop us a line here</a>.</p>



<h2>Supported Actions</h2>



<p>The extension currently records and generates scripts for:</p>



<ul>
<li>Element clicks (buttons, links, etc.)</li>



<li>Text input (input fields, textareas)</li>



<li>Form submissions</li>



<li>Keyboard interactions</li>



<li>Focus events</li>
</ul>



<p><strong>Note</strong>: The initial page URL is automatically included when recording starts. Subsequent page changes should result from user interactions (clicks, form submissions) rather than manual URL changes.</p>



<h2>Script Output Format</h2>



<p>Generated scripts use Macro Scheduler syntax with Chrome WebDriver commands:</p>



<pre class="wp-block-preformatted">ChromeStart>session_id
ChromeNavigate>session_id,url,https://example.com
ChromeFindElements>session_id,css selector,input[type='text'],elements
ChromeSetElementValue>session_id,elements_1,Hello World
ChromeElementAction>session_id,elements_1,click
ChromeQuit>session_id</pre>



<h2>Troubleshooting</h2>



<h3>Extension Not Loading</h3>



<ul>
<li>Make sure Developer mode is enabled</li>



<li>Verify all extension files are in the selected folder</li>



<li>Check Chrome&#8217;s console for error messages (<code>F12</code>&nbsp;→ Console tab)</li>
</ul>



<h3>Recording Not Working</h3>



<ul>
<li>Refresh the page after starting recording</li>



<li>Make sure the extension has permission to access the website</li>



<li>Check that you&#8217;re performing supported actions (clicks, typing, etc.)</li>
</ul>



<h3>Script Generation Issues</h3>



<ul>
<li>Ensure you have recorded at least one action</li>



<li>Verify the recorded events appear in the extension popup</li>



<li>Try clearing and re-recording if the script appears empty</li>
</ul>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Introducing Macro Scheduler Agent — AI-powered help for your scripts (Beta)</title>
		<link>https://www.mjtnet.com/blog/2025/06/04/introducing-macro-scheduler-agent-ai-powered-help-for-your-scripts-beta/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Wed, 04 Jun 2025 21:16:29 +0000</pubDate>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Macro Recorder]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3240</guid>

					<description><![CDATA[We’re excited to share an early Beta version of something we’ve been experimenting with here at MJT Net: &#x1f449;&#160;Macro Scheduler Agent&#160;— an AI-powered web tool to help you write, improve, and troubleshoot Macro Scheduler scripts. What can it do? Important caveats — this is Beta! We’re calling this an&#160;experimental Beta&#160;for good reason: &#x2705; It’s an [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>We’re excited to share an early Beta version of something we’ve been experimenting with here at MJT Net:</p>



<p><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f449.png" alt="👉" class="wp-smiley" style="height: 1em; max-height: 1em;" />&nbsp;<strong><a class="" href="https://agent.mjtnet.com/">Macro Scheduler Agent</a></strong>&nbsp;— an AI-powered web tool to help you write, improve, and troubleshoot Macro Scheduler scripts.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><strong>What can it do?</strong></p>



<ul>
<li><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f4dd.png" alt="📝" class="wp-smiley" style="height: 1em; max-height: 1em;" />&nbsp;<strong>Explain a script</strong>&nbsp;— upload a script and get a plain English explanation, plus suggestions to improve it</li>



<li><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f575.png" alt="🕵" class="wp-smiley" style="height: 1em; max-height: 1em;" />&nbsp;<strong>Why doesn&#8217;t this work?</strong>&nbsp;— submit a script you’re having trouble with, and get ideas for what might be going wrong</li>



<li><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f916.png" alt="🤖" class="wp-smiley" style="height: 1em; max-height: 1em;" />&nbsp;<strong>How would I automate this?</strong>&nbsp;— upload screenshots and describe what you want to automate</li>



<li><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f310.png" alt="🌐" class="wp-smiley" style="height: 1em; max-height: 1em;" />&nbsp;<strong>Web form automation</strong>&nbsp;(experimental) — upload a CSV and a web form URL, and it will try to generate a script to fill out the form</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><strong>Important caveats — this is Beta!</strong></p>



<p>We’re calling this an&nbsp;<strong>experimental Beta</strong>&nbsp;for good reason:</p>



<p><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> It’s an AI-based tool — results will vary<br><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> It’s&nbsp;<strong>still learning</strong>&nbsp;— sometimes it will get things wrong<br><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> It may suggest improvements, but they’re not guaranteed to be optimal<br><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> For the Web Automation wizard in particular, success depends heavily on the structure of the form</p>



<p><strong>Please treat this as a helpful assistant, not an infallible authority!</strong><br>Always test any generated scripts before using them in production.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><strong>Who can use it?</strong></p>



<p>Currently, access is limited to&nbsp;<strong>licensed Macro Scheduler users</strong>&nbsp;— it will check your email against our license database.<br>For now, it’s free to use for licensed users while we continue to develop and refine it.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><strong>Why are we building this?</strong></p>



<p>Macro Scheduler users are an incredibly creative bunch, building automations for all kinds of applications and workflows.</p>



<p>We see the potential for AI to:</p>



<p><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Help users learn the language faster<br><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Speed up troubleshooting<br><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Provide inspiration for better automation techniques<br><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Bridge the gap for newer users</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><strong>Try it out:</strong><br><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f449.png" alt="👉" class="wp-smiley" style="height: 1em; max-height: 1em;" />&nbsp;<a class="" href="https://agent.mjtnet.com/">https://agent.mjtnet.com/</a></p>



<p></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><strong>We need your feedback!</strong></p>



<p>If you try it out, we’d love to hear:</p>



<p><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> What worked well<br><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> What didn’t<br><img src="https://s.w.org/images/core/emoji/14.0.0/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> What else you’d like to see it do</p>



<p>This will help us improve it and guide future development.</p>



<p>Head over to the forums here:</p>



<p><a href="https://forum.mjtnet.com/topic/20710">https://forum.mjtnet.com/topic/20710</a></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><strong>Final note</strong></p>



<p>Again — this is&nbsp;<strong>Beta</strong>,&nbsp;<strong>experimental</strong>, and&nbsp;<strong>still learning</strong>.<br>It won’t always get things right — but we think it can already be a useful assistant.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Give it a go — and happy scripting!</p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Macro Scheduler 15.0.29 Available</title>
		<link>https://www.mjtnet.com/blog/2025/03/15/macro-scheduler-15-0-29-available/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Sat, 15 Mar 2025 11:58:31 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Announcements]]></category>
		<category><![CDATA[update]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3233</guid>

					<description><![CDATA[Macro Scheduler 15.0.29 update is available. This version applies some internal improvements for the Chrome/Edge automation functions and in particular allows you to set startup switches for Edge, and also set a download folder for Chrome. The CHROME_DOWNLOADPATH option is particularly useful if you need to automate a routine which involves downloading a file with Chrome. [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p><a href="https://www.mjtnet.com/macro-scheduler.htm">Macro Scheduler</a> 15.0.29 update is available.</p>



<ul>
<li>Added: EDGEDRIVER_OPTIONS variable to specify Edge startup switches</li>



<li>Added: CHROMEDRIVER_DOWNLOADPATH variable to specify Chrome download folder (experimental)</li>
</ul>



<p>This version applies some internal improvements for the Chrome/Edge automation functions and in particular allows you to set startup switches for Edge, and also set a download folder for Chrome. </p>



<p>The CHROME_DOWNLOADPATH option is particularly useful if you need to automate a routine which involves downloading a file with Chrome. It will avoid asking for confirmation and the file will be automatically downloaded to the specified folder.</p>



<p><a href="https://www.mjtnet.com/ua.htm">Registered Downloads/Upgrades</a>&nbsp;|&nbsp;<a href="https://www.mjtnet.com/macro-scheduler.htm">Trial Downloads</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Macro Scheduler 15.0.25 Update Available</title>
		<link>https://www.mjtnet.com/blog/2024/09/19/macro-scheduler-15-0-25-update-available/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Thu, 19 Sep 2024 09:09:51 +0000</pubDate>
				<category><![CDATA[Announcements]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3230</guid>

					<description><![CDATA[Macro Scheduler 15.0.25 update is now available. Registered Downloads/Upgrades &#124; Trial Downloads]]></description>
										<content:encoded><![CDATA[
<p><a href="https://www.mjtnet.com/macro-scheduler.htm">Macro Scheduler</a> 15.0.25 update is now available.</p>



<ul>
<li>Added: ONERROR (custom error routine) capture added for complex if statements</li>



<li>Added: experimental TMSWebBrowser and&nbsp;<a href="https://help.mjtnet.com/article/368-adobe-acrobat-pdf-control" target="_blank" rel="noreferrer noopener">TMSAcroPDF</a>&nbsp;(requires Adobe Acrobat Reader to be installed) objects to dialogs</li>



<li>Fixed: unable to get HTML property of HTMLViewer dialog object</li>



<li>Fixed: GetProcessIds not returning empty array if process does not exist</li>



<li>Fixed: GetWindowChildList missing from code builder</li>
</ul>



<p><a href="https://www.mjtnet.com/ua.htm">Registered Downloads/Upgrades</a> | <a href="https://www.mjtnet.com/macro-scheduler.htm">Trial Downloads</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Macro Scheduler Update 15.0.23 Available</title>
		<link>https://www.mjtnet.com/blog/2023/06/07/macro-scheduler-update-15-0-23-available/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Wed, 07 Jun 2023 13:26:40 +0000</pubDate>
				<category><![CDATA[Announcements]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3224</guid>

					<description><![CDATA[Macro Scheduler 15.0.23 is now available with the following changes: Registered Downloads/Upgrades &#124; Trial Downloads]]></description>
										<content:encoded><![CDATA[
<p><a href="https://www.mjtnet.com/macro-scheduler.htm">Macro Scheduler</a> 15.0.23 is now available with the following changes:</p>



<ul>
<li>Added: <a href="https://www.mjtnet.com/manuals/b/v15/topics/edgeexecute.htm" target="_blank" rel="noreferrer noopener">EdgeExecute</a> function</li>



<li>Added: RP_CAPTURESTDOUT and RP_STDOUT variables for capturing STDOUT from <a href="https://www.mjtnet.com/manuals/b/v15/topics/runprogram.htm" data-type="URL" data-id="https://www.mjtnet.com/manuals/b/v15/index.htm?context=3610" target="_blank" rel="noreferrer noopener">RunProgram</a> process. Warning: using this will mean RunProgram will ALWAYS wait for the process to terminate, which may require user input in some cases.</li>



<li>Added: <a href="https://www.mjtnet.com/manuals/b/v15/topics/lclick.htm" data-type="URL" data-id="https://www.mjtnet.com/manuals/b/v15/topics/lclick.htm" target="_blank" rel="noreferrer noopener">LClick</a> and <a href="https://www.mjtnet.com/manuals/b/v15/topics/rclick.htm" target="_blank" rel="noreferrer noopener">RClick</a> can now take multiplier like Press commands, e.g. LCLick * 2, RClick * 2</li>



<li>Added: optional 5th param to <a href="https://www.mjtnet.com/manuals/b/v15/topics/datediff.htm" target="_blank" rel="noreferrer noopener">DateDiff</a> &amp; <a href="https://www.mjtnet.com/manuals/b/v15/topics/timediff.htm" target="_blank" rel="noreferrer noopener">TimeDiff</a> commands to return whether date2/time2 is later or earlier than date1/time2</li>



<li>Added: <a href="https://www.mjtnet.com/manuals/b/v15/topics/between.htm" target="_blank" rel="noreferrer noopener">Between</a> function to return text between two tokens</li>



<li>Added: ^ (power) operator to Let command</li>



<li>Added: [drive], [folder], [filename] keywords to EasyPattern regex mode.</li>



<li>Added: Ability to block comment/uncomment with ctrl+/ in editor</li>
</ul>



<p><a href="https://www.mjtnet.com/ua.htm">Registered Downloads/Upgrades</a> | <a href="https://www.mjtnet.com/macro-scheduler.htm">Trial Downloads</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>University Hospitals Dorset Saves Up to £15,000 Automating Maternity Healthcare Records with Macro Scheduler</title>
		<link>https://www.mjtnet.com/blog/2022/09/20/university-hospitals-dorset-saves-up-to-15000-automating-maternity-healthcare-records-with-macro-scheduler/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Tue, 20 Sep 2022 12:57:05 +0000</pubDate>
				<category><![CDATA[Success Stories]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3218</guid>

					<description><![CDATA[University Hospitals Dorset (NHS) recently automated the transfer of data from their existing maternity records system into BadgerNet Maternity using Macro Scheduler. The NHS trust was able to save significant time and up to £15,000 by using Macro Scheduler to perform the automation. More details here. Read the case study.]]></description>
										<content:encoded><![CDATA[<p>University Hospitals Dorset (NHS) recently automated the transfer of data from their existing maternity records system into <a href="https://www.badgernotes.net" rel="noopener noreferrer" target="_blank">BadgerNet Maternity</a> using <a href="https://www.mjtnet.com/macro-scheduler.htm" rel="noopener noreferrer" target="_blank">Macro Scheduler</a>.</p>
<p><a href="https://ourdorset.org.uk/innovation/project/badgernet-automation-to-achieve-results/" rel="noopener noreferrer" target="_blank"><img decoding="async" src="https://ourdorset.org.uk/innovation/wp-content/uploads/sites/2/2022/08/BadgerNet.jpg" alt="BadgerNet Automation" /></a></p>
<p>The NHS trust was able to save significant time and up to £15,000 by using Macro Scheduler to perform the automation.</p>
<p><a href="https://ourdorset.org.uk/innovation/project/badgernet-automation-to-achieve-results/" rel="noopener noreferrer" target="_blank">More details here</a>.<br />
<a href="https://ourdorset.org.uk/innovation/wp-content/uploads/sites/2/2022/08/UHD-Maternity-Historicals-Automation-Case-Study-v0.5.pdf" rel="noopener noreferrer" target="_blank">Read the case study</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Macro Scheduler 15.0.20 Available</title>
		<link>https://www.mjtnet.com/blog/2021/12/21/macro-scheduler-15-0-20-available/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Tue, 21 Dec 2021 14:46:05 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3216</guid>

					<description><![CDATA[Seasons greetings! Last week we released Macro Scheduler maintenance update 15.0.20: Added: ChromeGetWindows, ChromeSwitchWindow, EdgeGetWindows, EdgeSwitchWindow functions Added: Copy Let assignment option to watchlist menu (creates Let&#62;variable=value on clipboard) Fixed: edge case with some strings not being quoted properly in variable expressions Updated: changed PPI zoom cut-off for larger icons Trial downloads &#124; Registered Updates]]></description>
										<content:encoded><![CDATA[<p>Seasons greetings!</p>
<p>Last week we released <a href="https://www.mjtnet.com/macro-scheduler.htm">Macro Scheduler</a> maintenance update 15.0.20:</p>
<ul>
<li>Added: ChromeGetWindows, ChromeSwitchWindow, EdgeGetWindows, EdgeSwitchWindow functions</li>
<li>Added: Copy Let assignment option to watchlist menu (creates Let&gt;variable=value on clipboard)</li>
<li>Fixed: edge case with some strings not being quoted properly in variable expressions</li>
<li>Updated: changed PPI zoom cut-off for larger icons</li>
</ul>
<p><a href="https://www.mjtnet.com/macro-scheduler.htm">Trial downloads</a> | <a href="https://www.mjtnet.com/ua.htm">Registered Updates</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Automating Windows 11 with Macro Scheduler</title>
		<link>https://www.mjtnet.com/blog/2021/07/19/automating-windows-11-with-macro-scheduler/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Mon, 19 Jul 2021 14:04:24 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3209</guid>

					<description><![CDATA[If you are signed up to the Windows Insider program you can already try Windows 11. Here&#8217;s Macro Scheduler 15 running happily in Windows 11: &#160;]]></description>
										<content:encoded><![CDATA[
<p>If you are signed up to the Windows Insider program you can already try Windows 11. Here&#8217;s Macro Scheduler 15 running happily in Windows 11:</p>

<p>&nbsp;</p>
<p><img decoding="async" style="max-width: 750px;" src="https://www.mjtnet.com/blog/wp-content/uploads/2021/07/Screenshot-2021-07-19-at-14.59.48-1024x611.png" alt="Automate Windows 11 with Macro Scheduler" /></p>]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Recording Excel macros for Macro Scheduler</title>
		<link>https://www.mjtnet.com/blog/2020/11/12/recording-excel-macros-for-macro-scheduler/</link>
		
		<dc:creator><![CDATA[Dorian]]></dc:creator>
		<pubDate>Thu, 12 Nov 2020 14:40:12 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3197</guid>

					<description><![CDATA[Did you know that since v15 you can run Excel VBA macros from directly within your Macro Scheduler code? We&#8217;ve added a helpdesk article showing you how it works here.]]></description>
										<content:encoded><![CDATA[
<p>Did you know that since v15 you can run Excel VBA macros from directly within your Macro Scheduler code? We&#8217;ve added a helpdesk article showing you how it works <a href="https://help.mjtnet.com/article/339-recording-excel-macros-for-macro-scheduler">here</a>.</p>



<p></p>


<p><iframe loading="lazy" src="https://screencast-o-matic.com/embed?sc=cYXX22MgnR&amp;v=5&amp;ff=1" width="640" height="360" frameborder="0" scrolling="no" allowfullscreen="allowfullscreen"></iframe></p>


<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Macro Scheduler, my lockdown assistant.</title>
		<link>https://www.mjtnet.com/blog/2020/05/27/macro-scheduler-my-lockdown-assistant/</link>
		
		<dc:creator><![CDATA[Dorian]]></dc:creator>
		<pubDate>Wed, 27 May 2020 13:07:46 +0000</pubDate>
				<category><![CDATA[Automation]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3139</guid>

					<description><![CDATA[The world has changed during the past 9 weeks or so, and some of the MJT staff have been putting Macro Scheduler to good use to help them during lockdown. Soon after lockdown was announced people began panic buying, and grocery store delivery slots would all be claimed within moments of being released. For those [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>The world has changed during the past 9 weeks or so, and some of the MJT staff have been putting <a href="https://www.mjtnet.com/">Macro Scheduler</a> to good use to help them during lockdown.</p>
<p><center><img decoding="async" loading="lazy" width="1024" height="791" class="aligncenter wp-image-3145" src="https://www.mjtnet.com/blog/wp-content/uploads/2020/05/iStock-515000042-1024x791.jpg" alt="" style="max-width:640px; height:auto" srcset="https://www.mjtnet.com/blog/wp-content/uploads/2020/05/iStock-515000042-1024x791.jpg 1024w, https://www.mjtnet.com/blog/wp-content/uploads/2020/05/iStock-515000042-300x232.jpg 300w, https://www.mjtnet.com/blog/wp-content/uploads/2020/05/iStock-515000042-768x593.jpg 768w, https://www.mjtnet.com/blog/wp-content/uploads/2020/05/iStock-515000042.jpg 1165w" sizes="(max-width: 1024px) 100vw, 1024px" /></center>Soon after lockdown was announced people began panic buying, and grocery store delivery slots would all be claimed within moments of being released. For those of us with vulnerable people at home and no family nearby, our only hope was securing regular delivery slots &#8211; and buying a freezer! But with thousands of people competing for those rare delivery slots and all online appliance outlets completely sold out of freezers, it was an uphill battle.</p>
<p>But Macro Scheduler came to the rescue.</p>
<p>One simple automation script monitored a handful of web pages 24/7, refreshing every minute or so. It watched our local Supermarket looking for slots, and it monitored the white-goods stores waiting for any one of half-a-dozen freezers to be re-stocked.</p>
<p>A few days went by. No luck. Was this going to work? Would there ever be any slots? On day 6 I received a text on my phone &#8211; I&#8217;d been smart enough to <a href="https://www.mjtnet.com/blog/2014/06/19/automating-facebook-and-other-web-apps-via-zapier/">use Zapier</a> so Macro Scheduler would notify me via text wherever I may be.</p>
<p>A freezer had become available on the John Lewis website! We scurried over to the laptop and hurriedly clicked on the link. It&#8217;s no exaggeration to say our hearts were in our mouths. This was important! We didn&#8217;t even read the description. We just needed a freezer. Added it to our cart. Paid for it. Got the confirmation email. A few seconds later none were available again. We had successfully managed to purchase a freezer during the few minutes one online retailer had some.</p>
<p>Since then, over the past 8 weeks or so we used Macro Scheduler to tell us when those supermarket deliveries are available. They only pop up once or twice a day if we&#8217;re lucky &#8211; but when they do, we hear our little notification beep and off we run to the laptop and start shopping! It has been a Godsend, and it hasn&#8217;t failed us yet. Thanks to Macro Scheduler we top-up our little freezer every two weeks, and lockdown has been largely worry-free.</p>
<p>The process was simple. Here are some of the commands we used. <a href="http://www.mjtnet.com/manual/index.html?iecreate.htm">IECreate</a>, <a href="http://www.mjtnet.com/manual/index.html?ienavigate.htm">IENavigate</a> to get us to the pages we were looking for and <a href="https://www.mjtnet.com/manual/index.html?iegetalltext.htm">IEGetAllText</a> helped us scrape the text from the page, then we used <a href="http://www.mjtnet.com/manual/index.html?position.htm">Position</a> to see if the text we were looking for was, or wasn&#8217;t, on the page. All contained in a nice little <a href="https://help.mjtnet.com/article/144-how-to-loop-the-loop">loop,</a> watching and waiting 24/7.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Assisting the UK National Health Service</title>
		<link>https://www.mjtnet.com/blog/2020/04/09/assisting-the-uk-national-health-service/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Thu, 09 Apr 2020 15:46:34 +0000</pubDate>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[General]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3133</guid>

					<description><![CDATA[We find ourselves in challenging times. At MJT Net we&#8217;re all working from home, with the difficulty of trying to educate and entertain our children at the same time. Of course there is also a great deal of financial uncertainty. Businesses and people everywhere are feeling the pinch, ourselves included. Clearly though, the biggest challenge [&#8230;]]]></description>
										<content:encoded><![CDATA[<p class="text-build-content">We find ourselves in challenging times. At MJT Net we&#8217;re all working from home, with the difficulty of trying to educate and entertain our children at the same time.</p>
<p class="text-build-content">Of course there is also a great deal of financial uncertainty. Businesses and people everywhere are feeling the pinch, ourselves included.</p>
<p>Clearly though, the biggest challenge is being felt by our amazing health services, which are under incredible pressures.</p>
<p>Behind the scenes, healthcare IT departments are working against the clock, often with huge volumes of data. So it&#8217;s great to know that <a href="https://www.mjtnet.com/macro-scheduler.htm">Macro Scheduler</a> is reducing the burden during the current crisis.</p>
<p>Here&#8217;s what Tom, a Clinical Systems Developer at an NHS hospital in Northern England, told us last week:</p>
<blockquote style="margin-left:30px; font-style:italic!important; background-color:rgba(0,0,0,.04); padding:10px"><p>&#8220;In a crisis situation, we needed a straightforward automation tool which could help us make quick changes to a wide range of systems &#8211; without time to write API code. We found that Macro Scheduler more than fit the bill: it rapidly enabled us to automate repetitive tasks and to free up needed resources &#8211; ultimately giving us the time to better support our clinical staff in fighting coronavirus. In particular we have been very impressed with its ability to easily integrate with Google Chrome &#8211; like many organisations a lot of our tools are web-based and our ability to build automation into these workflows is a real game-changer.&#8221;</p></blockquote>
<p>If you work for a hospital on the front-line of coronavirus care and would benefit in using Macro Scheduler, or require additional licenses, please <a href="https://www.mjtnet.com/contact.htm">contact me</a> using your official work email address, tell me what you need Macro Scheduler for and we will see how we can help.</p>
<p>We’ve worked closely with a few UK hospital trusts over the years. In particular, Bournemouth Hospital has used Macro Scheduler extensively to automate dozens of clinical and administrative processes within the trust. You will find a <a href="https://help.mjtnet.com/article/247-macro-scheduler-bridges-technologies-for-nhs-hospital">case study we did with them a few years ago here</a>. Many times Macro Scheduler has been used to streamline processes that save the time of clinicians. And that can mean more patients get seen.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Covid-19 Response &#8211; Free Macro Scheduler Licenses for NHS Establishments</title>
		<link>https://www.mjtnet.com/blog/2020/03/19/covid-19-free-licenses-for-nhs-establishments/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Thu, 19 Mar 2020 15:16:49 +0000</pubDate>
				<category><![CDATA[Announcements]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3113</guid>

					<description><![CDATA[We find ourselves in challenging times. Things here in the UK seem to be changing rapidly every day. Only last night we heard that our schools will close tomorrow and this morning it was announced they were likely to remain closed for the rest of the academic year. So no school until September. I am [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>We find ourselves in challenging times. Things here in the UK seem to be changing rapidly every day. Only last night we heard that our schools will close tomorrow and this morning it was announced they were likely to remain closed for the rest of the academic year. So no school until September. I am already working from home. All of us here at MJT are working remotely, so we&#8217;re all safe and able to support you. But with two boys at secondary school I am now preparing for having them both at home and having to make sure they do their work while trying to do mine. Could be interesting!</p>
<p>Clearly though, the biggest challenge is being felt by our amazing health service, which is under incredible pressures. So, where possible I&#8217;d like to offer any NHS establishment <strong>free use of Macro Scheduler</strong> while this crisis lasts. If you work for the NHS and would benefit in using Macro Scheduler, or require additional licenses, <a href="https://www.mjtnet.com/contact.htm">please contact me</a> using your NHS email address, tell me what you need Macro Scheduler for and we will see how we can help.</p>
<p>We&#8217;ve worked closely with a few NHS trusts over the years. In particular, Bournemouth Hospital has used Macro Scheduler extensively to automate dozens of clinical and administrative processes within the trust. You will find a <a href="https://help.mjtnet.com/article/247-macro-scheduler-bridges-technologies-for-nhs-hospital">case study we did with them a few years ago here</a>. Many times Macro Scheduler has been used to streamline processes that save the time of clinicians. And that can mean more patients get seen. </p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Sending Keystrokes to Elements in Chrome and Edge Using the New Chrome/Edge Functions</title>
		<link>https://www.mjtnet.com/blog/2020/03/12/sending-keystrokes-to-elements-in-chrome-and-edge-using-the-new-chrome-edge-functions/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Thu, 12 Mar 2020 12:56:32 +0000</pubDate>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3107</guid>

					<description><![CDATA[It may not be immediately obvious that as well as setting the value of elements with ChromeSetElementValue and EdgeSetElementValue you can also send non-character keystrokes, such as Enter, or Page Down. To do this, use the key codes for Edge and Chrome listed here. For example: ChromeSetElementValue>session_id,message_elements_1,First line //Press enter on the element ... ChromeSetElementValue>session_id,message_elements_1,\uE006 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>It may not be immediately obvious that as well as setting the value of elements with <a href="https://www.mjtnet.com/manuals/v15/HTML/chromesetelementvalue.html">ChromeSetElementValue</a> and <a href="https://www.mjtnet.com/manuals/v15/HTML/edgesetelementvalue.html">EdgeSetElementValue</a> you can also send non-character keystrokes, such as Enter, or Page Down.</p>
<p>To do this, use the <a href="https://www.mjtnet.com/manuals/v15/HTML/key-codes-for-edge-and-chrome.html">key codes for Edge and Chrome listed here</a>.</p>
<p>For example:</p>
<pre class="brush: macroscript">ChromeSetElementValue>session_id,message_elements_1,First line
//Press enter on the element ... 
ChromeSetElementValue>session_id,message_elements_1,\uE006
ChromeSetElementValue>session_id,message_elements_1,Second line</pre>
<p></p>
<p>Note that when sending keystrokes only one can be sent at a time.</p>
<p>Recently someone needed to scroll down inside a div, in order to force the page to fetch more data. Issuing a Page Down on the div element did the trick:</p>
<pre class="brush: macroscript">ChromeSetElementValue>session_id,div_elements_1,\uE00F</pre>
<p></p>
<p>So, ChromeSetElementValue sends keys as well as sets values &#8211; perhaps it should have been called ChromeSendKeysToElement and just maybe we&#8217;ll add that as a mapping if it helps.</p>
<p>Of course you don&#8217;t have to use the new Chrome/Edge functions &#8211; you can still use UI methods and use SetFocus, SendText and/or Image Recognition to locate page elements. </p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Using Macro Scheduler to Bridge Desktop Apps and Cloud &#8211; Case Study</title>
		<link>https://www.mjtnet.com/blog/2020/03/11/using-macro-scheduler-to-bridge-desktop-apps-and-cloud-case-study/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Wed, 11 Mar 2020 19:49:35 +0000</pubDate>
				<category><![CDATA[Success Stories]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3103</guid>

					<description><![CDATA[Are you automating web apps, or interacting with APIs? Macro Scheduler is packed with features that help with automating desktop applications and simulating user input. But it also has great support for consuming web resources via HTTP requests, as well as built in functions for automating modern web browsers. &#8220;Being able to move between GUI [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Are you automating web apps, or interacting with APIs?</p>
<p>Macro Scheduler is packed with features that help with automating desktop applications and simulating user input. But it also has great support for consuming web resources via HTTP requests, as well as built in functions for automating modern web browsers.</p>
<blockquote><p><strong>&#8220;Being able to move between GUI and API methods to handle our automation needs is priceless&#8221;</strong></p></blockquote>
<p>Find out how IT services company <a href="https://cloud2t.net/" target="_blank" rel="noopener">Cloud2T</a> uses Macro Scheduler to bridge desktop and modern API driven cloud services. <a href="https://help.mjtnet.com/article/323-macro-scheduler-seamlessly-blends-older-guis-with-newer-apis-and-effortlessly-runs-repetitive-volume-driven-rules">Read the case study here</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>Working with Frames in Chrome and Edge</title>
		<link>https://www.mjtnet.com/blog/2020/03/06/working-with-frames-in-chrome-edge/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Fri, 06 Mar 2020 13:28:54 +0000</pubDate>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3087</guid>

					<description><![CDATA[The new Chrome and Edge functions in Macro Scheduler 15 make it possible to locate frames and iframes and then manipulate elements within them. Switching Frames The ChromeSwitchFrame and EdgeSwitchFrame functions allow you to specify a frame or iframe element, by index or element reference, to switch the &#8220;browsing context&#8221; to. What this means is [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>The new Chrome and Edge functions in <a href="https://www.mjtnet.com/macro-scheduler.htm">Macro Scheduler 15</a> make it possible to locate frames and iframes and then manipulate elements within them.</p>
<h2>Switching Frames</h2>
<p>The <a href="https://www.mjtnet.com/manuals/v15/HTML/chromeswitchframe.html">ChromeSwitchFrame</a> and <a href="https://www.mjtnet.com/manuals/v15/HTML/edgeswitchframe.html">EdgeSwitchFrame</a> functions allow you to specify a frame or iframe element, by index or element reference, to switch the &#8220;browsing context&#8221; to.</p>
<p>What this means is that any subsequent interactions will take place against elements within that frame. So a subsequent ChromeFindElements call will attempt to locate the specific element within the frame, rather than the parent page, and ChromeElementAction will act against the given element within that frame.</p>
<pre class="brush:macroscript">//Find the frame using xpath
ChromeFindElements&gt;sessionID,xpath,//iframe[@src='/contact-form/formpage.html'],elements

//switch browsing context to this frame
ChromeSwitchFrame&gt;session_id,element,elements_1,res</pre>
<p></p>
<p>If xpath doesn&#8217;t mean anything to you see my recent post <a href="https://www.mjtnet.com/blog/2020/02/27/using-macro-scheduler-15s-chrome-automation-functions/">Using Macro Scheduler 15&#8217;s Chrome Functions</a> which includes an explanation of using Chrome&#8217;s Developer Tools to identify elements.</p>
<p>At some point you may need to switch the browsing context back to the parent frame. To do this you call ChromeSwitchFrame/EdgeSwitchFrame again with a null index. Subsequent calls to the Chrome/Edge functions will then act against the parent frame.</p>
<pre class="brush:macroscript">ChromeSwitchFrame&gt;session_id,index,null,res</pre>
<p></p>
<h2>Traversing Frames</h2>
<p>Since each time you switch frames you change the context to that frame, calling ChromeSwitchFrame or EdgeSwitchFrame again (on a valid frame element within) will switch the context down another level.</p>
<pre class="brush:macroscript">//Find the frame using xpath
ChromeFindElements&gt;sessionID,xpath,//iframe[@src='/contact-form/formpage.html'],elements
ChromeSwitchFrame&gt;session_id,element,elements_1,res

//Switch to the next frame down *within the current frame*
ChromeSwitchFrame&gt;session_id,index,0,res</pre>
<p></p>
<h2>Differences between Edge and Chrome</h2>
<p>The Edge and Chrome functions work in the same way and are almost identical. There&#8217;s one major difference when it comes to switching frames. When specifying an element (rather than index) ChromeSwitchFrame requires the element ID, whereas EdgeSwitchFrame requires the full element object. As well as an array of element IDs, EdgeFindElements returns a second array of the objects:</p>
<pre class="brush:macroscript">EdgeFindElements&gt;sessionID,xpath,//iframe[@src='/contact-form/formpage.html'],FrameElements</pre>
<p></p>
<p>This returns two arrays prefixed with the name passed as the return var (TheElements): FrameElements_1 &#8230; FrameElements_n and FrameElements_objects_1 &#8230; FrameElements_objects_n. For EdgeSwitchFrame use the second _objects array:</p>
<pre class="brush:macroscript">//switch to the frame
EdgeSwitchFrame&gt;session_id,element,FrameElements_objects_1,res</pre>
<p></p>
<h2>More Help</h2>
<p>View the <a href="https://www.mjtnet.com/manuals/v15/HTML/chrome-functions.html">Chrome Functions</a> and <a href="https://www.mjtnet.com/manuals/v15/HTML/edge-functions.html">Edge Functions</a> topics in the <a href="https://www.mjtnet.com/manuals/v15">Macro Scheduler Manual</a>.</p>
<h2>Full Example:</h2>
<pre class="brush:macroscript">Let&gt;CHROMEDRIVER_EXE=c:\chromedriver.exe

//start a Chrome session
ChromeStart&gt;session_id

//navigate to google.com
ChromeNavigate&gt;session_id,url,https://www.mjtnet.com/contact.htm

//Find the frame
ChromeFindElements&gt;sessionID,xpath,//iframe[@src='/contact-form/formpage.html'],elements

//switch to the first frame (the one with the fields)
ChromeSwitchFrame&gt;session_id,element,elements_1,res

//now anything we do is inside that frame so we should be able to get the name field and enter something
ChromeFindElements&gt;session_id,id,name,inputs
ChromeSetElementValue&gt;session_id,inputs_1,john doe

//Switch context back to parent
ChromeSwitchFrame&gt;session_id,index,null,res</pre>
<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
	<title>MacroScript SDK and Workflow Designer Updated for MacroScript v15</title>
		<link>https://www.mjtnet.com/blog/2020/02/28/macroscript-sdk-and-workflow-designed-updated-for-macroscript-v15/</link>
		
		<dc:creator><![CDATA[Marcus Tettmar]]></dc:creator>
		<pubDate>Fri, 28 Feb 2020 14:31:19 +0000</pubDate>
				<category><![CDATA[Announcements]]></category>
		<guid isPermaLink="false">https://www.mjtnet.com/blog/?p=3077</guid>

					<description><![CDATA[A quick note for those of you using the Macro Scheduler Pro Enterprise pack and/or the MacroScript SDK. Workflow Designer and the SDK have now been updated with the latest 15.0.06 MacroScript engine and can be downloaded from the registered user area.]]></description>
										<content:encoded><![CDATA[<p>A quick note for those of you using the Macro Scheduler Pro <a href="https://www.mjtnet.com/macro-scheduler-enterprise.htm">Enterprise pack</a> and/or the <a href="https://www.mjtnet.com/macroscript_sdk">MacroScript SDK</a>. Workflow Designer and the SDK have now been updated with the latest 15.0.06 MacroScript engine and can be downloaded from the <a href="https://www.mjtnet.com/ua.htm">registered user area</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
