0

Get Related Records

by
Published 8 days ago

List child records related to a parent via a child relationship name (e.g. Account → Contacts), optionally restricted to a chosen set of fields (multi-select).

Script salesforce Verified

The script

Submitted by hugo989 Bun
Verified 9 days ago
1
//native
2

3
export type DynSelect_sobject = string
4
export type DynSelect_relationship_name = string
5
export type DynMultiselect_fields = string[]
6

7
// Dropdown of the org's objects (global describe).
8
export async function sobject(auth: RT.Salesforce) {
9
  const apiVersion = auth.api_version || "v60.0"
10
  const response = await fetch(
11
    `${auth.instance_url}/services/data/${apiVersion}/sobjects/`,
12
    {
13
      headers: {
14
        Authorization: `Bearer ${auth.token}`,
15
        Accept: "application/json",
16
      },
17
    }
18
  )
19
  if (!response.ok) {
20
    throw new Error(`${response.status} ${await response.text()}`)
21
  }
22
  const { sobjects } = (await response.json()) as {
23
    sobjects: { name: string; label: string }[]
24
  }
25
  return sobjects
26
    .map((o) => ({ value: o.name, label: `${o.label} (${o.name})` }))
27
    .sort((a, b) => a.label.localeCompare(b.label))
28
}
29

30
// Dependent dropdown: child relationship names of the chosen object.
31
export async function relationship_name(
32
  auth: RT.Salesforce,
33
  sobject: DynSelect_sobject
34
) {
35
  if (!sobject) return []
36
  const apiVersion = auth.api_version || "v60.0"
37
  const response = await fetch(
38
    `${auth.instance_url}/services/data/${apiVersion}/sobjects/${sobject}/describe`,
39
    {
40
      headers: {
41
        Authorization: `Bearer ${auth.token}`,
42
        Accept: "application/json",
43
      },
44
    }
45
  )
46
  if (!response.ok) {
47
    throw new Error(`${response.status} ${await response.text()}`)
48
  }
49
  const { childRelationships } = (await response.json()) as {
50
    childRelationships: {
51
      relationshipName: string | null
52
      childSObject: string
53
    }[]
54
  }
55
  return childRelationships
56
    .filter((r) => r.relationshipName)
57
    .map((r) => ({
58
      value: r.relationshipName as string,
59
      label: `${r.relationshipName}${r.childSObject}`,
60
    }))
61
    .sort((a, b) => a.label.localeCompare(b.label))
62
}
63

64
// Dependent multi-select: fields of the related child object behind the chosen relationship.
65
export async function fields(
66
  auth: RT.Salesforce,
67
  sobject: DynSelect_sobject,
68
  relationship_name: DynSelect_relationship_name
69
) {
70
  if (!sobject || !relationship_name) return []
71
  const apiVersion = auth.api_version || "v60.0"
72
  const headers = {
73
    Authorization: `Bearer ${auth.token}`,
74
    Accept: "application/json",
75
  }
76
  const parent = await fetch(
77
    `${auth.instance_url}/services/data/${apiVersion}/sobjects/${sobject}/describe`,
78
    { headers }
79
  )
80
  if (!parent.ok) {
81
    throw new Error(`${parent.status} ${await parent.text()}`)
82
  }
83
  const { childRelationships } = (await parent.json()) as {
84
    childRelationships: {
85
      relationshipName: string | null
86
      childSObject: string
87
    }[]
88
  }
89
  const child = childRelationships.find(
90
    (r) => r.relationshipName === relationship_name
91
  )
92
  if (!child) return []
93
  const childDescribe = await fetch(
94
    `${auth.instance_url}/services/data/${apiVersion}/sobjects/${child.childSObject}/describe`,
95
    { headers }
96
  )
97
  if (!childDescribe.ok) {
98
    throw new Error(`${childDescribe.status} ${await childDescribe.text()}`)
99
  }
100
  const { fields: fieldList } = (await childDescribe.json()) as {
101
    fields: { name: string; label: string }[]
102
  }
103
  return fieldList
104
    .map((f) => ({ value: f.name, label: `${f.label} (${f.name})` }))
105
    .sort((a, b) => a.label.localeCompare(b.label))
106
}
107

108
/**
109
 * Get Related Records
110
 * List child records related to a parent via a child relationship name (e.g. Account → Contacts), optionally restricted to a chosen set of fields.
111
 */
112
export async function main(
113
  auth: RT.Salesforce,
114
  sobject: DynSelect_sobject,
115
  record_id: string,
116
  relationship_name: DynSelect_relationship_name,
117
  fields: DynMultiselect_fields | undefined
118
) {
119
  const apiVersion = auth.api_version || "v60.0"
120
  const url = new URL(
121
    `${auth.instance_url}/services/data/${apiVersion}/sobjects/${sobject}/${record_id}/${relationship_name}`
122
  )
123
  if (fields && fields.length > 0) {
124
    url.searchParams.append("fields", fields.join(","))
125
  }
126

127
  const response = await fetch(url, {
128
    method: "GET",
129
    headers: {
130
      Authorization: `Bearer ${auth.token}`,
131
      Accept: "application/json",
132
    },
133
  })
134

135
  if (!response.ok) {
136
    throw new Error(`${response.status} ${await response.text()}`)
137
  }
138

139
  return await response.json()
140
}
141