I have the following situation:
I want to get the console log of a website and send that to WebSocket clients.
I was able to create a node server and send data to connected users with below code.
const puppeteer = require('puppeteer');
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 2222 });
wss.on('connection', function connection(ws) {
ws.send("sending the sample data");
});
I was able to get the console log of website using following code:
(async () => {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--headless',
'--disable-gpu',
'--window-size=1920x1080'
]
});
const page = await browser.newPage();
await page.goto('https://example.com/test.php');
page.on('console', msg => console.log(msg.text()));
})();
Here page.on is a callback function, which is called every time there is a console log. How do I broadcast that msg (console.log from puppeteer) to WebSocket clients?
Please note that the website is opened once only when the app is started and console.log output is generated using setInterval every second. So new users get only the latest data.
Instead of console.log(msg.text()) you need to broadcast the message to all ws clients, right?
So a simple code will be:
page.on('console', msg => {
wss.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send(msg.text());
}
});
});
Read here for more info
Related
So I am trying to send my user's audio to a server and save it in a file with the following code (Frontend is JavaScript, and the server is Python), it doesn't seem to work with no errors in the JavaScript, and Python console and an empty output.wav file.
<script>
const socket = new WebSocket("ws://localhost:8080");
const startRecordingButton = document.getElementById("start-recording");
let mediaRecorder;
startRecordingButton.addEventListener("click", async () => {
const stream = await navigator.mediaDevices.getUserMedia({
audio: true,
});
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start();
mediaRecorder.addEventListener("dataavailable", (event) => {
socket.send(event.data);
});
mediaRecorder.addEventListener("error", (event) => {
console.error("MediaRecorder error:", event);
});
});
</script>
<button id="start-recording">Start Recording</button>
import asyncio
import wave
import websockets
with wave.open("output.wav", "wb") as wav_file:
wav_file.setsampwidth(2)
wav_file.setnchannels(1)
wav_file.setframerate(16000)
async def handle(websocket, path):
async for message in websocket:
data = message.data
wav_file.writeframes(data)
start_server = websockets.serve(handle, "localhost", 8080)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
I've got the LTS Python, Pip, and the latest versions of the WebSocket package. I am trying to test this in the latest Google Chrome browser. What is wrong with this code?
I am trying to setup slack bot and facing below issue.
Error: Slack request signing verification failed
I am exactly following this YT tutorial, even tried git clone his repo to try out but still facing same error.
I even tried to search other slack bot setup tutorial and come back to same issue.
Please help if any of you have experience in fixing this.
Followed tutorial: https://www.youtube.com/watch?v=Awuh2I6iFb0
-> Environment: NodeJS
-> app.js file
require('dotenv').config();
const { WebClient } = require('#slack/web-api');
const { createEventAdapter } = require('#slack/events-api');
const slackSigningSecret = process.env.SLACK_SIGNING_SECRET;
const slackToken = process.env.SLACK_TOKEN;
const port = process.env.SLACK_PORT || 3000;
const slackEvents = createEventAdapter(slackSigningSecret);
const slackClient = new WebClient(slackToken);
slackEvents.on('app_mention', (event) => {
console.log(`Got message from user ${event.user}: ${event.text}`);
(async () => {
try {
await slackClient.chat.postMessage({ channel: event.channel, text: `Hello <#${event.user}>! :tada:` })
} catch (error) {
console.log(error.data)
}
})();
});
slackEvents.on('error', console.error);
slackEvents.start(port).then(() => {
console.log(`Server started on port ${port}`)
});
Full error code:
Error: Slack request signing verification failed
at Server. (/Users/byao/CD/playground/slackcicd/node_modules/#slack/events-api/dist/http-handler.js:148:39)
at Server.emit (events.js:375:28)
at parserOnIncoming (_http_server.js:897:12)
at HTTPParser.parserOnHeadersComplete (_http_common.js:126:17) {
code: 'SLACKHTTPHANDLER_REQUEST_SIGNATURE_VERIFICATION_FAILURE'
}
Very appreciated and full of thank you if any of you are willing to help!
I am not able to automate postman script for this procedure:
Open postman then in authorization tab select type->OAuth 2.0, Add authorization data->Request Headers and Access token->Get Access Token
Filled fields-Token Name, Grant Type->Authorization Code, Callback URL, Auth Url, Acess Token Url, client Id, Scope, State, Client Authentication->Send as basic Auth header
then when request Token a pop up window opens for SSO
enter image description here
Then Manage Acess tokens pop up appears, then select Use Token button at the bottom, then running api url which now contain token in the Header tab->temperory headers.
How to automate this procedure with storing token in environment variables,then running rest of the API's with it.
I tried to access access_token from oauth 2.0 login by using Express and puppeteer.
var express = require('express');
const puppeteer = require('puppeteer');
var app = express();
app.get('/', function(req, res) {
run().then(() => console.log('Done')).catch(error => console.log(error));
async function run(){
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.goto('https://abcd.com/authorize?
audience=https://abcd.com&scope=openid%20email%20profile&client_id=abcd&response_type=token&redirect_uri=https://abcd.com/callback');
await new Promise(resolve => setTimeout(resolve, 5000));
await page.focus('#email');
await page.keyboard.type('abcd#gmail.com');
await page.focus('#password');
await page.keyboard.type('efghi');
const waitForLoad = new Promise(resolve => page.on('load', () => resolve()));
await page.evaluate(() => {
document.querySelector('span[class="label"]').click();
});
await waitForLoad;
console.log('Waiting to be redirected to the client.');
const clientUrl = await page.evaluate(() => window.location.href);
//1st the split is from when it encounters = in the url
var split1 = clientUrl.split('=');
//2nd split is when it encounters & in the 2nd object of the array
var split2 = split1[1].split('&');
//taking array in an object and conversing it to json
var obj = {
access_token: split2[0]
}
await browser.close();
res.send(obj);
};
});
app.listen(8000, function(){
console.log('Heard on 8000');
});
This can be run on postman to run other api with the received access token.
Using refresh token This can also be achieved in less time
Get refresh token by API https://{{auth0_domain}}/oauth/token
BODY-
grant_type:password
client_id:abcdefghijklmn
audience:https://abcd.com
username:abcd
password:efgh
scope:openid profile email offline_access
In Response will generate Refresh Token, this token then can be used in getting accesss_token without again generating refresh token in future. It's a one time process only and it doesn't get expired in a day or a week or a month.
I have a Node/Vue application. I am consuming a WebSocket from Binance, a crypto exchange. I can see the quotes on the server console as I log them, I can send them to the browser for a short period of time before the client stops logging them.
Browser just using WebSocket API
Node using ws library
Node code, this I am running as it's own service as its just this.
'use strict';
const WebSocket = require('ws');
const binanceWS = new WebSocket('wss://stream.binance.com:9443/ws/btcusdt#trade')
const server = new WebSocket.Server({ port: 5002 });
//websocket connection event will return a socket you can later use
binanceWS.on("open", function() {
console.log("connected to Binance");
});
binanceWS.on('message', function(data){
console.log(data);
server.on('connection', function connection(ws){
console.log("Connected a new client");
ws.send(data);
});
server.on('closed', function (id){
console.log("connection closed");
console.log(id);
});
server.on('error', function (err){
console.log(err)
})
})
On the Client side I am using Vue and in the app.js file I have this on the created hook.
let socket = new WebSocket("ws://localhost:5002")
socket.addEventListener('message', function(event){
let quotes = JSON.parse(event.data);
console.log(quotes.p)
});
socket.addEventListener('error', function(event){
console.log("closing because " + event);
})
Right now I am only listening to the consoles in the above app.vue file.
What I see in the browser console is a lot of quotes, then they stop after a second or 2. There can be over a thousand quotes in some times. Then on occasion I see a console.log('created') that I have in a child component of app.vue. In many cases this is the last thing in the console after hundreds of quotes.
In the console.log for the server I see a lot of sessions being created with one page refresh. So much that it fills my console.
So I'm not sure I am creating the connections correcly, I am not sure if Vue is somehow stopping the console.log's?
I don't see any errors anywhere and the entire time in my server console the Binance API continues streaming.
you have to write server event listener outside binance on message handler;
then you can pass messages from binance to the server by emitting new event to the server
on receiving message from binance you can send data to all connection on the server
Or Try this code I think it will work :
'use strict';
const WebSocket = require('ws');
const binanceWS = new WebSocket('wss://stream.binance.com:9443/ws/btcusdt#trade')
const server = new WebSocket.Server({ port: 5002 });
server.on('connection', function connection(ws){
console.log("Connected a new client");
});
server.on('closed', function (id){
console.log("connection closed");
console.log(id);
});
server.on('error', function (err){
console.log(err)
})
//websocket connection event will return a socket you can later use
binanceWS.on("open", function() {
console.log("connected to Binance");
});
binanceWS.on('message', function(data){
console.log(data);
server.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
})
An Electron App which uses ipcMain and ipcRenderer process to send telnet commands on click of a button along with npm telnet-client library for Telnet connection between desktop App & remote device (server). I'm new to promises so could not figure it out the right implementation.
Issue: every time a button is clicked a new Telnet session is established and my remote device becomes unresponsive after twenty concurrent sessions. To overcome this I've added connection.end() after connection.exec() completes on Telnet connection which somehow improves functionality by closing connection after sending command but also adds latency. However I also realized this does not work all the time and skips intermittently leaving the connection open.
Question: how can I check whether the Telnet session is already established and then send commands through the existing session instead creating new session every time and running behind closing it explicitly.
server.html
<script>
const {ipcRenderer} = require('electron')
function sendCommand(channel, arg){
ipcRenderer.send(channel, arg)
}
</script>
<button onclick="sendCommand('channel-1', 'command1');"> Command 1 </button>
<button onclick="sendCommand('channel-1', 'command2');"> Command 2 </button>
main.js
const {ipcMain} = require('electron')
var Telnet = require('telnet-client')
var connection = new Telnet()
ipcMain.on('channel-1', (event, arg) => {
var params = {
host: '192.168.1.121',
port: 23,
shellPrompt: ' ',
timeout: 1500,
}
var cmd = arg
connection.on('ready', function(prompt) {
connection.exec(cmd, function(err, response) {
console.log(response)
})
})
connection.on('timeout', function() {
console.log('socket timeout!')
connection.end()
})
connection.on('close', function() {
console.log('connection closed')
})
connection.connect(params)
})
Thanks in advance.
The following modification helped me sending commands over the existing telnet channel without creating multiple sessions of telnet, now the speed of sending telnet command is fast.
var params = {
host: '192.168.1.121',
port: 23,
shellPrompt: ' ',
timeout: 1500,
// removeEcho: 4
}
connection.connect(params)
var cmd = "a temp command"
connection.on('ready', function(prompt) {
connection.exec(cmd, function(err, response) {
console.log(response)
})
})
connection.on('timeout', function() {
console.log('socket timeout!')
connection.end()
})
connection.on('close', function() {
console.log('connection closed')
})
ipcMain.on('channel-1', (event, arg) => {
cmd = arg
if(connection.getSocket().writable){
connection.exec(cmd, function(err, response) {
console.log(response)
})
}else{
console.log("connection closed!" + connection.getSocket().writable)
}
})