-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.js
148 lines (125 loc) · 4.37 KB
/
client.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
const util = require('util');
const { JSDOM } = require('jsdom');
const { ChatManager, TokenProvider } = require('@pusher/chatkit');
const readline = require('readline');
const axios = require('axios');
const prompt = require('prompt');
const ora = require('ora');
require('dotenv').config();
const { log } = console;
/*
* Chatkit does not currently support Node,
* so will trick it to think we're using a browser environment.
*/
const makeChatkitNodeCompatible = () => {
const { window } = new JSDOM();
global.window = window;
global.navigator = {};
};
makeChatkitNodeCompatible();
const { INSTANCE_LOCATOR: instanceLocator } = process.env;
const AUTH_URL = 'http://localhost:3001';
if (!instanceLocator) {
log('Please set INSTANCE_LOCATOR environment variable');
process.exit(1);
}
const authenticate = async username => {
try {
const { data } = await axios.post(AUTH_URL + '/users', { username });
} catch ({ message }) {
throw new Error(`Failed to authenticate, ${message}`);
}
};
(async () => {
const spinner = ora();
try {
prompt.start();
prompt.message = '';
const get = util.promisify(prompt.get);
const usernameSchema = [
{
description: 'Enter your username',
name: 'username',
type: 'string',
pattern: /^[a-zA-Z0-9\-]+$/,
message: 'Username must be only letters, numbers, or dashes',
required: true,
},
];
const { username } = await get(usernameSchema);
try {
spinner.start('Authenticating..');
await authenticate(username);
spinner.succeed(`Authenticated as ${username}`);
} catch (err) {
spinner.fail();
throw err;
}
const chatManager = new ChatManager({
instanceLocator,
userId: username,
tokenProvider: new TokenProvider({ url: AUTH_URL + '/authenticate' }),
});
spinner.start('Connecting to Pusher..');
const currentUser = await chatManager.connect();
spinner.succeed('Connected');
spinner.start('Fetching rooms..');
const joinableRooms = await currentUser.getJoinableRooms();
spinner.succeed('Fetched rooms');
const availableRooms = [...currentUser.rooms, ...joinableRooms];
if (!availableRooms)
throw new Error(
"Couldn't find any available rooms. If you're the developer, go to dash.pusher.com, open your Chatkit instance, and create a room (or two!) using the Inspector tab!",
);
log('Available rooms:');
availableRooms.forEach((room, index) => {
log(`${index} - ${room.name}`);
});
const roomSchema = [
{
description: 'Select a room',
name: 'room',
type: 'number',
cast: 'integer',
pattern: /^[0-9]+$/,
conform: v => {
if (v >= availableRooms.length) {
return false;
}
return true;
},
message: 'Room must only be numbers',
required: true,
},
];
const { room: roomNumber } = await get(roomSchema);
const room = availableRooms[roomNumber];
spinner.start(`Joining room ${roomNumber}..`);
await currentUser.subscribeToRoom({
roomId: room.id,
hooks: {
onNewMessage: message => {
const { senderId, text } = message;
if (senderId === username) return;
log(`${senderId}: ${text}`);
},
onUserJoined: ({ name }) => {
log(`${name} joined`);
},
},
messageLimit: 0,
});
spinner.succeed(`Joined ${room.name}`);
log(
'You may now send and receive messages. Type your message and hit <Enter> to send.',
);
const input = readline.createInterface({ input: process.stdin });
input.on('line', async text => {
await currentUser.sendMessage({ roomId: room.id, text });
});
} catch (err) {
spinner.fail();
log(err);
process.exit(1);
}
})();