A managed Power Platform solution installed into your own environment: Dataverse tables, a plugin assembly, Power Automate flows, and web resources on the Case form. Where the Salesforce connector extends through Flow, this one extends through a configuration table — field mapping is data, not code.
Connector class
Like Salesforce, everything here installs into the member's own environment and TSANet operates nothing. Intercom is the opposite pole — a TSANet-hosted gateway, because nothing can run in-tenant at all — and Zendesk sits between. What distinguishes Dynamics from Salesforce is not where the code runs but how you change its behaviour.
| Salesforce | Dynamics | |
|---|---|---|
| Server-side code | Apex classes | Plugin assembly (.NET), registered on SDK messages |
| Automation | Flow library, clone and edit | Power Automate cloud flows |
| Field mapping | Written into the flow | a configuration table |
| UI surface | Lightning Web Components | HTML + JavaScript web resources on the Case form |
| Feature toggles | Flow activation | Environment variables |
| Inbound delivery | Apex REST on a public Site | Registered webhook to Power Automate, or the scheduled poll |
That third row is the one to notice. Mapping a TSANet field onto a Dynamics column is a record in the TSANet Case Mapping table, not a step in a flow — so a member can retarget the integration without opening an editor, and an admin who has never seen Power Automate can still change what lands where.
Architecture
A managed solution containing six Dataverse tables, a plugin assembly registered against roughly fifteen SDK message steps, a set of Power Automate cloud flows, a model-driven configuration app, a canvas app for connection settings, and the web resources that render the collaboration UI on the Case form.
CommonIntegration.js is the bridge from the browser to the plugin layer.ap_CaseCreateForm.html) plus a set of JavaScript web resources. If you are following that guide, read "LWC" as "web resource".Data model
The collaboration record. ap_name is the TSANet identifier (100 chars), ap_direction is inbound or outbound, and statuscode carries Open, Information, Accepted, Rejected or Closed — the API enum also has PENDINGACTION, which this option set has no value for; how the solution handles it has not been verified. ap_formjson holds the live form payload as a 200,000-character memo.
Notes against a case — ap_description up to 2,000 characters, plus creator name and email, related back through ap_tsanetcaseid. The API's note carries a required summary (500 characters) and an optional description (5,000), so a longer partner note is truncated here, and how the solution fills summary on outbound notes has not been verified.
Formal replies on inbound cases. The response type option set covers approval, rejection, information request, information response, close and approval update. Close applies to outbound cases only — the API rejects a closure from the receiving company.
Connection configuration: client id, secret, and the environment URI (capped at 400 characters). Edited through the Connection Settings canvas app.
The declarative field-mapping configuration — see below. This is the table that makes the connector reconfigurable without code.
Integration logging. The first place to look when a sync cycle or a plugin step misbehaves.
Four option sets ship alongside: ap_direction, ap_priorities, ap_tsaresponsetypes and ap_sourcesystem. Because these are ordinary Dataverse tables, they carry standard views, are reportable, and obey your environment's security model — a TSANET User security role granting access to the case, note and response tables ships with the solution.
To surface collaborations against something other than the standard Case, add the TSANet tables to your own unmanaged solution, create a lookup from your table to ap_tsanetcase, and drop a subgrid on the form with Show related records enabled. Nothing in the managed solution needs changing.
Authentication
Credentials live in ap_tsanetsetting and are entered through the TSANET Configuration app: a client id, a secret, and the environment URI. A given environment uses either OAuth2 or a bearer token — not both, and not a fallback from one to the other. Picking the wrong one for the credentials TSANet issued you is a common first-install failure. The API page documents two schemes — OAuth 2.0 client credentials, the current path, and the legacy POST /v1/login JWT; how the solution's Bearer mode maps onto those has not been verified against the solution source.
membership@tsanet.org.Case Mapping
This is the connector's distinguishing feature. Rather than editing a flow to change which TSANet field lands on which Dynamics column, you create records in ap_casemapping. Three mapping types cover the three places a mapping is needed:
| Mapping type | What it drives |
|---|---|
| Response Form | Prefilling the form an agent sees when responding to an inbound case |
| Case Create | Building the Dynamics Case created when a collaboration is accepted |
| TSA Case default prefill | Seeding a new outbound collaboration from the originating record |
Automation
Three environment variables toggle the automatic behaviours, so a member can adopt them one at a time rather than all at once.
With Auto Routing of New Case enabled, an arriving collaboration tries to attach itself to work that already exists before creating anything new:
Synchronisation
The solution ships with scheduled Power Automate flows that poll the Connect API on a 15-minute interval, retrieving case status and creating inbound cases, responses and notes. Agents can force an update from the main navigation rather than waiting for the next cycle.
Near-real-time delivery is opt-in: the Register webhook button in the configuration app points TSANet at a Power Automate endpoint so case and note events arrive as they happen. Registering it does not retire the schedule — the poll remains the backstop, the same belt-and-braces arrangement Salesforce and Fin / Intercom use; Zendesk's poller runs only while an agent has a tab open.
The registration is on the current webhook API: the flow behind the button subscribes on /v2/webhooks with prefixed CloudEvents types. Two details worth knowing. First, the subscription covers case creation and new notes only — responses and closures arrive with the next poll, so a case that seems slow to update after the partner acts is the schedule at work, not a fault. Second, the endpoint flow never branches on the event-type string: it validates the secret, reads the token from either payload shape, and fetches the case, which makes it immune to the bare-versus-prefixed no-op trap that catches consumers that match type strings.
| Path | Latency | Setup |
|---|---|---|
| Scheduled flow | Up to 15 minutes | Ships enabled — nothing to configure |
| Registered webhook | Near-real-time | One button in the configuration app |
| Manual refresh | Immediate | Available to agents from the nav |
Setup
membership@tsanet.orgmake.powerapps.com, select the target environment and run Import Solutionadmin.powerplatform.microsoft.comLimits & gotchas
ap_formjson caps at 200,000 characters. Large process forms with many fields and long option lists are the realistic way to approach it.Accept: application/problem+json, and there is no idempotency key on create — a retried create is a second case. Both on Working with the API.ap_tsanetlog first when something silently fails — it is the integration's own log table.