N
Novu2y ago
Nexen

socket url and authentication

Hello, i have problems with socket connection. How should the url look like and where can i get token ? from source code i see it tries to match subscriber id, but i cannot see it anywhere. im not using react or angular.
23 Replies
Nexen
Nexen2y ago
after an hour i finally found where the JWT token is created https://github.com/novuhq/novu/blob/7235e410366e0897ed3f44cc8974f62f5ff56044/libs/testing/src/user.session.ts#L147 now how to make the socket connection 🤔 EDIT: doesnt work, so digging more
Dima Grossman
Dima Grossman2y ago
Hi @the_nexen the token for the socket service is created automaticaly and available either behind the scene with the iframe embed or by using the react component: by using the useSocket hook: https://docs.novu.co/notification-center/react-components#realtime-sockets
Nexen
Nexen2y ago
im using flutter, so i cant use any of your SDKs. is there a way to expose it on my end ? i was looking at api documentation and the authentication is missing. i managed to find the correct call
final response = await http.post(
Uri.parse('http://10.0.2.2:4500/widgets/session/initialize'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'ApiKey apikey',
},
body: jsonEncode(<String, dynamic>{
'applicationIdentifier': 'appId',
'subscriberId': 'id',
}),
);
final response = await http.post(
Uri.parse('http://10.0.2.2:4500/widgets/session/initialize'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'ApiKey apikey',
},
body: jsonEncode(<String, dynamic>{
'applicationIdentifier': 'appId',
'subscriberId': 'id',
}),
);
but its taking like a minute and i get empty body
Dima Grossman
Dima Grossman2y ago
I can try to create a small guide for you, but not sure would be able to do it. Basically you need to reverse how the react component initialize a session. I can write something tomorrow ish
Nexen
Nexen2y ago
exactly, it would be nice to "split" it for the future That would be amazing if you could do that! we decided loong ago for flutter (cross platform) and mashing in somehow js to have notifications is iffy to me. if i get session and proper example of websockets url, then it should be fine right? plan is: socket to get unread notifications (just count) then fetch notifications (separate page upon clicking) then the whole functionality when on page and active notification -> read, onclick etc..
Dima Grossman
Dima Grossman2y ago
Hi, sorry in a crazy few days, have it on my todo list. will update asap 🙏
Nexen
Nexen2y ago
Hello @dimagrossman when could i expect an update? 🙂
Paweł T.
Paweł T.2y ago
@the_nexen I see that the URL that you are hitting is missing the /v1 prefix, could you try with that? like: http://10.0.2.2:3000/v1/widgets/session/initialize then using that token you can initialize the socket connection
Nexen
Nexen2y ago
I can try with v1, but what is the socket url? Ws://localhost:3002 isnt working and how to pass authentication?
Paweł T.
Paweł T.2y ago
the default API port is 3000 and WS 3002 to create to socket connection in web app we do use the socket.io-client library, and the URL passed looks like this: http://localhost:3002 so it starts with http then it's switched to ws
const socket = io(socketUrl, {
reconnectionDelayMax: 10000,
transports: ['websocket'],
auth: {
token: `${token}`,
},
});
const socket = io(socketUrl, {
reconnectionDelayMax: 10000,
transports: ['websocket'],
auth: {
token: `${token}`,
},
});
Nexen
Nexen2y ago
Thanks! ill try that, im using https://pub.dev/packages/web_socket_channel so hopefully i can find the correct way of setting params
Dart packages
web_socket_channel | Dart Package
StreamChannel wrappers for WebSockets. Provides a cross-platform WebSocketChannel API, a cross-platform implementation of that API that communicates over an underlying StreamChannel.
Nexen
Nexen2y ago
ill try it next year, im a bit swamped with relations hehe
Paweł T.
Paweł T.2y ago
sure, let me know if anything needed 😉
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Nexen
Nexen2y ago
Ill try to make it work today, hit me up in dms maybe we can find something together @paweltymczuk Hello! can you show me network url you send for socket? i have option to pass in token in url query param and dont see in docker that the url was hit.. no log whatsoever, just that nest is initialized
WebSocketChannelException: WebSocketChannelException: HttpException: Connection closed before full header was received, uri = http://localhost:3002/?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVC...
WebSocketChannelException: WebSocketChannelException: HttpException: Connection closed before full header was received, uri = http://localhost:3002/?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVC...
seems like socket.io isnt really socket server, just acts like it. thats why websocketchannel doesnt work, because its proper. Nice that i found the issue. BUT this is really weird, because of this i have to have two socket clients.
Novu_Bot
Novu_Bot2y ago
@the_nexen, you just advanced to level 3!
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Nexen
Nexen2y ago
Another one, now its just not me 🙂 there is no flutter guide, api reference is your friend, socketio client needed, websocketchannel doesnt work. You need to scout sourcecode
final response = await http.post(
Uri.parse('http://localhost:3000/v1/widgets/session/initialize'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'ApiKey x',
},
body: jsonEncode(<String, dynamic>{
'applicationIdentifier': 'x',
'subscriberId': 'x',
}),
);
NovuSession session = NovuSession.fromJson(jsonDecode(response.body));
print('RESPONSE');
print(session.data?.token);

IO.Socket socket = IO.io(
'http://localhost:3002/?token=${session.data?.token}',
IO.OptionBuilder().setReconnectionDelayMax(10000).setTransports(['websocket']).build(),
);
socket.onConnect((_) {
print('connected');
});

socket.onConnectError((data) => print(data));
socket.on('unseen_count_changed', (data) => print('unseen_count_changed $data'));
socket.onDisconnect((_) => print('disconnect'));
final response = await http.post(
Uri.parse('http://localhost:3000/v1/widgets/session/initialize'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'ApiKey x',
},
body: jsonEncode(<String, dynamic>{
'applicationIdentifier': 'x',
'subscriberId': 'x',
}),
);
NovuSession session = NovuSession.fromJson(jsonDecode(response.body));
print('RESPONSE');
print(session.data?.token);

IO.Socket socket = IO.io(
'http://localhost:3002/?token=${session.data?.token}',
IO.OptionBuilder().setReconnectionDelayMax(10000).setTransports(['websocket']).build(),
);
socket.onConnect((_) {
print('connected');
});

socket.onConnectError((data) => print(data));
socket.on('unseen_count_changed', (data) => print('unseen_count_changed $data'));
socket.onDisconnect((_) => print('disconnect'));
Flutter example for socket
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Pawan Jain
Pawan Jain2y ago
Yes @orangedot API secret is for backend only
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Pawan Jain
Pawan Jain2y ago
@Engineering Can you please help?
DavidSouthmountain
The api key needs to be keept secret the notification uses a specific token instead that is created by the NovuProvider in the react package for example