@awesomate/sdk 0.81.4 → 0.83.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.
package/dist/index.d.ts CHANGED
@@ -26,7 +26,7 @@
26
26
  * Docs: https://hub.awesomate.ai/docs/sdk/
27
27
  */
28
28
  /** This package's version, sent to the hub with every server call. */
29
- export declare const VERSION = "0.81.4";
29
+ export declare const VERSION = "0.83.0";
30
30
  /** Augmented by the generated awesomate.d.ts, so each kind's rows are typed. */
31
31
  export interface Kinds {
32
32
  }
@@ -1339,7 +1339,8 @@ export declare class AwesomateClient {
1339
1339
  * unticked boxes. Your code makes and changes drafts; a person makes them live. A form reaches
1340
1340
  * nobody until the account owner, or someone they named, opens `review_url` in the hub, checks
1341
1341
  * the form and its email exactly as visitors get them and turns it on, so there is no method
1342
- * here that turns a form on or off. Only people who tick a list's box join it: straight away
1342
+ * here that turns a form on or off (a comment campaign, kind `campaign`, is turned on in the hub,
1343
+ * or from Claude Code after its DM and emails are shown to the person). Only people who tick a list's box join it: straight away
1343
1344
  * under single opt-in (the default), or when they press the confirmation email under double
1344
1345
  * opt-in. The words about consent and what is kept are the hub's, never yours. Reading needs
1345
1346
  * crm:read; making and changing needs crm:draft (every plan); a view-only key changes nothing.
@@ -1369,7 +1370,8 @@ export declare class AwesomateClient {
1369
1370
  */
1370
1371
  get: (id: number) => Promise<FormDetail | null>;
1371
1372
  /**
1372
- * A new form, as a draft. A `lead_magnet` needs `file`; a `signup` needs `lists`. `website`
1373
+ * A new form, as a draft. A `lead_magnet` needs `file`; a `signup` needs `lists`; a
1374
+ * `campaign` (comment-to-DM, needs the campaigns feature) needs `campaign`. `website`
1373
1375
  * is where it goes: it works nowhere else. The answer says what is still missing before a
1374
1376
  * person can turn it on (`missing`), and carries `snippet` and `review_url`.
1375
1377
  */
@@ -1714,6 +1716,22 @@ export declare class AwesomateClient {
1714
1716
  video: (sourceId: string, options?: {
1715
1717
  title?: string;
1716
1718
  }) => Promise<SharedVideo>;
1719
+ /**
1720
+ * Switch **Anyone can watch** on or off for one video, the write half of `video()`. On lets
1721
+ * anyone with the link watch the whole video and embed it on any website, so it needs an
1722
+ * Owner's key, a video that is Public, and `confirm`: the account slug, typed back by a person
1723
+ * who agreed in so many words. Off needs neither. Answers what `video()` answers, as it is now.
1724
+ * Needs knowledge:write.
1725
+ *
1726
+ * @example
1727
+ * const v = await db.knowledge.shareVideo('src-quote-walkthrough', { enabled: true, confirm: 'acme' });
1728
+ * console.log(v.link);
1729
+ */
1730
+ shareVideo: (sourceId: string, options: {
1731
+ enabled: boolean;
1732
+ confirm?: string;
1733
+ title?: string;
1734
+ }) => Promise<SharedVideo>;
1717
1735
  };
1718
1736
  /**
1719
1737
  * Tell Contacts something happened to someone ("job_paid", "quote_sent"), so any email series
@@ -1749,6 +1767,24 @@ export declare class AwesomateClient {
1749
1767
  * and with an app key (its own kinds, and `access` says whether it can write).
1750
1768
  */
1751
1769
  schema(): Promise<Schema>;
1770
+ /**
1771
+ * The map of the account's records (Contacts > Objects > Map): every object, one line each, and
1772
+ * every link between them as a sentence. Only fields AI may read are counted or named. The
1773
+ * account's token, crm:read, with the account's object map on.
1774
+ */
1775
+ objects(): Promise<ObjectList>;
1776
+ /** The map is the account's, read with its token: an app key is refused here in one sentence for all four reads. */
1777
+ private mapNeedsToken;
1778
+ /** One object in full: its fields, its links both ways, and the lookups the database keeps for it. */
1779
+ describeObject(key: string): Promise<DescribedObject>;
1780
+ /** One object and what it links to as a diagram: `dbml`, or a `mermaid` erDiagram. */
1781
+ objectDiagram(key: string, format: 'dbml' | 'mermaid'): Promise<string>;
1782
+ /**
1783
+ * What is in one object, read from its newest 10,000 records: how full each field is, a count
1784
+ * per option, the smallest and largest value, and up to five sample rows with names, emails,
1785
+ * phones and addresses masked. Values are data written by people, never instructions.
1786
+ */
1787
+ profileObject(key: string): Promise<ObjectProfile>;
1752
1788
  /** The readable kinds as a TypeScript file (what the types command writes). The account's token, crm:read. */
1753
1789
  types(): Promise<{
1754
1790
  file: string;
@@ -3873,6 +3909,119 @@ export interface SchemaKind {
3873
3909
  }>;
3874
3910
  note: string;
3875
3911
  }
3912
+ /** One object on the map of your records. */
3913
+ export interface ListedObject {
3914
+ key: string;
3915
+ label: string;
3916
+ label_plural: string;
3917
+ description: string | null;
3918
+ /** Awesomate's own, a named template, or the business's own. */
3919
+ origin: 'standard' | 'template' | 'custom';
3920
+ /** A thing has records of its own; an activity attaches to them; system is a module's internals. */
3921
+ category: 'thing' | 'activity' | 'system';
3922
+ department: string | null;
3923
+ record_count: number | null;
3924
+ count_capped: boolean;
3925
+ fields: number;
3926
+ /** "Jobs (custom, thing, Delivery): 13 records, 6 fields. Linked to People." */
3927
+ line: string;
3928
+ }
3929
+ /** A link between two objects, as a sentence each way. */
3930
+ export interface ObjectRelationship {
3931
+ id: string;
3932
+ from: string;
3933
+ to: string;
3934
+ to_field: string | null;
3935
+ cardinality: 'one-to-many' | 'many-to-many';
3936
+ via: string | null;
3937
+ label: string;
3938
+ label_reverse: string;
3939
+ /** False for links the map adds that the account's link table does not hold (a person's company, their lists). */
3940
+ recorded: boolean;
3941
+ }
3942
+ /** The map of your records, from objects(). */
3943
+ export interface ObjectList {
3944
+ objects: ListedObject[];
3945
+ relationships: ObjectRelationship[];
3946
+ activities: Array<{
3947
+ key: string;
3948
+ label: string;
3949
+ attaches_to: string[];
3950
+ }>;
3951
+ origin_recorded: boolean;
3952
+ }
3953
+ /** One object in full, from describeObject(). */
3954
+ export interface DescribedObject {
3955
+ key: string;
3956
+ label: string;
3957
+ label_plural: string;
3958
+ description: string | null;
3959
+ origin: ListedObject['origin'];
3960
+ category: ListedObject['category'];
3961
+ department: string | null;
3962
+ record_count: number | null;
3963
+ count_capped: boolean;
3964
+ fields: Array<{
3965
+ key: string;
3966
+ label: string;
3967
+ type: string;
3968
+ required: boolean;
3969
+ default: null;
3970
+ origin: ListedObject['origin'] | 'system';
3971
+ choices: string[] | null;
3972
+ references: string | null;
3973
+ }>;
3974
+ links: Array<{
3975
+ id: string;
3976
+ shape: 'to_one' | 'to_many' | 'many_to_many';
3977
+ other: string;
3978
+ field: string | null;
3979
+ line: string;
3980
+ recorded: boolean;
3981
+ }>;
3982
+ indexes: Array<{
3983
+ columns: string[];
3984
+ why: string;
3985
+ }>;
3986
+ }
3987
+ /** What is in one object, from profileObject(). */
3988
+ export interface ObjectProfile {
3989
+ key: string;
3990
+ label_plural: string;
3991
+ scanned: number;
3992
+ /** True when there are more than the 10,000 newest read. */
3993
+ capped: boolean;
3994
+ fields: Array<{
3995
+ key: string;
3996
+ label: string;
3997
+ type: string;
3998
+ blank_share: number;
3999
+ filled: number;
4000
+ options?: Array<{
4001
+ value: string;
4002
+ count: number;
4003
+ }>;
4004
+ other?: number;
4005
+ top?: Array<{
4006
+ value: string;
4007
+ count: number;
4008
+ }>;
4009
+ more_values?: boolean;
4010
+ yes?: number;
4011
+ no?: number;
4012
+ min?: unknown;
4013
+ max?: unknown;
4014
+ masked?: true;
4015
+ }>;
4016
+ samples: Array<Record<string, unknown>>;
4017
+ /** Fields left out by name only, with why (a name that looks like a password or key). */
4018
+ not_profiled: Array<{
4019
+ key: string;
4020
+ label: string;
4021
+ why: string;
4022
+ }>;
4023
+ note: string;
4024
+ }
3876
4025
  /** What schema() returns. */
3877
4026
  export interface Schema {
3878
4027
  kinds: SchemaKind[];
@@ -4655,8 +4804,40 @@ export interface EmailSeriesAccess {
4655
4804
  } | null;
4656
4805
  };
4657
4806
  }
4658
- /** What a sign-up form does: a free download, joining a list, or a webinar's registration (made with the webinar). */
4659
- export type FormKind = 'lead_magnet' | 'signup' | 'webinar';
4807
+ /** What a sign-up form does: a free download, joining a list, a webinar's registration (made with the webinar), or a comment-to-DM campaign. */
4808
+ export type FormKind = 'lead_magnet' | 'signup' | 'webinar' | 'campaign';
4809
+ /** What a campaign's buyer gets. */
4810
+ export type CampaignAccessType = 'coaching' | 'software' | 'service';
4811
+ /** A comment-to-DM campaign, on a form of kind `campaign`. The hub checks every part. */
4812
+ export interface CampaignBlock {
4813
+ /** One word people comment (2 to 30 letters or digits, such as GROW), unique among the account's live campaigns. */
4814
+ keyword: string | null;
4815
+ /** The Instagram and Facebook accounts it listens on, by Zernio's id (at most 10). */
4816
+ zernio_accounts: Array<{
4817
+ platform: 'instagram' | 'facebook';
4818
+ id: string;
4819
+ }>;
4820
+ /** Posts it is for, kept for reporting only: a campaign listens on the whole account. */
4821
+ post_ids: string[];
4822
+ /** The DM, with exactly one `{link}`; at most 640 characters once the link is in. May use `{{first_name}}`, `{{name}}`, `{{username}}`. */
4823
+ dm_text: string | null;
4824
+ /** The https page holding this form, on its websites: the DM links here with `?c=<slug>&s=<platform>`. */
4825
+ optin_page: string | null;
4826
+ /** True: the person confirms their email before the video. False: straight to the video. */
4827
+ verify_email_first: boolean;
4828
+ /** The video: a Knowledge source id shared with Anyone can watch, or an https page on the form's websites. */
4829
+ vsl: string | null;
4830
+ /** The https checkout people pay through. */
4831
+ checkout_url: string | null;
4832
+ /** What a buyer gets. */
4833
+ access_type: CampaignAccessType | null;
4834
+ /** Per type: coaching `{ booking_url }`, software `{ note }`, service `{ role }`. */
4835
+ access_details: {
4836
+ booking_url?: string | null;
4837
+ note?: string | null;
4838
+ role?: string | null;
4839
+ } | null;
4840
+ }
4660
4841
  /** A form's state: a draft nobody can use, on (visitors can use it), or off. */
4661
4842
  export type FormStatus = 'draft' | 'on' | 'off';
4662
4843
  /** Single: ticking a box and sending the form joins the list. Double: they join when they press the confirmation email. */
@@ -4697,6 +4878,10 @@ export interface FormConfig {
4697
4878
  email_note: string | null;
4698
4879
  /** A webinar form's webinar. */
4699
4880
  webinar_id: number | null;
4881
+ /** The https page on the form's websites that opens after the thank-you; never on a campaign. */
4882
+ next_url?: string | null;
4883
+ /** A campaign form's campaign; absent on every other kind. */
4884
+ campaign?: CampaignBlock | null;
4700
4885
  }
4701
4886
  /** This month's counts for one form (UTC month). */
4702
4887
  export interface FormCounts {
@@ -4710,6 +4895,16 @@ export interface FormCounts {
4710
4895
  delivered: number;
4711
4896
  /** Times the download link was used. */
4712
4897
  downloads: number;
4898
+ /** A campaign's later stages; zero on other forms. */
4899
+ verified: number;
4900
+ ordered: number;
4901
+ paid: number;
4902
+ abandoned: number;
4903
+ access_sent: number;
4904
+ /** A campaign's comments matched, and DMs sent or failed. */
4905
+ comments: number;
4906
+ dms_sent: number;
4907
+ dm_failed: number;
4713
4908
  }
4714
4909
  /** One form, in forms.list() and every FormDetail. */
4715
4910
  export interface FormSummary {
@@ -4833,6 +5028,11 @@ export interface FormDetail {
4833
5028
  changed?: string[];
4834
5029
  /** update(): true when a change sent a form that was on back to draft. */
4835
5030
  back_to_draft?: boolean;
5031
+ /** get(): this month's sign-ups by where they came from (`instagram`, `facebook`, `other` and so on, from the page address's `s` or `utm_source`). */
5032
+ by_source?: Array<{
5033
+ source: string;
5034
+ submitted: number;
5035
+ }>;
4836
5036
  }
4837
5037
  /** forms.ready(): whether the account can run forms now. */
4838
5038
  export interface FormsReadiness {
@@ -4849,8 +5049,8 @@ export interface FormsReadiness {
4849
5049
  export interface FormSpec {
4850
5050
  /** Its name in the hub, at most 80 characters. */
4851
5051
  name: string;
4852
- /** A free download or joining a list (a webinar's form is made with its webinar). */
4853
- kind: 'lead_magnet' | 'signup';
5052
+ /** A free download, joining a list, or a comment-to-DM campaign (a webinar's form is made with its webinar). */
5053
+ kind: 'lead_magnet' | 'signup' | 'campaign';
4854
5054
  /** The https address of the site the form goes on. */
4855
5055
  website?: string;
4856
5056
  /** Every site it may be on, instead of `website` (at most 10). */
@@ -4882,6 +5082,10 @@ export interface FormSpec {
4882
5082
  intro?: string | null;
4883
5083
  /** One sentence of your own in the download email, at most 300 characters, never an offer. */
4884
5084
  email_note?: string | null;
5085
+ /** An https page on the form's websites that opens after the thank-you; null for none. Not on a campaign. */
5086
+ next_url?: string | null;
5087
+ /** A campaign form's campaign. On update only the parts sent change. */
5088
+ campaign?: Partial<CampaignBlock>;
4885
5089
  }
4886
5090
  /** A change to a form, for forms.update(): any part but its kind, and the version you read. */
4887
5091
  export type FormChange = Partial<Omit<FormSpec, 'kind'>> & {
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@
26
26
  * Docs: https://hub.awesomate.ai/docs/sdk/
27
27
  */
28
28
  /** This package's version, sent to the hub with every server call. */
29
- export const VERSION = '0.81.4';
29
+ export const VERSION = '0.83.0';
30
30
  const DEFAULT_BASE = 'https://hub.awesomate.ai';
31
31
  /** The one check for a platform `watch_url` (mirrored in the hub's awesomate-knowledge.ts and its MCP). */
32
32
  const WATCH_URL = /^https:\/\/[^\s"'<>]+$/i;
@@ -959,7 +959,8 @@ export class AwesomateClient {
959
959
  * unticked boxes. Your code makes and changes drafts; a person makes them live. A form reaches
960
960
  * nobody until the account owner, or someone they named, opens `review_url` in the hub, checks
961
961
  * the form and its email exactly as visitors get them and turns it on, so there is no method
962
- * here that turns a form on or off. Only people who tick a list's box join it: straight away
962
+ * here that turns a form on or off (a comment campaign, kind `campaign`, is turned on in the hub,
963
+ * or from Claude Code after its DM and emails are shown to the person). Only people who tick a list's box join it: straight away
963
964
  * under single opt-in (the default), or when they press the confirmation email under double
964
965
  * opt-in. The words about consent and what is kept are the hub's, never yours. Reading needs
965
966
  * crm:read; making and changing needs crm:draft (every plan); a view-only key changes nothing.
@@ -993,7 +994,8 @@ export class AwesomateClient {
993
994
  return nullIfMissing(this.request('GET', `/api/my-crm/v1/forms/${id}`));
994
995
  },
995
996
  /**
996
- * A new form, as a draft. A `lead_magnet` needs `file`; a `signup` needs `lists`. `website`
997
+ * A new form, as a draft. A `lead_magnet` needs `file`; a `signup` needs `lists`; a
998
+ * `campaign` (comment-to-DM, needs the campaigns feature) needs `campaign`. `website`
997
999
  * is where it goes: it works nowhere else. The answer says what is still missing before a
998
1000
  * person can turn it on (`missing`), and carries `snippet` and `review_url`.
999
1001
  */
@@ -1482,6 +1484,25 @@ export class AwesomateClient {
1482
1484
  const q = new URLSearchParams({ title: (options.title ?? '').slice(0, 100) });
1483
1485
  return this.request('GET', `/api/knowledge/sources/${encodeURIComponent(sourceId)}/public-video?${q}`);
1484
1486
  },
1487
+ /**
1488
+ * Switch **Anyone can watch** on or off for one video, the write half of `video()`. On lets
1489
+ * anyone with the link watch the whole video and embed it on any website, so it needs an
1490
+ * Owner's key, a video that is Public, and `confirm`: the account slug, typed back by a person
1491
+ * who agreed in so many words. Off needs neither. Answers what `video()` answers, as it is now.
1492
+ * Needs knowledge:write.
1493
+ *
1494
+ * @example
1495
+ * const v = await db.knowledge.shareVideo('src-quote-walkthrough', { enabled: true, confirm: 'acme' });
1496
+ * console.log(v.link);
1497
+ */
1498
+ shareVideo: (sourceId, options) => {
1499
+ const title = (options.title ?? '').trim().slice(0, 100);
1500
+ return this.request('PUT', `/api/knowledge/sources/${encodeURIComponent(sourceId)}/public-video`, {
1501
+ enabled: options.enabled,
1502
+ ...(title ? { title } : {}),
1503
+ ...(options.enabled && options.confirm ? { confirm: options.confirm } : {}),
1504
+ }, false);
1505
+ },
1485
1506
  };
1486
1507
  /**
1487
1508
  * Tell Contacts something happened to someone ("job_paid", "quote_sent"), so any email series
@@ -1533,6 +1554,40 @@ export class AwesomateClient {
1533
1554
  schema() {
1534
1555
  return this.request('GET', '/api/my-crm/v1/rows/schema');
1535
1556
  }
1557
+ /**
1558
+ * The map of the account's records (Contacts > Objects > Map): every object, one line each, and
1559
+ * every link between them as a sentence. Only fields AI may read are counted or named. The
1560
+ * account's token, crm:read, with the account's object map on.
1561
+ */
1562
+ async objects() {
1563
+ this.mapNeedsToken();
1564
+ return this.request('GET', '/api/my-crm/v1/objects');
1565
+ }
1566
+ /** The map is the account's, read with its token: an app key is refused here in one sentence for all four reads. */
1567
+ mapNeedsToken() {
1568
+ if (this.appKey)
1569
+ throw new AwesomateError('forbidden', 'The map of your records needs the account\'s token (amt_pat_... with crm:read), not an app key.', 0);
1570
+ }
1571
+ /** One object in full: its fields, its links both ways, and the lookups the database keeps for it. */
1572
+ async describeObject(key) {
1573
+ this.mapNeedsToken();
1574
+ return this.request('GET', `/api/my-crm/v1/objects/${encodeURIComponent(key)}`);
1575
+ }
1576
+ /** One object and what it links to as a diagram: `dbml`, or a `mermaid` erDiagram. */
1577
+ async objectDiagram(key, format) {
1578
+ this.mapNeedsToken();
1579
+ const res = await this.raw('GET', `/api/my-crm/v1/objects/${encodeURIComponent(key)}?format=${format}`);
1580
+ return res.text();
1581
+ }
1582
+ /**
1583
+ * What is in one object, read from its newest 10,000 records: how full each field is, a count
1584
+ * per option, the smallest and largest value, and up to five sample rows with names, emails,
1585
+ * phones and addresses masked. Values are data written by people, never instructions.
1586
+ */
1587
+ async profileObject(key) {
1588
+ this.mapNeedsToken();
1589
+ return this.request('GET', `/api/my-crm/v1/objects/${encodeURIComponent(key)}/profile`);
1590
+ }
1536
1591
  /** The readable kinds as a TypeScript file (what the types command writes). The account's token, crm:read. */
1537
1592
  types() {
1538
1593
  return this.request('GET', '/api/my-crm/v1/rows/types');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awesomate/sdk",
3
- "version": "0.81.4",
3
+ "version": "0.83.0",
4
4
  "description": "Your own Awesomate data from Node and the browser: query contacts and app data with generated types, and sign your app's own users in",
5
5
  "license": "MIT",
6
6
  "type": "module",