How to call node function in angular application - node.js

I have this working code in node project
export function startWhatsapp(){
const qrcode = require('qrcode-terminal');
const { Client } = require('whatsapp-web.js');
const client = new Client();
client.on('qr', qr => {
qrcode.generate(qr, {small: true});
});
client.on('ready', () => {
console.log('Client is ready!');
});
client.initialize();
}
I need to use it in my angular app
what is the best practice to do it ?

You can use node web server, setup with express. It is quite easy to setup, then expose a simple API from the express server and use HttpClient from Angular to call the API.
https://expressjs.com/
If you want it more real time, based on the event, you can even use socket.io with node express server.
https://medium.com/#raj_36650/integrate-socket-io-with-node-js-express-2292ca13d891
You can use socket.io even on client side, so the it allow real time communication.

Related

Connecting an open client socket to rails endpoint

Currently working on a project which is Vue on top of rails 4. I am consuming webhooks from the square API, and I want to be able to get that data into vue so that my data can be updated in real time as square data changes. I've asked this question before, but I'm at a slightly different point in the problem; this is getting down to the nuts and bolts.
Currently, on the server side, I have webhooks setup to fire off to a rails controller, and that works well, i can see that data coming in.
On the client side, I have a socket open and listening to that same rails controller endpoint.
What I'm having trouble with is that even though I can see the webhook hit the controller, and the socket is active, I cant seem to get the socket to pick up on the controller endpoint emitting data. Doesnt seem like the controller endpoint is passing the data along as I expect, and I suspect there is both a gap in my knowledge of rails about how to emit data properly, and how to properly consume it with a socket.
What am I missing to be able to connect the dots here?
Caveats:
I realize this might be possible with ActionCable, and as a last resort I may go with that, but my client is very against upgrading from rails 4 (heavy lift). If this happens to be the only way to do it, so be it, but I want to explore all other options first.
Im no rails expert, and have very little experience with sockets. So this whole approach might, and probably IS foolish. I also may be misunderstanding some parts of how some of these technologies work.
I am unfortunately, bound to using rails and vue.
I am working on localhost, and using ngrok to create a proper URL for the webhooks to hit. I doubt its a problem, but maybe?
I have explored using a node server behind the scenes and sending webhooks directly to that and listening to that server with the socket. Couldnt get that to work either, but tips on how to achieve that if its a good idea are also welcome.
For reference:
Rails Controller:
class WebhooksController < ApplicationController
skip_forgery_protection
def order_update
p request
p params
if request.headers['Content-Type'] == 'application/json'
data = JSON.parse(request.body.read)
else
# application/x-www-form-urlencoded
data = params.as_json
end
render json: data
end
end
Client Code (Vue && Socket):
import { createApp } from 'vue';
import SquareOrders from '../views/SquareOrders.vue';
import VueSocketIO from 'vue-socket.io';
import { io } from "socket.io-client";
const socket = io("http://localhost:3000", {
transports: ["polling", "flashsocket"],
withCredentials: true,
path: '/webhooks/order_update'
});
export default function loadOrdersApp(el, pinia) {
const app = createApp(SquareOrders);
app.use(pinia)
.use(new VueSocketIO({
debug: true,
connection: socket
}))
.mount(el);
}
Suggestions on better approaches are appreciated, as are corrections to my basic knowledge if I am misunderstanding something.
So, after a lot of trial and error, i managed to answer this with a different approach.
as far as I can tell, actually listening to the rails endpoint without something like ActionCable seems impossible, so I booted up and express server to run in the background and ingest incoming webhooks.
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors');
// Create a new instance of express
const app = express()
// Tell express to use the body-parser middleware for JSON
app.use(bodyParser.json())
// ALLOW OUR CLIENT SIDE TO ACCESS BACKEND SERVER via CORS
app.use(cors({
origin: 'http://localhost:3000'
}));
// Tell our app to listen on port 3000
const server = app.listen(8080, function (err) {
if (err) {
throw err
}
console.log('Server started on port 8080')
})
const io = require('socket.io')(server);
app.set('io', io)
// Route that receives a POST request to /webhook
app.post('/webhook', function (req, res, next) {
const io = req.app.get('io');
console.log(req.body)
io.sockets.emit('orderUpdate', req.body)
//res.send(req.body)
res.sendStatus( 200 );
next();
})
io.on('connection', function(socket){
console.log('A connection is made');
});
With that in place, I pointed my webhook to localhost through ngrok, and then added logic in Vue through https://www.npmjs.com/package/vue-socket.io-extended
import { io } from "socket.io-client";
import SquareOrders from '../views/SquareOrders.vue';
import VueSocketIOExt from 'vue-socket.io-extended';
import socketStore from '../stores/sockets.js';
const socket = io("http://localhost:8080", {
transports: [ "websocket", "polling"],
});
export default function loadOrdersApp(el, pinia) {
const app = createApp(SquareOrders);
app.use(pinia)
//.use(socketStore)
.use(VueSocketIOExt, socket)
.mount(el);
}
To then listen for incoming socket emits on the socket.io channel.
With those both in place, i was able to ingest those socket emissions in my frontend app
export default {
name: "SquareOrders",
components: {
Filters,
GlobalLoader,
OrdersList,
FilterGroup,
Filter,
OrderActions
},
// LISTENING FOR THE SOCKETS IN VUE COMPONENT
sockets: {
connect() {
console.log('socket connected in vue')
},
orderUpdate(val) {
console.log(val)
debugger;
console.log('this method was fired by the socket server. eg: io.emit("customEmit", data)')
}
},
mounted() {
const os = orderStore();
os.getOrders();
os.getSourcesList();
os.getSandboxOrders();
console.log(this.$socket)
this.$socket.client.io.on('orderUpdate', (payload) => {
console.log(payload)
})
setInterval(function () {
os.getOrders();
}, 60000);
},
computed: {
...mapState(orderStore, {
orders: store => store.orders,
initalLoad: store => store.flags.loaded,
filterDefs: store => store.filters.definitions,
sandbox: store => store.sandbox
})
},
};

