Sharing & summary digest
| Status | spec โ client-built, no backend work required |
| Owner | Android |
| Depends on | LLM analysis (GET /api/calls/{id}/analysis), Calls API (GET /api/calls/{id}) |
What it doesโ
Turns a completed call's analysis into a clean, shareable text digest โ the Scryon equivalent of a Fathom / Otter "meeting summary" โ that the user can send over WhatsApp, email, or any share target straight from the call detail screen.
The reference layout we're matching:
๐ Pricing discussion with Alex
6 Jun 2026 ยท 38 min ยท with Alex
SUMMARY
Customer asked for revised pricing by Friday and agreed to a follow-up demo.
KEY POINTS
โข Pricing tier is the only remaining blocker
โข Customer wants the 12-month discount reflected
โข Demo locked for Friday 11am
ACTION ITEMS
โ Send revised pricing sheet โ You ยท by 26 Jun
โ Schedule follow-up call โ Alex
DECISIONS
โข Demo will use the new pricing dashboard build
Shared via Scryon
Why it's client-built (not backend)โ
We already return everything the digest needs in the analysis JSON and the call record. There is no new LLM call, no new field, and no new endpoint. The digest is a pure, deterministic transform of data the client already holds, so it lives in the client:
- Zero round-trips โ share works offline once analysis is cached.
- Localisable โ date formats, section headers, and the
Shared via Scryonfooter follow the device locale. - No backend coupling โ the share sheet (WhatsApp / Gmail / SMS) is an OS concern, same seam we drew for action-item intent chips: the backend classifies, the client launches.
If a second platform (iOS, web) ever needs byte-identical output, promote this spec to a backend
shareDigestblock in the analysis JSON. Until then, this doc is the contract โ keep platforms in sync by following it.
Inputsโ
| Digest piece | Source | Field |
|---|---|---|
| Title | GET /api/calls/{id} | title โ fallback analysis.suggestedTitle |
| Date | GET /api/calls/{id} | recordedAt โ fallback createdAt |
| Duration | GET /api/calls/{id} | durationSeconds |
| Counterparty | GET /api/calls/{id} | contactName (omit the with โฆ clause if null) |
SUMMARY line | analysis | oneLineSummary โ fallback first sentence of executiveSummary |
KEY POINTS | analysis | executiveSummaryBullets[].text (cap 5) โ fallback top keyDiscussionPoints[].text |
ACTION ITEMS | analysis | actionItems[] โ title, ownerDisplayName, dueDate, intent |
DECISIONS | analysis | decisions[] |
FOLLOW-UPS (expanded only) | analysis | followUps[] |
TOPICS (expanded only) | analysis | sections[] โ items[].text |
Composition rulesโ
- Section order is fixed: header โ
SUMMARYโKEY POINTSโACTION ITEMSโDECISIONSโ footer. Expanded mode insertsTOPICSafterKEY POINTSandFOLLOW-UPSafterACTION ITEMS. - Drop empty sections entirely โ no "Decisions: none" lines. If only the header and footer survive, fall back to sharing
oneLineSummaryalone. - Action items group by owner (
ownerDisplayName); null-owner items go under anUnassignedgroup, listed last. Render the phone user's own name as You. - Due dates: append
ยท by {dueDate}only whendueDateis present.dueDateis a raw LLM string โ render verbatim, do not attempt to re-parse. - Length cap (compact mode): โค 5 key points, โค 8 action items, โค 4 decisions, each line truncated to ~120 chars with
โฆ. Keeps the message under a single WhatsApp screen. - Never invent. Only render fields the analysis actually returned. Old v1 calls have no
executiveSummaryBulletsโ fall back tokeyDiscussionPoints, then toexecutiveSummary. - Intent glyph (optional polish): prefix an action item with its intent emoji instead of
โwhenintentis set โmeeting ๐,email โ๏ธ,call ๐,message ๐ฌ,reminder โฐ,task โ,none/unset โโ.
Two render targetsโ
The body is identical; only the markup differs.
WhatsApp / generic text/plainโ
WhatsApp honours *bold*. Make headers bold; everything else stays plain:
*๐ Pricing discussion with Alex*
6 Jun 2026 ยท 38 min ยท with Alex
*SUMMARY*
Customer asked for revised pricing by Friday and agreed to a follow-up demo.
*KEY POINTS*
โข Pricing tier is the only remaining blocker
โข Customer wants the 12-month discount reflected
*ACTION ITEMS*
โ Send revised pricing sheet โ You ยท by 26 Jun
โ Schedule follow-up call โ Alex
_Shared via Scryon_
Emailโ
- Subject:
{title} โ call summary(e.g.Pricing discussion with Alex โ call summary). - Body: the same digest without WhatsApp asterisks (plain text), or an HTML version mirroring the structure if the share target accepts
text/html.
Share mechanism (Android, follow-up implementation)โ
No backend involvement โ the digest string is dropped into a standard share intent:
// System share sheet โ WhatsApp, Gmail, SMS, etc. appear automatically
val send = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
putExtra(Intent.EXTRA_SUBJECT, "$title โ call summary")
putExtra(Intent.EXTRA_TEXT, digestPlain) // or digestWhatsApp
}
startActivity(Intent.createChooser(send, "Share summary"))
Direct targets, if the UI offers explicit WhatsApp / email buttons:
// WhatsApp
Uri.parse("https://wa.me/?text=" + Uri.encode(digestWhatsApp))
// Email
Uri.parse("mailto:?subject=" + Uri.encode(subject) + "&body=" + Uri.encode(digestPlain))
What this is NOTโ
- โ Not a new API or LLM call โ it reuses
GET /api/calls/{id}/analysis. - โ Not a backend responsibility (today) โ the server never builds share text or knows the user's installed apps.
- โ Not the full transcript โ it's the summary. Sharing raw transcripts is a separate feature with its own privacy review.
Relatedโ
- LLM analysis โ the schema every field comes from.
- API ยท Analysis โ exact field reference.
- API ยท Action items โ intent vocabulary reused for the action-item glyphs.
- Calls API โ title / date / duration / contact.