@unboundcx/sdk 4.13.20 → 4.13.22
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/package.json +1 -1
- package/services/messaging/SmsService.js +27 -0
- package/services/portals.js +138 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unboundcx/sdk",
|
|
3
|
-
"version": "4.13.
|
|
3
|
+
"version": "4.13.22",
|
|
4
4
|
"description": "Official JavaScript SDK for the Unbound API - A comprehensive toolkit for integrating with Unbound's communication, AI, and data management services",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -17,6 +17,8 @@ export class SmsService {
|
|
|
17
17
|
* @param {Object} [params.variables] - Template variables
|
|
18
18
|
* @param {Array<string>} [params.mediaUrls] - Media URLs for MMS
|
|
19
19
|
* @param {string} [params.webhookUrl] - Webhook URL for delivery status
|
|
20
|
+
* @param {string} [params.relatedId] - Task/engagement (or other record) id
|
|
21
|
+
* to attach this message to, so it surfaces on that record's feed
|
|
20
22
|
* @returns {Promise<Object>} Message details
|
|
21
23
|
*/
|
|
22
24
|
async send({
|
|
@@ -27,6 +29,7 @@ export class SmsService {
|
|
|
27
29
|
variables,
|
|
28
30
|
mediaUrls,
|
|
29
31
|
webhookUrl,
|
|
32
|
+
relatedId,
|
|
30
33
|
}) {
|
|
31
34
|
const messageData = {};
|
|
32
35
|
if (from) messageData.from = from;
|
|
@@ -35,6 +38,7 @@ export class SmsService {
|
|
|
35
38
|
if (variables) messageData.variables = variables;
|
|
36
39
|
if (mediaUrls) messageData.mediaUrls = mediaUrls;
|
|
37
40
|
if (webhookUrl) messageData.webhookUrl = webhookUrl;
|
|
41
|
+
if (relatedId) messageData.relatedId = relatedId;
|
|
38
42
|
|
|
39
43
|
this.sdk.validateParams(
|
|
40
44
|
{ to, ...messageData },
|
|
@@ -46,6 +50,7 @@ export class SmsService {
|
|
|
46
50
|
variables: { type: 'object', required: false },
|
|
47
51
|
mediaUrls: { type: 'array', required: false },
|
|
48
52
|
webhookUrl: { type: 'string', required: false },
|
|
53
|
+
relatedId: { type: 'string', required: false },
|
|
49
54
|
},
|
|
50
55
|
);
|
|
51
56
|
|
|
@@ -73,4 +78,26 @@ export class SmsService {
|
|
|
73
78
|
const result = await internalRequest(this.sdk, `/messaging/sms/${id}`, 'GET');
|
|
74
79
|
return result;
|
|
75
80
|
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* List SMS/MMS messages tied to a task/engagement (or other record) id —
|
|
84
|
+
* feed read path for the contact-center interaction timeline.
|
|
85
|
+
* @param {string} relatedId - Related record id
|
|
86
|
+
* @returns {Promise<Object>} { messages: [...] }
|
|
87
|
+
*/
|
|
88
|
+
async getByRelated(relatedId) {
|
|
89
|
+
this.sdk.validateParams(
|
|
90
|
+
{ relatedId },
|
|
91
|
+
{
|
|
92
|
+
relatedId: { type: 'string', required: true },
|
|
93
|
+
},
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const result = await internalRequest(
|
|
97
|
+
this.sdk,
|
|
98
|
+
`/messaging/sms/related/${relatedId}`,
|
|
99
|
+
'GET',
|
|
100
|
+
);
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
76
103
|
}
|
package/services/portals.js
CHANGED
|
@@ -86,6 +86,26 @@ export class PortalsService {
|
|
|
86
86
|
* @param {string} [updates.name] - New display name for the portal.
|
|
87
87
|
* @param {string} [updates.domain] - New custom domain for the portal.
|
|
88
88
|
* @param {object} [updates.settings] - Updated portal configuration settings.
|
|
89
|
+
* @param {object} [updates.settings.profile] - P11.2: visitor-editable
|
|
90
|
+
* profile fields. `{ people: { enabled, fields: [{ name, editable }] },
|
|
91
|
+
* company: { enabled, fields: [{ name, editable }], editorMode,
|
|
92
|
+
* editorFilter } }`. `fields` (max 40 each) is the allowlist of
|
|
93
|
+
* people/company columns exposed on the portal's `GET /portal-profile` —
|
|
94
|
+
* never system columns (id/*At/*By/isDeleted/recordTypeId), foreign
|
|
95
|
+
* keys, or encrypted fields (the API 400s on save otherwise).
|
|
96
|
+
* `company.editorMode` is `'none'|'all'|'rules'` — whether a signed-in
|
|
97
|
+
* visitor may edit their OWN company record: nobody / everyone signed
|
|
98
|
+
* in / only people matching `editorFilter` (same `{'<field>::<op>':
|
|
99
|
+
* value}` AND-map as `settings.peopleFilter`, ≥1 rule required for
|
|
100
|
+
* `'rules'`). A per-person override (people custom field
|
|
101
|
+
* `portalCompanyEdit__c`, `'allow'|'deny'`, set via `sdk.objects.update`)
|
|
102
|
+
* wins over `editorMode`/`editorFilter` when present.
|
|
103
|
+
* @param {string} [updates.settings.companyTicketsMode] - `'none'|'all'|'rules'`
|
|
104
|
+
* — successor to the legacy `settings.companyTickets` boolean
|
|
105
|
+
* (`true`→`'all'`, `false`→`'none'`); same 3-way shape as
|
|
106
|
+
* `settings.profile.company.editorMode` above, paired with
|
|
107
|
+
* `settings.companyTicketsFilter`. Prefer this over the boolean going
|
|
108
|
+
* forward — both may be sent, `companyTicketsMode` wins.
|
|
89
109
|
* @param {boolean} [updates.isPublic] - Updated public accessibility flag.
|
|
90
110
|
* @param {string} [updates.customCss] - Updated custom CSS for the portal.
|
|
91
111
|
* @param {string} [updates.customJs] - Updated custom JavaScript for the portal.
|
|
@@ -572,16 +592,31 @@ export class PortalsService {
|
|
|
572
592
|
}
|
|
573
593
|
|
|
574
594
|
/**
|
|
575
|
-
* Staff-only portal credential status for a person. Never
|
|
595
|
+
* Staff-only portal credential + access status for a person. Never
|
|
596
|
+
* includes hashes or tokens.
|
|
576
597
|
*
|
|
577
598
|
* @param {string} peopleId
|
|
578
599
|
* @returns {Promise<{
|
|
600
|
+
* status: "none"|"invited"|"active"|"locked",
|
|
579
601
|
* hasPassword: boolean,
|
|
580
602
|
* ssoLinked: boolean,
|
|
581
603
|
* lastLoginAt: string|null,
|
|
582
604
|
* lastLoginMethod: string|null,
|
|
583
|
-
* mustReset: boolean
|
|
584
|
-
*
|
|
605
|
+
* mustReset: boolean,
|
|
606
|
+
* invitedAt: string|null,
|
|
607
|
+
* lockedUntil: string|null,
|
|
608
|
+
* portals: Array<{
|
|
609
|
+
* id: string,
|
|
610
|
+
* name: string,
|
|
611
|
+
* kind: "support"|"partner",
|
|
612
|
+
* hostedDomain: string,
|
|
613
|
+
* domain: string|null,
|
|
614
|
+
* matches: boolean
|
|
615
|
+
* }>
|
|
616
|
+
* }>} `portals` lists only support/partner portals on the account (a
|
|
617
|
+
* portal with no login surface, e.g. `marketing`, is never included);
|
|
618
|
+
* `matches` is whether this person currently passes that portal's
|
|
619
|
+
* people-access filter.
|
|
585
620
|
*/
|
|
586
621
|
async getPeopleAccess(peopleId) {
|
|
587
622
|
this.sdk.validateParams(
|
|
@@ -625,6 +660,106 @@ export class PortalsService {
|
|
|
625
660
|
);
|
|
626
661
|
}
|
|
627
662
|
|
|
663
|
+
/**
|
|
664
|
+
* Invites a person to sign in to a support/partner portal: upserts their
|
|
665
|
+
* portal credential (`mustReset=1`), stamps `invitedAt`/`invitedBy`, and
|
|
666
|
+
* sends the account's `portal-welcome` email with a fresh 30-minute
|
|
667
|
+
* single-use set-password link.
|
|
668
|
+
*
|
|
669
|
+
* The person must pass the target portal's people-access filter — see
|
|
670
|
+
* `getPeopleAccess(peopleId).portals[].matches` — or the call 400s.
|
|
671
|
+
*
|
|
672
|
+
* @param {string} peopleId
|
|
673
|
+
* @param {object} params
|
|
674
|
+
* @param {string} params.portalId - The support/partner portal to invite them to.
|
|
675
|
+
* @returns {Promise<{
|
|
676
|
+
* status: "invited",
|
|
677
|
+
* hasPassword: boolean,
|
|
678
|
+
* ssoLinked: boolean,
|
|
679
|
+
* lastLoginAt: string|null,
|
|
680
|
+
* lastLoginMethod: string|null,
|
|
681
|
+
* mustReset: boolean,
|
|
682
|
+
* invitedAt: string,
|
|
683
|
+
* lockedUntil: string|null
|
|
684
|
+
* }>}
|
|
685
|
+
*/
|
|
686
|
+
async invitePerson(peopleId, { portalId }) {
|
|
687
|
+
this.sdk.validateParams(
|
|
688
|
+
{ peopleId, portalId },
|
|
689
|
+
{
|
|
690
|
+
peopleId: { type: "string", required: true },
|
|
691
|
+
portalId: { type: "string", required: true },
|
|
692
|
+
},
|
|
693
|
+
);
|
|
694
|
+
|
|
695
|
+
return internalRequest(
|
|
696
|
+
this.sdk,
|
|
697
|
+
`/portals/people/${encodeURIComponent(peopleId)}/invite`,
|
|
698
|
+
"POST",
|
|
699
|
+
{ body: { portalId } },
|
|
700
|
+
);
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* Sends a person a fresh password-reset email for a support/partner
|
|
705
|
+
* portal (the account's `portal-password-reset` template) with a new
|
|
706
|
+
* 30-minute single-use set-password link. Works whether they were
|
|
707
|
+
* previously invited or already active.
|
|
708
|
+
*
|
|
709
|
+
* @param {string} peopleId
|
|
710
|
+
* @param {object} params
|
|
711
|
+
* @param {string} params.portalId - The support/partner portal to send the reset for.
|
|
712
|
+
* @returns {Promise<{
|
|
713
|
+
* status: "none"|"invited"|"active"|"locked",
|
|
714
|
+
* hasPassword: boolean,
|
|
715
|
+
* ssoLinked: boolean,
|
|
716
|
+
* lastLoginAt: string|null,
|
|
717
|
+
* lastLoginMethod: string|null,
|
|
718
|
+
* mustReset: boolean,
|
|
719
|
+
* invitedAt: string|null,
|
|
720
|
+
* lockedUntil: string|null
|
|
721
|
+
* }>}
|
|
722
|
+
*/
|
|
723
|
+
async resetPersonPassword(peopleId, { portalId }) {
|
|
724
|
+
this.sdk.validateParams(
|
|
725
|
+
{ peopleId, portalId },
|
|
726
|
+
{
|
|
727
|
+
peopleId: { type: "string", required: true },
|
|
728
|
+
portalId: { type: "string", required: true },
|
|
729
|
+
},
|
|
730
|
+
);
|
|
731
|
+
|
|
732
|
+
return internalRequest(
|
|
733
|
+
this.sdk,
|
|
734
|
+
`/portals/people/${encodeURIComponent(peopleId)}/reset-password`,
|
|
735
|
+
"POST",
|
|
736
|
+
{ body: { portalId } },
|
|
737
|
+
);
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* Revokes a person's portal access (soft-deletes their credential across
|
|
742
|
+
* every portal on the account). Idempotent — revoking someone with no
|
|
743
|
+
* credential is a no-op, not an error.
|
|
744
|
+
*
|
|
745
|
+
* @param {string} peopleId
|
|
746
|
+
* @returns {Promise<{ ok: true }>}
|
|
747
|
+
*/
|
|
748
|
+
async revokePeopleAccess(peopleId) {
|
|
749
|
+
this.sdk.validateParams(
|
|
750
|
+
{ peopleId },
|
|
751
|
+
{
|
|
752
|
+
peopleId: { type: "string", required: true },
|
|
753
|
+
},
|
|
754
|
+
);
|
|
755
|
+
|
|
756
|
+
return internalRequest(
|
|
757
|
+
this.sdk,
|
|
758
|
+
`/portals/people/${encodeURIComponent(peopleId)}/access`,
|
|
759
|
+
"DELETE",
|
|
760
|
+
);
|
|
761
|
+
}
|
|
762
|
+
|
|
628
763
|
/**
|
|
629
764
|
* Lists the customer-facing labels configured for each engagement status.
|
|
630
765
|
*
|