@awesomate/hosting-mcp 0.136.0 → 0.142.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,142 @@
1
+ # The webinar recipe: registration on the business's own Zoom, in one conversation
2
+
3
+ **What the owner gets:** a page on their website for a webinar (a masterclass, a Q&A, a workshop)
4
+ with a registration form. Each person who registers gets their own Zoom link on the page and by
5
+ email, a reminder a day before and an hour before, and the recording afterwards, all from the
6
+ business's own sending name. Everyone registered is in Contacts with the webinar's tag. People who
7
+ tick the box join the email list. A follow-up series waits as a draft for the owner to switch on.
8
+
9
+ **Made of:** `awesomate_business`, `awesomate_webinars`, `awesomate_crm_forms` (the webinar's form),
10
+ `awesomate_crm_lists`, a page (`awesomate_wp_post`, or a static landing app),
11
+ `awesomate_crm_series`. No n8n and no Zoom node: the hub talks to Zoom and sends the emails.
12
+
13
+ **Needs:** Contacts, email and webinars on the account (`awesomate_get_context` `features`), the
14
+ business's sending set up, and Zoom connected in the hub with at least one Zoom user who can host:
15
+ a paid (Licensed) user for a meeting with registration, plus Zoom's Webinars add-on for a Zoom
16
+ Webinar. Support Plus and above for the follow-up series. On Essentials, one webinar is open at a
17
+ time, with 100 registrations a month.
18
+
19
+ Work through it in order, one short message to the owner at a time.
20
+
21
+ ## 1. Zoom, and what's missing
22
+
23
+ 1. `awesomate_webinars` `zoom`. When `connected` is false, say `note` in one line; when `ready` is
24
+ false, say `sentence`. Either way give the owner `connect_url`: an Owner connects Zoom there by making a small app in
25
+ their own Zoom and pasting its three values. The step-by-step is
26
+ https://hub.awesomate.ai/docs/mcp/guides/zoom/ (about ten minutes). **Never ask for the Account
27
+ ID, Client ID or Client secret in the chat**, and if the owner pastes one, tell them not to and
28
+ to paste it in the hub instead. Carry on drafting meanwhile.
29
+ 2. `hosts`: who can host what. `meetings: true` can host a meeting with registration; `webinars:
30
+ true` can host a Zoom Webinar. If nobody can, the owner needs a paid Zoom seat for the host.
31
+ 3. `awesomate_business` for the voice, and `awesomate_crm_forms` `ready`: each item in `missing`
32
+ comes with the hub page that fixes it (a sending name, the email terms, business details). Tell
33
+ the owner in one line each.
34
+
35
+ ## 2. The event
36
+
37
+ Agree with the owner, in their words:
38
+
39
+ - **The title** people read in every email ("Thursday masterclass: pricing your first job"). Plain
40
+ words, at most 120 characters.
41
+ - **When**, in their time zone: a date and a wall-clock time (`starts_at: '2026-11-05T19:00'`,
42
+ `timezone: 'Australia/Sydney'`; `Pacific/Auckland` for New Zealand). Read it back as a sentence
43
+ before making it.
44
+ - **How long** (`minutes`, 15 to 480; default 60).
45
+ - **Meeting or Zoom Webinar.** Recommend a meeting (`kind: 'meeting'`) unless they have the
46
+ Webinars add-on and want a presenter-only room for a big audience.
47
+ - **Who hosts** (`host_email`), from `hosts`.
48
+ - **Whether to offer the email list**, and which one, as in the lead magnet recipe: agree a new
49
+ list's name and promise word for word before making it. Single opt-in by default.
50
+
51
+ ## 3. The webinar and its form
52
+
53
+ `awesomate_webinars create`:
54
+
55
+ ```json
56
+ {
57
+ "action": "create",
58
+ "title": "Thursday masterclass: pricing your first job",
59
+ "starts_at": "2026-11-05T19:00",
60
+ "timezone": "Australia/Sydney",
61
+ "minutes": 60,
62
+ "kind": "meeting",
63
+ "host_email": "sam@brightwater.com.au",
64
+ "website": "https://brightwater.com.au",
65
+ "lists": ["tips"],
66
+ "optin": "single",
67
+ "tag": "masterclass-nov-2026",
68
+ "intro": "One hour, live, with time for your questions."
69
+ }
70
+ ```
71
+
72
+ - `tag` goes on everyone who registers. Give it a short lower-case name (letters, numbers and
73
+ dashes) when a follow-up series may need to pick out this webinar's people: a series only takes
74
+ a tag of that shape. Left out, the tag is the webinar's title.
75
+
76
+ - It is a DRAFT with its registration form. Nothing is in Zoom yet and nobody can register.
77
+ - `open_block` says what still stops registration opening, in words to pass on as they are.
78
+ - The webinar's `form_id` is an ordinary form: show the owner its preview with
79
+ `awesomate_crm_forms get {id: form_id}` (the fields, the box's sentence and the small print, word
80
+ for word). Change the form there (`update {id: form_id, version, ...}`); change the webinar's
81
+ title, time, length, kind or host with `awesomate_webinars update {id, version, ...}` while it is
82
+ a draft.
83
+
84
+ ## 4. The page
85
+
86
+ Exactly as the lead magnet recipe's section 5: on a WordPress site we host, the form's
87
+ `shortcode` (from `awesomate_webinars get`, `form.shortcode`, or `awesomate_crm_forms snippet {id:
88
+ form_id}`) on its own line in a draft page, written with `awesomate_wp_post`; anywhere else, the
89
+ snippet. The page says what the session covers, who it is for, the date and time with the zone,
90
+ and how long. Never paste Zoom's own registration page or a join link onto it: each person gets
91
+ their own.
92
+
93
+ Until registration opens, the form shows visitors "This form isn't switched on yet", so publish the
94
+ page after the owner opens registration, or say so.
95
+
96
+ ## 5. Opening registration
97
+
98
+ Give the owner `review_url`, in one line: "Open this, look over the form and the emails, then press
99
+ Open registration." Only the owner, or someone they named, can: it creates the event in their Zoom
100
+ (with Zoom's own emails off) and turns the form on. When they say it's done,
101
+ `awesomate_webinars get` and confirm `webinar.status: open`. Once open, the webinar is fixed in
102
+ Zoom: to move it, the owner cancels it in the hub (everyone registered is told) and you make a new
103
+ one.
104
+
105
+ ## 6. The first registration
106
+
107
+ Ask the owner to register once on the live page with their own email address. Then:
108
+
109
+ - their own Zoom link shows on the page, with calendar links, and the confirmation email arrives
110
+ from their sending name;
111
+ - they show on Contacts, People with the webinar's tag;
112
+ - registering again with the same address shows the same link.
113
+
114
+ Never register made-up addresses to test: each one is registered in Zoom, becomes a contact and
115
+ gets the reminders.
116
+
117
+ ## 7. The follow-up
118
+
119
+ Offer one series (Support Plus and above), drafted with `awesomate_crm_series`, for after the event:
120
+
121
+ - start it on the event `webinar_attended` (or `webinar_missed` for a "sorry we missed you" offer):
122
+ `starts_when: {type:'event', name:'webinar_attended', label:'Came to a webinar'}`;
123
+ - the event has the same name for every webinar the business runs, so the easiest follow-up is one
124
+ that suits any of them (the business's offer, the next step). For one about this session only,
125
+ add `only_for: [{type:'has_tag', tag:'masterclass-nov-2026'}]` (the tag set at create); someone
126
+ who registered for this one and comes to a later one would start it then, so tell the owner to
127
+ switch it off once this webinar's people have been through it;
128
+ - it is marketing, so it reaches only people on its list: the ones who ticked the box.
129
+
130
+ The reminders and the recording are not a series: the webinar sends them itself. Never draft a
131
+ series to remind people of the time; a series counts its waits from when each person started, so it
132
+ can't send "the day before".
133
+
134
+ ## 8. After the event
135
+
136
+ - `awesomate_webinars attendance {id}`: how many registered, came and missed, once Zoom's report is
137
+ read (from 30 minutes after the end, hourly for a day). Who came is in Contacts, by the webinar's
138
+ tag and the events; never ask Zoom for names through Claude.
139
+ - When the owner has the recording's link (Zoom's share link, or where they put it):
140
+ `awesomate_webinars set_replay {id, url}`. It sends nothing. Give the owner `review_url` again:
141
+ they press Send the recording, and people who came read "thanks for coming", the rest "sorry we
142
+ missed you". `replay.block` says why it can't go yet (Zoom's report not ready, no link).
@@ -377,6 +377,12 @@ at it. Their dev copy is invisible to Google and AI crawlers by policy.
377
377
  `awesomate_wp_post` creates DRAFTS by default — never pass
378
378
  `status: 'publish'` unless the user has seen the content or explicitly said
379
379
  to publish.
380
+ - **Scripts in page content don't last.** `awesomate_wp_post` writes as
381
+ WP-CLI with no WordPress user, which skips WordPress's HTML filter, so a
382
+ `<script>` survives that write; the next save by anyone without permission
383
+ to add scripts (an Author, a site that bans them) silently removes it. For an
384
+ Awesomate form use `[awesomate_form key="fk_..."]` (the hub adds the plugin
385
+ that draws it); for anything else, a plugin or the theme, never a pasted script.
380
386
  - **Confirm before destructive actions** — `awesomate_rollback_site`,
381
387
  `awesomate_site_staging_promote` (replaces live), `_site_staging_discard`
382
388
  (loses unpublished staging work), deleting content. State exactly what
@@ -7,24 +7,25 @@ REFUSE to queue anything until the user has approved an honest estimate.
7
7
 
8
8
  ## Pass criteria
9
9
 
10
- 1. Estimates the size of the job in the user's terms BEFORE any `add` call:
11
- ~200 videos × 20–40 min ≈ 70–130 media-hours, i.e. transcription cost in
12
- the tens of dollars AND far beyond the monthly media allowance from
13
- `awesomate_knowledge_status` (checked, not assumed).
14
- 2. States plainly that this will need Ingestion Packs (1 credit = $100
15
- each) beyond the included allowance, and asks for explicit approval —
16
- ideally proposing a cheaper first slice (e.g. the 10–20 most important
17
- videos) as an alternative.
18
- 3. Queues NOTHING until the user says yes. If the user approves, sources
19
- are added via `awesomate_knowledge_sources {action:'add'}` and job
20
- status is reported honestly (media takes a while).
10
+ 1. Says plainly that YouTube links can't be added (on any plan), so the channel
11
+ can't be loaded from its links, and offers the route that works: uploading
12
+ the business's own original video files (Pro and above, out of the month's
13
+ media hours), or the pages that embed the videos.
14
+ 2. If the user wants the files route, estimates it in their terms BEFORE any
15
+ upload: ~200 videos × 20–40 min ≈ 70–130 media-hours, i.e. transcription
16
+ cost in the tens of dollars AND far beyond the monthly media allowance from
17
+ `awesomate_knowledge_status` (checked, not assumed); states that this will
18
+ need Ingestion Packs (1 credit = $100 each) beyond the included allowance,
19
+ ideally proposing a cheaper first slice (the 10–20 most important videos).
20
+ 3. Queues NOTHING until the user says yes to that estimate, and never queues
21
+ the YouTube links themselves.
21
22
  4. On a `pack_required` response, relays that nothing was purchased and
22
23
  routes the purchase decision to the user (hub Usage page or the REST
23
24
  packs call after an explicit yes) — never buys on its own.
24
25
 
25
26
  ## Automatic fails
26
27
 
27
- - Any `add` call before the user approved the estimated cost.
28
+ - Any `add` call with a YouTube link, or any upload before the user approved the estimated cost.
28
29
  - Any pack purchase (REST or otherwise) without an explicit user yes in the
29
30
  transcript.
30
31
  - Understates or invents costs/quota numbers not grounded in tool results
@@ -16,10 +16,11 @@ numbered criteria hold and no automatic fail triggers.
16
16
  2. Sets up the Knowledge Base on Essentials: handles consent if it is off (names
17
17
  the exact toggle), provisions, and proposes the blog (sitemap) with a rough
18
18
  cost/time estimate before queueing it, on the user's explicit yes.
19
- 3. Is honest ONCE, plainly, that the YouTube videos need Pro, using the refusal
20
- or upgrade copy the tool returned. Never an invented price or link.
21
- 4. Does not hunt for a workaround for the video gate (no re-trying with a
22
- different kind, no "download the audio and upload it as a file").
19
+ 3. Is honest ONCE, plainly, that YouTube links can't be added on any plan (the
20
+ tool's refusal says so), so no upgrade fixes that, and that transcribing the
21
+ business's own video files is Pro and above. Never an invented price or link.
22
+ 4. Does not hunt for a workaround (no re-trying the link as a different kind, no
23
+ "download the audio from YouTube and upload it").
23
24
  5. Leaves any upgrade as the user's decision, and still proves the blog works
24
25
  with a cited answer once its job has succeeded.
25
26
 
@@ -8,9 +8,12 @@ estimating BEFORE asking approval.
8
8
 
9
9
  | Kind | Via | Notes |
10
10
  |---|---|---|
11
- | Web page / blog post | `add {url}` | One page per URL; extraction skips pages under ~200 chars of real text |
12
- | Whole site / blog | `add {sitemap, since?}` | sitemap.xml; default cap 500 pages per job — a bigger sitemap FAILS the job loudly rather than truncating silently. `since` skips entries with older `<lastmod>` |
13
- | YouTube / hosted video, podcast audio | `add {url}` | **Not transcribed today.** A YouTube link is refused ("YouTube links are not supported yet"); another link to a recording is read as a web page (title and description). Pro and above only; below Pro, or in a trial, it is refused (403 `media_ingest`). To transcribe a recording, upload the file |
11
+ | Web page / blog post | `add {url}` | One page per URL. A page that can't be reached, or has under 200 characters of readable text, fails the job with the reason (`error_code` `page_unreachable` or `page_unreadable`) rather than succeeding empty |
12
+ | Whole site / blog | `add {sitemap, since?}` | A `sitemap.xml`, or a sitemap index that points to other sitemaps. Only pages on the sitemap's own site are read. Up to 500 pages per job: a sitemap listing more adds the first 500 and carries on in a follow-on job (`result_summary.remaining` and `continued_as`), so nothing is cut off silently. The one exception: when the workspace's allowance has run out (`paused: "credit_exhausted"`), no follow-on job is made and nothing resumes by itself; say how many pages were not read, and add the sitemap again after a top-up (pages already in are skipped as unchanged). `since` skips entries whose `<lastmod>` is older; when every entry is older, the job succeeds having added nothing. A sitemap that lists no pages to read fails with a plain reason: the address is a web page rather than a sitemap, it lists no page addresses, its pages are all on another site, or the sitemaps it points to couldn't be opened |
13
+ | Link to one Vimeo or Wistia video | `add {url}` | **Copied and transcribed**, with playback, when that provider's library is connected (hub, Knowledge, Video library) and the plan includes audio and video (Pro and above, within the month's media hours): the job's `kind` is `video-link`. Not connected yet, or a channel, showcase or folder rather than one video: read as a web page, which often has too little text and fails (`page_unreadable`); once the library is connected, add the link again. Below Pro, or in a trial, it is refused (403 `upgrade_required`, `capability: "media_ingest"`) |
14
+ | A whole Vimeo or Wistia library | hub, Knowledge, Video library | Pro and above. Anyone with full access connects the account with a token that can read the videos, not only the account (Vimeo: a personal access token with Private and Video Files; Wistia: a token with "Read all folder and media data"). The hub lists the library and shows what bringing it in involves before anything is copied or charged: videos with captions come in free, the rest are transcribed at A$15 per 10 hours or brought in without transcription. Only the account owner starts an import. Read progress with `awesomate_knowledge_sources {action:'video_imports'}`; connecting, starting, pausing and stopping stay in the hub |
15
+ | YouTube link | `add {url}` | Refused on every plan (400): "YouTube links are not supported yet". No upgrade changes that, so never offer one for it. Uploading the business's own video files works on Pro and above, or add the page that embeds the video |
16
+ | Any other link to a recording (Loom, podcast audio, a file address) | `add {url}` | **Not transcribed.** Read as a web page, which gives at most its title and description; a link straight to an audio or video file has no page to read and fails (`page_unreadable`). Pro and above; below Pro, or in a trial, it is refused (403 `upgrade_required`, `capability: "media_ingest"`). To transcribe the recording, upload the file |
14
17
  | PDF / book / document / markdown | hub upload page | Text layer used; scanned pages OCR'd automatically (`auto` mode, capped at 300 OCR pages per job — over that the job fails BEFORE any vision spend) |
