Building Multi-Application Workflows with UFO: Cross-App Automation Sequences
Master cross-application automation with Microsoft UFO by building workflows that transfer data between Excel, Outlook, browsers, and desktop applications through coordinated multi-app sequences.
The Power of Cross-Application Workflows
Single-application automation is useful but limited. The real productivity gains come from workflows that span multiple applications — extracting data from a database viewer, processing it in Excel, creating a report in Word, and emailing it through Outlook. These are the workflows that consume hours of manual labor every week and are notoriously difficult to automate with traditional tools.
UFO's HostAgent architecture is specifically designed for this scenario. It manages application switching, context preservation, and data transfer between apps.
Workflow 1: Web Data to Excel Report
This workflow scrapes data from a browser and processes it in Excel:
import subprocess
import time
def run_ufo_task(task: str, timeout: int = 300):
"""Execute a single UFO task."""
result = subprocess.run(
["python", "-m", "ufo", "--task", task],
capture_output=True, text=True, timeout=timeout,
)
if result.returncode != 0:
raise RuntimeError(f"UFO task failed: {result.stderr}")
return result.stdout
def web_to_excel_report():
"""Extract web data and create an Excel report."""
run_ufo_task(
"In Google Chrome, select the data table on the sales "
"dashboard and copy it to clipboard."
)
run_ufo_task(
"Open Excel, create a new workbook, paste clipboard at A1. "
"Bold the header row, auto-fit column widths, and add a "
"Growth % column with formulas."
)
run_ufo_task(
"In Excel, select Month and Revenue columns, insert a line "
"chart, save as Monthly_Report.xlsx on the Desktop."
)
Workflow 2: Excel Analysis to Email Summary
def excel_to_email_summary():
"""Analyze Excel data and send a summary email."""
tasks = [
# Open and analyze Excel data
(
"In Excel, open the file C:\\Reports\\Q1_Revenue.xlsx. "
"Go to the Summary sheet. Note the total revenue value in "
"cell D15 and the growth percentage in cell E15."
),
# Select and copy key data
(
"In Excel, select the range A1 through E5 on the Summary "
"sheet which contains the top 5 performers. Copy the "
"selection to clipboard."
),
# Compose email with context
(
"In Microsoft Outlook, create a new email. Set the To field "
"to leadership@company.com. Set the Subject to "
"'Q1 Revenue Summary - Top Performers'. In the email body, "
"type 'Team,' press Enter twice, then type "
"'Here are the Q1 revenue highlights:' press Enter twice, "
"then paste the clipboard contents. Press Enter twice more "
"and type 'Full report available in the shared drive.' "
"press Enter, type 'Best regards'"
),
# Send
(
"In Outlook, review the email and click Send."
),
]
for i, task in enumerate(tasks, 1):
print(f"Executing step {i}/{len(tasks)}...")
run_ufo_task(task)
time.sleep(2) # Allow UI to settle between steps
Building a Workflow Orchestrator
For production use, wrap UFO tasks in an orchestrator that handles errors, retries, and logging:
import logging
from dataclasses import dataclass
from enum import Enum
from typing import Callable, Optional
logger = logging.getLogger("ufo_orchestrator")
class StepStatus(Enum):
PENDING = "pending"
RUNNING = "running"
COMPLETED = "completed"
FAILED = "failed"
RETRYING = "retrying"
@dataclass
class WorkflowStep:
name: str
task: str
timeout: int = 300
max_retries: int = 2
pre_condition: Optional[Callable] = None
post_validation: Optional[Callable] = None
class UFOWorkflowOrchestrator:
def __init__(self, workflow_name: str, steps: list[WorkflowStep]):
self.workflow_name = workflow_name
self.steps = steps
self.results = []
def execute(self) -> dict:
"""Execute all workflow steps in sequence."""
logger.info(f"Starting workflow: {self.workflow_name}")
for i, step in enumerate(self.steps):
logger.info(f"Step {i+1}/{len(self.steps)}: {step.name}")
# Check pre-condition
if step.pre_condition and not step.pre_condition():
logger.error(f"Pre-condition failed for step: {step.name}")
return self._build_result("failed", i)
# Execute with retries
success = False
for attempt in range(step.max_retries + 1):
try:
output = run_ufo_task(step.task, step.timeout)
# Validate result
if step.post_validation:
if not step.post_validation(output):
raise ValueError("Post-validation failed")
success = True
self.results.append({
"step": step.name,
"status": "completed",
"attempt": attempt + 1,
})
break
except Exception as e:
logger.warning(
f"Step '{step.name}' attempt {attempt+1} failed: {e}"
)
if attempt < step.max_retries:
logger.info("Retrying...")
time.sleep(3)
if not success:
logger.error(f"Step '{step.name}' failed after all retries")
return self._build_result("failed", i)
return self._build_result("completed", len(self.steps))
def _build_result(self, status: str, steps_completed: int) -> dict:
return {
"workflow": self.workflow_name,
"status": status,
"steps_completed": steps_completed,
"total_steps": len(self.steps),
"details": self.results,
}
Data Transfer Patterns
Cross-application data transfer in UFO relies on three mechanisms:
See AI Voice Agents Handle Real Calls
Book a free demo or calculate how much you can save with AI voice automation.
Clipboard — the primary method. Copy in one app, switch to another, paste. Works for text, images, and formatted content.
File system — save a file from one application, open it in another. Useful for large datasets and binary formats.
Shared text — for small values, include the data directly in the task description: "In Outlook, type the total $1,250,000 in the email body."
FAQ
How does UFO handle timing between application switches?
UFO includes a configurable SLEEP_TIME parameter (default 2 seconds) that pauses between actions to let the UI settle. For cross-application switches, the HostAgent waits for the target window to become active before handing off to the AppAgent. You may need to increase SLEEP_TIME for slower machines or heavy applications.
What happens if data is lost during clipboard transfer between apps?
Clipboard transfer is generally reliable but can fail if another application modifies the clipboard between the copy and paste operations. For critical workflows, verify the paste result by including a verification step: "Verify the pasted data in cell A1 matches the expected header."
Can UFO handle workflows that span more than two applications?
Yes. The HostAgent can coordinate any number of applications in sequence. The orchestrator pattern shown above supports unlimited steps across any number of applications. The primary constraint is the total execution time and API cost.
#CrossAppAutomation #MultiAppWorkflow #DataTransfer #WorkflowOrchestration #MicrosoftUFO #DesktopAutomation #WindowsWorkflows #OfficePipeline
CallSphere Team
Expert insights on AI voice agents and customer communication automation.
Try CallSphere AI Voice Agents
See how AI voice agents work for your industry. Live demo available -- no signup required.