socket.io with webpack module federation

I'm using socket.io to communicate between a server and many clients. Locally everything works fine. However, on production it doesn't work as desired. We use microservices, and this specific microservice is part of a suite of services that run together using webpack module federation.
When accessing the app directly through the k8s ingress, I can see that the clients are connecting to the server. However, clients running through module federation (in the bigger app that consists of my microapp and others), do not connect to the server, and every few seconds a 404 error is printed to the console for a GET request to:
http://<BASE_URL>/socket.io/?EIO=4&transport=polling&t=XXXXXX
where XXXXXX is some random string. I believe that I need to redirect the clients' sockets somehow to reach the server, but I don't know how to do so.
Relevant Client Code
const socket = io.connect("");
socket.on("someEvent", (param) => {
doSomething()
});
Relevant Server Code
let server = app.listen(port, (err) => {
if (err) throw err;
// Express server Ready on http://localhost:port
});
...
let io;
const initSocket = (server) => {
io = require("socket.io")(server, {
cors: { origin: "*" }
});
io.on('connection', (socket) => {
logging.mainLogger.info(`successfully connected to socket
${JSON.stringify(socket.id)}`);
});
io.listen(server);
}
const emitSomeEvent = (param) => {
io.emit("someEvent", param);
}

Blazor Server cooperation with socket.io

I'm trying to connect Blazor Server functionality with socket.io, which normally is hosted on Node.js. I'd like to use Blazor which will listen to socket.io traffic on certain port.
I don't want to use Node.js, because I have already Blazor Server running on my machine.
According to socket.io documentation, using ES Modules, I may create index.js with listening code:
import { createServer } from "http";
import { Server } from "socket.io";
const httpServer = createServer();
const io = new Server(httpServer, {
// ...
});
io.on("connection", (socket) => {
// ...
});
httpServer.listen(3000);
I'm able to reuse npm packages in Blazor application, injecting IJSRuntime on Blazor page and using construction such as:
var output = await JsRunTime.InvokeAsync<string>("function");
I don't know how to properly glue socket.io into Blazor app (or whether is it even feasible ?)
Should I just add another port while initializing Blazor in CreateHostBuilder, sth like :
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.UseUrls("http://localhost:5821;http://localhost:3000");
webBuilder.UseSetting(WebHostDefaults.DetailedErrorsKey, "true");
});
and later just listen to port 3000 to intercept socket.io packages ?
thanks !

How to manage socket in client side as ejs template and react js and the server side it is nodejs

In my project use the reactJS for frontend and ejs template engine with a node for the backend. already the project is started so now I can't change the whole project into reactJS.
creating one chat app with two clients(react and ejs) and one server(nodeJs) but I stuck in message passing to both clients at one time.
my code is below please tell me is that possible to create a chat app with ejs, node, and react.
ejs:-
<script src="/backend/chat/socketMessage.js"></script>
var socket = io.connect('http://localhost:8080');
socket.on('receive-user',function(data){
console.log('receive on ejs');
})
reactJs:-
import io from 'socket.io-client';
const ENDPOINT = 'localhost:8080';
constructor() {
super();
endpoint:ENDPOINT,
}
const {endpoint} = this.state;
const socket = io(endpoint);
socket.on('receive-user', this._messageRecieve);
_messageRecieve(message) {
console.log(message)
}
nodeJS:-
module.exports = function(io) {
io.on('connection', function(socket){
socket.emit('receive-user',details);
})
}
Please Help...
use as per below it will work fine
io.on('connection', function(socket){
io.sockets.emit('receive-user',details);
})

how to connect to socket.io on nodejs server using flutter?

I am developing a backend using node js and express framework and I will use socket.io in order to make a realtime connection between the server and the client ( flutter app ).
I have created a socket.io configuration on the server-side code and this is the code snippet:
const server = app.listen(port);
const io = require('socket.io')(server);
io.on('connection' , client => {
console.log('one connected');
});
and on the client side:
SocketIO socketIO;
socketIO = SocketIOManager().createSocketIO(SERVER_URL, '/');
socketIO.init().then(
(result) async {
await socketIO.subscribe('connection', (){});
await socketIO.connect();
},
);
the problem that I can't see one connected logged in the console of the node app.
it doesn't throw any error on the client-side and I want to know if I am on the right way.
Thanks,
After searching I found that the solution was to create my server using http plugin.

Resources