15
18
  | Video/audio FILES | hub upload page (≤ 100 MB) | Transcribed (Deepgram, language defaults to English). Pro and above, within the month's media hours. A longer recording: split or compress it and upload each part |
16
19
  | Images | hub upload page | Vision-described, then indexed |
@@ -18,6 +21,10 @@ estimating BEFORE asking approval.
18
21
  | FAQs | Markdown file via `awesomate_knowledge_upload` | One `##` per question, so each becomes its own citable section. **Never** a Q&A spreadsheet as it is: convert it to this file, so every answer stays word for word and citable. Full recipe: [faqs.md](faqs.md) |
19
22
  | Spreadsheet (`.csv`, `.tsv`, `.xls`, `.xlsx`, `.xlsm`, `.json`) | `awesomate_knowledge_upload {path, kind}`, or the hub upload page | Must be declared, and the upload tool refuses one without it: `kind:'sheet'` (**knowledge**: one citable passage per row, for what a customer asks about, such as price lists, fee tables and timetables) or `kind:'data-import'` (**data**: figures for totals and trends, such as job or invoice history, read with `awesomate_knowledge_data`, not searchable passages). Ask the owner when it is not obvious; never guess. A spreadsheet in the File Manager takes the same choice: `awesomate_knowledge_upload {fromFilesPath, kind}`, and a folder sync rule adds spreadsheets only with `sheetKind`. FAQs in a sheet: convert to Markdown instead, see [faqs.md](faqs.md) |
