Skip to content

Commit 5e9971c

Browse files
add bindings
1 parent 9335902 commit 5e9971c

3 files changed

Lines changed: 24 additions & 32 deletions

File tree

samples/email-triage-agent/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ The agent takes a single required input at job start:
3737

3838
## Connection (binding)
3939

40-
The Outlook connection used by the agent is declared as a **binding** in `bindings.json` rather than passed in as input. The code references placeholder identifiers (`<your-outlook-connection>` / `<your-folder>`) which Orchestrator resolves to the deployer-selected connection at run time, via the binding-overwrite mechanism.
40+
The Outlook connection used by the agent is declared as a **binding** in `bindings.json` rather than passed in as input. The code references a placeholder connection key (`<your-outlook-connection>`) and calls `sdk.connections.retrieve_async(OUTLOOK_CONNECTION_KEY)`. That method is decorated with `@resource_override("connection", resource_identifier="key")`, which inspects the runtime's binding-overwrite context and substitutes the deployer-selected connection's real key before the HTTP call. The agent then reads `connection.name` and `connection.folder.path` from the resolved connection and feeds them into `WaitIntegrationEvent`.
4141

4242
To run the agent:
4343

44-
- **In Orchestrator (deployed)**: pick the actual Outlook 365 connection when configuring the agent — Orchestrator's binding UI presents the deployer with the list of available `uipath-microsoft-outlook365` connections and overwrites the placeholders.
45-
- **Locally**: edit the `CONNECTION_NAME` / `CONNECTION_FOLDER` constants at the top of `graph.py` to point at a real connection in your tenant, or pass a resource-overwrites file via `--resource-overwrites`.
44+
- **In Orchestrator (deployed)**: pick the actual Outlook 365 connection when configuring the agent — Orchestrator's binding UI presents the deployer with the list of available `uipath-microsoft-outlook365` connections and overwrites the placeholder key.
45+
- **Locally**: edit the `OUTLOOK_CONNECTION_KEY` constant at the top of `graph.py` to a real connection key in your tenant, or pass a resource-overwrites file via `--resource-overwrites`.
4646

4747
The connector key (`uipath-microsoft-outlook365`) is hardcoded.
4848

samples/email-triage-agent/bindings.json

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,16 @@
33
"resources": [
44
{
55
"resource": "connection",
6-
"key": "<your-outlook-connection>.<your-folder>",
6+
"key": "<your-outlook-connection>",
77
"value": {
8-
"name": {
8+
"ConnectionId": {
99
"defaultValue": "<your-outlook-connection>",
1010
"isExpression": false,
11-
"displayName": "Connection Name"
12-
},
13-
"folderPath": {
14-
"defaultValue": "<your-folder>",
15-
"isExpression": false,
16-
"displayName": "Folder Path"
11+
"displayName": "Outlook Connection"
1712
}
1813
},
1914
"metadata": {
20-
"connector": "uipath-microsoft-outlook365",
15+
"Connector": "uipath-microsoft-outlook365",
2116
"useConnectionService": "true",
2217
"BindingsVersion": "2.2"
2318
}

samples/email-triage-agent/graph.py

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,11 @@
3838
GRAPH_API_BASE = "https://graph.microsoft.com/v1.0"
3939
OUTLOOK_CONNECTOR = "uipath-microsoft-outlook365"
4040

41-
# Placeholders bound to the actual connection via bindings.json. Orchestrator
42-
# substitutes these with the deployer-selected connection at run time.
43-
CONNECTION_NAME = "<your-outlook-connection>"
44-
CONNECTION_FOLDER = "<your-folder>"
41+
# Placeholder connection key bound to a real connection via bindings.json.
42+
# `connections.retrieve_async` is decorated with @resource_override("connection",
43+
# resource_identifier="key"), so at run time the decorator inspects the binding
44+
# overwrite context and substitutes the deployer-selected connection's real key.
45+
OUTLOOK_CONNECTION_KEY = "<your-outlook-connection>"
4546

4647

4748
class Severity(str, Enum):
@@ -108,19 +109,10 @@ async def _send_outlook_reply(message_id: str, body: str) -> None:
108109
issued for the UiPath Outlook connection that received the trigger.
109110
"""
110111
sdk = UiPath()
111-
connections = await sdk.connections.list_async(
112-
name=CONNECTION_NAME,
113-
folder_path=CONNECTION_FOLDER,
114-
connector_key=OUTLOOK_CONNECTOR,
115-
)
116-
connection = next(
117-
(c for c in connections if c.name == CONNECTION_NAME),
118-
None,
119-
)
120-
if connection is None or connection.id is None:
112+
connection = await sdk.connections.retrieve_async(OUTLOOK_CONNECTION_KEY)
113+
if connection.id is None:
121114
raise RuntimeError(
122-
f"Outlook connection {CONNECTION_NAME!r} not found in "
123-
f"folder {CONNECTION_FOLDER!r}."
115+
f"Outlook connection {OUTLOOK_CONNECTION_KEY!r} could not be resolved."
124116
)
125117

126118
token = await sdk.connections.retrieve_token_async(connection.id)
@@ -138,18 +130,23 @@ async def _send_outlook_reply(message_id: str, body: str) -> None:
138130

139131

140132
async def wait_for_email(state: GraphState) -> dict[str, Any]:
133+
sdk = UiPath()
134+
connection = await sdk.connections.retrieve_async(OUTLOOK_CONNECTION_KEY)
135+
folder_path = (
136+
connection.folder.get("path") if isinstance(connection.folder, dict) else None
137+
)
141138
logger.info(
142139
"Waiting for next email on '%s' (folder='%s') with subject=%r (triaged so far: %d)...",
143-
CONNECTION_NAME,
144-
CONNECTION_FOLDER,
140+
connection.name,
141+
folder_path,
145142
state.subject,
146143
state.triage_count,
147144
)
148145
email = interrupt(
149146
WaitIntegrationEvent(
150147
connector=OUTLOOK_CONNECTOR,
151-
connection_name=CONNECTION_NAME,
152-
connection_folder_path=CONNECTION_FOLDER,
148+
connection_name=connection.name or "",
149+
connection_folder_path=folder_path,
153150
operation="EMAIL_RECEIVED",
154151
object_name="Message",
155152
filter_expression=f"(subject=='{state.subject}')",

0 commit comments

Comments
 (0)