draft-outreach
skill✓Generates personalized outreach messages by pulling context from Dataverse records. Creates tailored emails for new prospects, re-engagement, follow-ups, or cross-sell. Use when user says "draft an email to [contact]", "write outreach for", "help me reach out to", "compose email", "re-engage this contact", "follow-up email", "prospecting email", or "outreach message for".
apm::install
apm install @microsoft/draft-outreachapm::skill.md
---
name: draft-outreach
description: Generates personalized outreach messages by pulling context from Dataverse records. Creates tailored emails for new prospects, re-engagement, follow-ups, or cross-sell. Use when user says "draft an email to [contact]", "write outreach for", "help me reach out to", "compose email", "re-engage this contact", "follow-up email", "prospecting email", or "outreach message for".
metadata:
author: Dataverse
version: 1.0.0
category: sales-productivity
---
# Draft Outreach
Generic outreach gets ignored. Personalized messages that reference real context — a recent interaction, a known pain point, or a relevant product already owned — get responses. This skill eliminates the blank-page problem by pulling Dataverse data to craft contextually relevant outreach, saving reps time while improving reply rates. It works within Dataverse without requiring external enrichment tools.
## Instructions
### Step 1: Identify Target Contact and Outreach Trigger
Accept input from the user:
- **Target:** Contact name, lead name, or account name
- **Outreach type:** New intro, re-engagement, follow-up, cross-sell, renewal, or event-based
- **Goal:** Meeting request, proposal follow-up, demo invite, check-in, etc.
- **Tone:** Formal, conversational, or brief (default: conversational)
#### Step 2: Retrieve Contact or Lead Record
**If contact:**
```
SELECT contactid, fullname, firstname, jobtitle, accountid, emailaddress1,
telephone1, description, createdon, modifiedon
FROM contact
WHERE fullname LIKE '%[name]%'
```
**If lead:**
```
SELECT leadid, fullname, firstname, jobtitle, companyname, emailaddress1,
telephone1, description, leadsourcecode, leadqualitycode, createdon
FROM lead
WHERE statecode = 0
AND fullname LIKE '%[name]%'
```
Present matches if multiple found. Confirm the target with the user before proceeding.
#### Step 3: Gather Account Context
If a contact was found, retrieve their account:
```
SELECT accountid, name, industrycode, revenue, numberofemployees,
description, address1_city, address1_stateorprovince,
customertypecode, accountcategorycode
FROM account
WHERE accountid = '[accountid]'
```
#### Step 4: Review Relationship History
**Recent activities (last 90 days):**
```
SELECT activityid, activitytypecode, subject, actualend, description,
statecode, regardingobjectid
FROM activitypointer
WHERE regardingobjectid = '[contactid or accountid]'
AND statecode = 1
ORDER BY actualend DESC
```
Limit to 10 most recent. Note:
- Days since last interaction
- Last activity type and topic
- Any commitments made (from description)
**Open opportunities:**
```
SELECT opportunityid, name, estimatedvalue, estimatedclosedate, salesstage,
closeprobability, description, currentsituation, customerneed, customerpainpoints
FROM opportunity
WHERE customerid = '[accountid]'
AND statecode = 0
```
**Recently closed opportunities:**
```
SELECT opportunityid, name, estimatedvalue, actualclosedate, statecode, statuscode
FROM opportunity
WHERE customerid = '[accountid]'
AND statecode IN (1, 2)
AND actualclosedate >= '[90_days_ago]'
```
**Products owned (from won opportunities):**
```
SELECT opportunityproduct.productid, product.name, opportunityproduct.quantity,
opportunityproduct.priceperunit, opportunity.actualclosedate
FROM opportunityproduct
JOIN opportunity ON opportunityproduct.opportunityid = opportunity.opportunityid
JOIN product ON opportunityproduct.productid = product.productid
WHERE opportunity.customerid = '[accountid]'
AND opportunity.statecode = 1
```
#### Step 5: Check Open Cases
```
SELECT incidentid, title, statecode, prioritycode, createdon, description
FROM incident
WHERE customerid = '[accountid]'
AND statecode = 0
ORDER BY prioritycode ASC
```
Flag open cases — they affect tone (avoid aggressive outreach to accounts with open escalations).
#### Step 6: Retrieve Open Tasks Linked to This Contact
```
SELECT taskid, subject, description, scheduledend, statecode
FROM task
WHERE regardingobjectid = '[contactid or accountid]'
AND statecode = 0
ORDER BY scheduledend ASC
```
If any open tasks exist for this contact, confirm outreach aligns with existing follow-up plan.
#### Step 7: Determine Personalization Signals
Based on gathered context, identify the strongest personalization hooks ranked by specificity:
**Tier 1 (most specific — use if available):**
- Last call/meeting topic referenced by subject or description
- Pain point mentioned in opportunity customerpainpoints
- Commitment made in prior activity (action item)
- Product recently purchased — now cross-sell opportunity
**Tier 2 (account-level):**
- Industry-specific context (manufacturing, financial services, healthcare)
- Company growth signals (employee count, revenue)
- Active opportunity stage and deal context
**Tier 3 (generic fallback):**
- Account category (prospect, customer, partner)
- Time since last interaction
- Lead source (inbound vs outbound)
#### Step 8: Generate Outreach Draft
**Select template based on outreach type:**
---
**New Intro:**
> Subject: [Company] + [Your Company] — [value proposition in 5 words]
>
> Hi [Firstname],
>
> I came across [Account Name] while [researching [industry] leaders / reviewing your profile] and noticed [specific detail from account description or industry].
>
> We help [industry] companies [key value prop relevant to their industry]. [Reference a peer company result if available in Dataverse notes].
>
> Would a 20-minute call make sense to explore if there's a fit? Happy to work around your schedule.
>
> Best,
> [Rep Name]
---
**Re-engagement (contact gone quiet):**
> Subject: Re: [Last activity subject] — checking back in
>
> Hi [Firstname],
>
> It's been [n weeks] since we last connected about [last activity subject]. I wanted to check back in — [reference the context from last interaction].
>
> [If open case exists:] I also noticed there's an open [issue] — I've looped in our support team to make sure it's resolved quickly.
>
> Are you still evaluating [solution/need from opportunity]? Happy to reconnect at your convenience.
>
> Best,
> [Rep Name]
---
**Follow-up (after meeting/call):**
> Subject: Follow-up: [Meeting subject] — [key next step]
>
> Hi [Firstname],
>
> Thanks for your time [yesterday/on [date]]. A few things from our conversation:
>
> - [Key point 1 from activity description]
> - [Key point 2]
> - [Commitment / next step agreed]
>
> As discussed, [action item] — I'll have that to you by [date].
>
> [If BANT gap identified:] Before our next conversation, it would help to understand [budget / decision process / timeline] so I can tailor our next steps appropriately.
>
> Best,
> [Rep Name]
---
**Cross-sell:**
> Subject: [Product already owned] → [New product]: natural next step for [Company]
>
> Hi [Firstname],
>
> Given how you've been using [existing product] since [close date], I wanted to introduce [new product/solution].
>
> Several [industry] customers who started with [existing product] have added [new product] to [specific benefit — e.g., reduce manual work in X process].
>
> Worth a quick call to walk through what it could look like for [Account Name]?
>
> Best,
> [Rep Name]
---
**Tone adjustments:**
- **Formal:** Replace contractions, add full titles, longer sentences
- **Brief:** 3 sentences maximum, single CTA
- **Conversational:** Default as shown above
#### Step 9: Create Email Activity in Dataverse
After generating the draft, offer to create an email activity record:
```
Use create_record tool with tablename: email
- subject: [Generated subject line]
- description: [Draft body text]
- regardingobjectid: [Opportunity ID or Account ID]
- directioncode: true (outgoing)
- statecode: 0 (draft / open)
- to: [Contact's activityparty reference]
- from: [Current user systemuser reference]
```
Note: Email is saved as a draft (statecode = 0). Rep reviews and sends from Dynamics 365 or Outlook.
#### Step 10: Provide Sending Guidance
Along with the draft, provide:
**Personalization highlights used:**
- Which Tier 1/2/3 signals were incorporated and why
**Suggested timing:**
- If contact was active recently (<14 days): send today
- If contact has gone quiet (>30 days): consider calling first
- If open escalated case: wait for resolution before outreach
**Follow-up cadence suggestion:**
- If no reply in 3 days: follow up once
- If no reply after 2 attempts: assign a task for manager review or route to nurture
### Output Format
Provide:
1. **Subject line options** (2-3 variants from short to descriptive)
2. **Email draft** (full body, personalization signals highlighted)
3. **Sending notes** (timing, tone rationale, cautions)
4. **Draft saved confirmation** (Dataverse email record ID if created)
### Example Interaction
**User Input:**
"Draft a re-engagement email for Emily Torres at Fabrikam. We haven't talked in 18 days."
**Skill Output:**
✉️ **Draft Outreach — Re-engagement | Emily Torres, Fabrikam**
**Personalization used:**
- Last interaction: "QBR discussion" — 18 days ago (Tier 1)
- Open deal: Fabrikam Cloud Migration — $85,000, Propose stage (Tier 2)
- Open case: API integration timeout errors (flag — acknowledge)
---
**Subject options:**
1. Checking in: Cloud Migration timeline — Fabrikam
2. Quick follow-up from our last call, Emily
3. Fabrikam Cloud Migration — next steps?
**Draft:**
> Hi Emily,
>
> It's been a few weeks since we spoke about the cloud migration. I wanted to check back in — has anything changed with your timeline or the decision process on your end?
>
> I also wanted to acknowledge the API timeout issue that came in — our team is working to resolve it and I'll make sure you have an update by end of this week.
>
> If it helps, I can put together a revised proposal addressing the questions that came up in our last conversation. Would 20 minutes work later this week?
>
> Best,
> Sarah
---
**Sending notes:**
- ⚠️ Open support case — acknowledge it early as shown; don't lead with the pitch
- Confirm case resolution status with support before sending if possible
- If no reply in 3 business days, follow up with a call (not another email)
**Draft saved:** Email activity created in Dataverse (ID: `email-xxx`) — linked to Fabrikam Cloud Migration opportunity. Ready to review and send.
### Dataverse Tables Used
| Table | Purpose |
|-------|---------|
| `contact` | Target contact details |
| `lead` | Target lead details |
| `account` | Account context and firmographics |
| `activitypointer` | Relationship history |
| `opportunity` | Open and closed deal context |
| `opportunityproduct` | Products owned for cross-sell |
| `product` | Product names |
| `incident` | Open support cases |
| `task` | Open follow-up commitments |
| `email` | Save outreach draft as email activity |
### Key Fields Reference
**email:**
- `subject` (NVARCHAR 200) - Email subject line
- `description` (MULTILINE TEXT) - Email body
- `directioncode` (BIT) - Outgoing(1), Incoming(0)
- `statecode` (STATE) - Draft/Open(0), Completed/Sent(1), Canceled(2)
- `regardingobjectid` (LOOKUP) - Linked opportunity, account, or contact
- `scheduledstart` (DATETIME) - Planned send time
**contact:**
- `firstname` (NVARCHAR) - For personalized salutation
- `jobtitle` (NVARCHAR) - For context and tone calibration
- `emailaddress1` (EMAIL) - Primary email
- `description` (MULTILINE TEXT) - Notes and background
### Configurable Parameters
- Default tone (formal, conversational, brief)
- Re-engagement threshold days (default: 14 days without activity)
- Cross-sell trigger (days since last purchase, default: 30 days)
- Follow-up cadence (default: 3 business days)
- Case severity threshold that pauses outreach (default: Priority 1 escalations)
## Examples
### Example 1: New Prospect Introduction
**User says:** "Draft an intro email to Sarah Chen at Northwind"
**Actions:**
1. Query contact record for Sarah Chen
2. Retrieve Northwind account context (industry, size)
3. Check for any existing activities or opportunities
4. Generate personalized intro email
**Result:**
```
To: sarah.chen@northwind.com
Subject: Quick thought on Northwind's supply chain initiative
Hi Sarah,
I noticed Northwind recently expanded into the Midwest market —
congratulations on the growth.
We've helped similar distribution companies reduce order
processing time by 40% while scaling operations.
Would you have 15 minutes this week to explore if there's a fit?
Best,
Mike
---
Sending notes:
• Personalized with company expansion context
• Follow up in 3 days if no reply
```
### Example 2: Re-engagement Email
**User says:** "Help me reach out to James at Fabrikam again"
**Actions:**
1. Query contact and account records
2. Review last interaction date and context
3. Check for open opportunities or past purchases
4. Generate re-engagement email referencing history
**Result:**
```
To: james.wilson@fabrikam.com
Subject: Following up on our cloud migration conversation
Hi James,
It's been a few weeks since we discussed your Q2 cloud
migration goals. I wanted to check in — has the internal
budget review wrapped up?
I have a case study from a similar Financial Services company
that might be relevant to share with your CFO.
Happy to reconnect whenever timing works.
Best,
Sarah
---
Context used:
• Last contact: 18 days ago (demo call)
• Open opp: Cloud Migration ($85K)
• Stage: Proposal sent, awaiting budget approval
```
### Example 3: Cross-sell Outreach
**User says:** "Compose a cross-sell email to Alpine Ski House"
**Actions:**
1. Query account and identify primary contact
2. Review products already owned
3. Identify complementary products
4. Generate cross-sell email with value prop
**Result:**
```
To: lisa.park@alpineskihouse.com
Subject: Maximize your CRM investment with Analytics
Hi Lisa,
Congratulations on 6 months with our CRM platform — your
team's adoption rate is impressive.
Many customers at your stage add our Analytics module to get
deeper visibility into sales performance. Based on your 200+
open opportunities, you'd likely see immediate value.
Want me to set up a 20-minute demo?
Best,
Mike
---
Cross-sell context:
• Purchased: CRM Platform ($42K) 6 months ago
• Suggested: Analytics Module ($15K)
• Open support cases: 0 (safe to approach)
```
## Troubleshooting
### Error: Contact not found
**Cause:** Name doesn't match any contact record, or contact is inactive
**Solution:**
- Search with partial name or company
- Check lead table if contact not found
- Present multiple matches for user selection
### Error: No relationship history available
**Cause:** New contact with no activities or opportunities
**Solution:**
- Generate cold outreach template
- Use account-level context if available
- Note that intro is cold (no prior relationship)
### Error: Open support case blocks outreach
**Cause:** Contact has active Priority 1 escalation
**Solution:**
- Alert user about open case
- Suggest acknowledging case in email
- Recommend waiting for resolution before sales outreach