Skip to content

Commit 796a7b4

Browse files
authored
Merge branch 'master' into patch-1
2 parents 1e6039f + 9f35c65 commit 796a7b4

File tree

6 files changed

+248
-0
lines changed

6 files changed

+248
-0
lines changed

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,54 @@ const response = await client.teams.find({
10671067
const response = await client.teams.list();
10681068
```
10691069

1070+
### Visitors
1071+
1072+
#### [Retrieve a Visitor](https://developers.intercom.com/intercom-api-reference/reference/view-a-visitor)
1073+
1074+
```typescript
1075+
const response = await client.visitors.find({ id: '123' });
1076+
```
1077+
1078+
OR
1079+
1080+
```typescript
1081+
const response = await client.visitors.find({ userId: '123' });
1082+
```
1083+
1084+
#### [Update a Visitor](https://developers.intercom.com/intercom-api-reference/reference/update-a-visitor)
1085+
1086+
```typescript
1087+
const response = await client.visitors.update({
1088+
userId: '123',
1089+
name: 'anonymous bruh',
1090+
customAttributes: {
1091+
paid_subscriber: true,
1092+
},
1093+
});
1094+
```
1095+
1096+
#### [Delete a Visitor](https://developers.intercom.com/intercom-api-reference/reference/delete-a-visitor)
1097+
1098+
```typescript
1099+
const response = await client.visitors.delete({
1100+
id,
1101+
});
1102+
```
1103+
1104+
#### [Convert a Visitor](https://developers.intercom.com/intercom-api-reference/reference/convert-a-visitor-to-a-user)
1105+
1106+
```typescript
1107+
const response = await client.visitors.mergeToContact({
1108+
visitor: {
1109+
id: '123',
1110+
},
1111+
user: {
1112+
userId: '123',
1113+
},
1114+
type: Role.USER,
1115+
});
1116+
```
1117+
10701118
### Identity verification
10711119

10721120
`intercom-node` provides a helper for using [identity verification](https://docs.intercom.com/configure-intercom-for-your-product-or-site/staying-secure/enable-identity-verification-on-your-web-product):

lib/client.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import Segment from './segment';
1414
import Message from './message';
1515
import Team from './team';
1616
import Tag from './tag';
17+
import Visitor from './visitor';
1718

1819
import * as packageJson from '../package.json';
1920

@@ -66,6 +67,7 @@ export default class Client {
6667
teams: Team;
6768
usebaseURL: (baseURL: string) => this;
6869
usernamePart?: string;
70+
visitors: Visitor;
6971

7072
constructor(args: Constructor) {
7173
const [usernamePart, passwordPart] = Client.getAuthDetails(args);
@@ -91,6 +93,7 @@ export default class Client {
9193
this.segments = new Segment(this);
9294
this.tags = new Tag(this);
9395
this.teams = new Team(this);
96+
this.visitors = new Visitor(this);
9497
this.requestOpts = {
9598
baseURL: 'https://api.intercom.io',
9699
};

lib/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export * from './segment/segment.types';
3838
export * from './subscription/subscription.types';
3939
export * from './tag/tag.types';
4040
export * from './team/team.types';
41+
export * from './visitor/visitor.types';
4142

4243
// Export enums needed for requests
4344
export { SearchContactOrderBy } from './contact';
@@ -55,3 +56,9 @@ export {
5556
RedactConversationPartType,
5657
} from './conversation';
5758
export { RecepientType } from './message';
59+
export {
60+
ContactObjectForMerge,
61+
MergeVisitorToContactData,
62+
VisitorObjectForMerge,
63+
IdentificationForVisitor,
64+
} from './visitor';

lib/visitor.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { Client, ContactObject } from '.';
2+
import { Role } from './common/common.types';
3+
import { VisitorObject } from './visitor/visitor.types';
4+
5+
export default class Visitor {
6+
public readonly baseUrl = 'visitors';
7+
8+
constructor(private readonly client: Client) {
9+
this.client = client;
10+
}
11+
12+
find({ id, userId }: FindVisitorByIdData) {
13+
const query = userId ? { user_id: userId } : {};
14+
const url = `/${this.baseUrl}${id ? `/${id}` : ''}`;
15+
16+
return this.client.get<VisitorObject>({
17+
url,
18+
params: query,
19+
});
20+
}
21+
update({ id, userId, name, customAttributes }: UpdateVisitorData) {
22+
const data = {
23+
id,
24+
user_id: userId,
25+
name,
26+
custom_attributes: customAttributes,
27+
};
28+
29+
return this.client.put<VisitorObject>({
30+
url: `/${this.baseUrl}`,
31+
data,
32+
});
33+
}
34+
delete({ id }: DeleteVisitorByIdData) {
35+
return this.client.delete<VisitorObject>({
36+
url: `/${this.baseUrl}/${id}`,
37+
});
38+
}
39+
mergeToContact({ visitor, user, type }: MergeVisitorToContactData) {
40+
const data = {
41+
visitor: {
42+
id: visitor.id,
43+
user_id: visitor.userId,
44+
email: visitor.email,
45+
},
46+
user: {
47+
id: user.id,
48+
user_id: user.userId,
49+
email: user.email,
50+
},
51+
type,
52+
};
53+
54+
return this.client.post<ContactObject>({
55+
url: `/${this.baseUrl}/convert`,
56+
data,
57+
});
58+
}
59+
}
60+
61+
export type IdentificationForVisitor =
62+
| { id: string; userId?: never }
63+
| { id?: never; userId: string };
64+
65+
type FindVisitorByIdData = IdentificationForVisitor;
66+
67+
type UpdateVisitorData = IdentificationForVisitor & {
68+
name?: string;
69+
customAttributes?: VisitorObject['custom_attributes'];
70+
};
71+
72+
type DeleteVisitorByIdData = { id: string };
73+
74+
export type MergeVisitorToContactData = {
75+
visitor: VisitorObjectForMerge;
76+
user: ContactObjectForMerge;
77+
type: Role;
78+
};
79+
80+
export type VisitorObjectForMerge =
81+
| { id: string; userId?: never; email?: never }
82+
| { id?: never; userId: string; email?: never }
83+
| { id?: never; userId?: never; email: string };
84+
85+
export type ContactObjectForMerge = IdentificationForVisitor & {
86+
email?: string;
87+
};

lib/visitor/visitor.types.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { JavascriptObject, SegmentObject, TagObject, Timestamp } from '..';
2+
3+
export type VisitorObject = {
4+
type: 'visitor';
5+
id: string;
6+
created_at: Timestamp;
7+
updated_at: Timestamp;
8+
user_id: string;
9+
name: string;
10+
custom_attributes: JavascriptObject;
11+
last_request_at: Timestamp;
12+
avatar: string | { url: string };
13+
unsubscribed_from_emails: boolean;
14+
location_data: JavascriptObject;
15+
social_profiles: JavascriptObject[];
16+
segments: SegmentObject[];
17+
tags: TagObject[];
18+
};

test/visitor.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import assert from 'assert';
2+
import { Client, Role } from '../lib';
3+
import nock from 'nock';
4+
5+
describe('visitors', () => {
6+
const client = new Client({
7+
usernameAuth: { username: 'foo', password: 'bar' },
8+
});
9+
it('retrieves a visitor by id', async () => {
10+
const id = 'baz';
11+
12+
nock('https://api.intercom.io').get(`/visitors/${id}`).reply(200, {});
13+
14+
const response = await client.visitors.find({ id });
15+
16+
assert.deepStrictEqual({}, response);
17+
});
18+
it('retrieves a visitor by user id', async () => {
19+
const userId = 'baz';
20+
21+
nock('https://api.intercom.io')
22+
.get('/visitors')
23+
.query({ user_id: userId })
24+
.reply(200, {});
25+
26+
const response = await client.visitors.find({ userId });
27+
28+
assert.deepStrictEqual({}, response);
29+
});
30+
it('updates a visitor by id', async () => {
31+
const requestData = {
32+
user_id: '124',
33+
name: 'Winston Smith',
34+
custom_attributes: {
35+
paid_subscriber: true,
36+
monthly_spend: 155.5,
37+
team_mates: 9,
38+
},
39+
};
40+
nock('https://api.intercom.io').put('/visitors').reply(200, {});
41+
const response = await client.visitors.update({
42+
userId: requestData.user_id,
43+
name: requestData.name,
44+
customAttributes: requestData.custom_attributes,
45+
});
46+
47+
assert.deepStrictEqual({}, response);
48+
});
49+
it('deletes a visitor', async () => {
50+
const id = 'baz';
51+
52+
nock('https://api.intercom.io')
53+
.delete(`/visitors/${id}`)
54+
.reply(200, {});
55+
56+
const response = await client.visitors.delete({
57+
id,
58+
});
59+
60+
assert.deepStrictEqual({}, response);
61+
});
62+
it('converts a visitor into contact', async () => {
63+
const requestData = {
64+
visitor: { id: 'baz' },
65+
user: { user_id: 'bez' },
66+
type: Role.USER,
67+
};
68+
69+
nock('https://api.intercom.io')
70+
.post('/visitors/convert', requestData)
71+
.reply(200, {});
72+
73+
const response = await client.visitors.mergeToContact({
74+
visitor: {
75+
id: requestData.visitor.id,
76+
},
77+
user: {
78+
userId: requestData.user.user_id,
79+
},
80+
type: requestData.type,
81+
});
82+
83+
assert.deepStrictEqual({}, response);
84+
});
85+
});

0 commit comments

Comments
 (0)