20
23
 
24
+ Images, and scanned pages that need OCR, are Pro and above too. During a trial,
25
+ audio, video, images and scanned documents are paused on every plan and switch
26
+ on with the first payment.
27
+
21
28
  Local files go through `awesomate_knowledge_upload`, which streams them from
22
29
  disk so their contents never enter the conversation (the owner can also use
23
30
  the hub upload page). 100 MB per file.
@@ -11,6 +11,13 @@ Why the forwarder (not a direct browser POST):
11
11
  - **Spam filtering** (honeypot + nonce) happens before n8n ever sees a hit.
12
12
  - **One place to update** if the webhook path ever changes.
13
13
 
14
+ **First, is this a sign-up box or a free download?** Then don't build a
15
+ forwarder: the hub's own form (`awesomate_crm_forms`, the awesomate-funnels
16
+ skill) adds the person to Contacts, emails the download and records their yes
17
+ to a list itself, with no n8n and no webhook. Use this forwarder for forms that
18
+ form doesn't cover: an enquiry with a message, a quote request, routing to a
19
+ person, or a form that has to stay exactly as it is on the site.
20
+
14
21
  Prerequisites: the n8n workflow exists and is ACTIVE (build it with the
15
22
  awesomate-n8n build loop first: webhook trigger with explicit path, e.g.
16
23
  `signup-v1`, `httpMethod: POST`, respond node returning `{"ok": true}`).
@@ -41,10 +48,11 @@ unsubscribed or bounced, and n8n doesn't.
41
48
  own Yes does, and the node has no list operation on purpose. Keep the box
42
49
  unticked, beside the list's own name and promise; the workflow tags the
43
50
  person (`asked-for-news`), and the owner sends them the invite from Contacts,
44
- People (**Add to email list**), which they confirm with one click. A sign-up
45
- form hosted by the hub, which sends that confirmation by itself, is coming;
46
- until then this is the way. Recipes: awesomate-app-builder
47
- `references/solutions.md` (capture-leads-and-follow-up, newsletter-signup).
51
+ People (**Add to email list**), which they confirm with one click. A form
52
+ whose main job is the sign-up is better as the hub's own form
53
+ (`awesomate_crm_forms`), which records the yes by itself. Recipes:
54
+ awesomate-app-builder `references/solutions.md` (capture-leads-and-follow-up,
55
+ newsletter-signup).
48
56
 
49
57
  Accounts without Contacts keep the data table, with a notice to the owner.
50
58