I made a electron app a couple years ago. now like to update for a little bit diiferint usage.
When I try to run this after updating electron and libraries and import it is failing on the http requirement.
The long ago compiled app still works, but even the code for that if i copy it to new project also failed on this require line.
Error in the console
ReferenceError: Can't find variable: require
renderer.js:62
And below are the codes
browser setup in index.js
const path = require('path');
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require('electron-squirrel-startup')) { // eslint-disable-line global-require
app.quit();
}
const createWindow = () => {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 200,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true,
}
});
// and load the index.html of the app.
mainWindow.loadFile(path.join(__dirname, 'index.html'));
// Open the DevTools.
//mainWindow.webContents.openDevTools();
};
failing request in renderer.js
/* placeCall
* Grab the SIP uri from the input box and send it to the codec.
* Requires an account on the codec that can make calls.
* Send the authorization in the http header.
*/
function placeCall(){
var uri = document.getElementById("sipuri").value;
var xmldoc = '<Command><Dial command="true"><Number>' + uri + '</Number></Dial></Command>';
var xmlLength = xmldoc.length;
var sysIp = document.getElementById("sysip").value;
// console.log("XMLDOC: " + xmldoc);
var http = require("https"); <- CRASHES HERE ON LINE 62!
var options = {
"method": "POST",
"hostname": sysIp,
"port": null,
"path": "/putxml",
"rejectUnauthorized": false,
"headers": {
"content-type": "text/xml",
"content-length": xmlLength,
"authorization": "Basic dkeicjsmcielwoslkdddddd"
}
};
var req = http.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
});
req.write(xmldoc);
req.end();
}
the error is in the browser. seems like it has to run as electron app.
That must be that require is really a node.js operation.
Maybe this question is repeated elsewhere and this one can be deleted.
Related
I'm following the docs in zapier regarding the callbackUrl https://platform.zapier.com/cli_docs/docs#zgeneratecallbackurl however cannot seem to get the performResume step to be run. The zap I'm creating based on this integration also does not seem to wait for the callbackUrl to be hit.
const createScreenshot = (z, bundle) => {
const callbackUrl = z.generateCallbackUrl();
const promise = z.request({
url: 'https://myapi.com/v1/render',
method: 'POST',
params: {},
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: {
...bundle.inputData,
webhook_url: callbackUrl
},
removeMissingValuesFrom: {},
});
z.console.log("Returning from perform / createScreenshot");
return promise.then((response) => ({ ...response.data, waiting_for: "performResume" }));
const onScreenshotFinished = (z, bundle) => {
z.console.log("In performResume / onScreenshotFinished", bundle.cleanedRequest);
const responseBody = bundle.cleanedRequest;
let screenshotUrl;
if (responseBody.event === "render.succeeded") {
z.console.log("render was processed successfully", responseBody);
screenshotUrl = responseBody.result.renderUrl;
return { screenshotUrl, ...responseBody };
}
z.console.log("render was not processed", responseBody);
throw z.errors.Error("Screenshot was not successful");
}
module.exports = {
operation: {
perform: createScreenshot,
performResume: onScreenshotFinished,
...
}
}
We talked through this question (and its solution) on GitHub (zapier/zapier-platform#398), but to summarize for SO readers:
When setting up a resumable Zap, the editor uses the sample to populate the data in the callback. No actual waiting happens during the setup process. Once the zap is live, it works like normal.
So, to implement:
perform should return sample data that matches the data the "resume" webhook sends
performSubscribe can read that data and operate normally
See the GH issue for more info.
I have this Ionic 5/Capacitor app, which I'm making an API call to a local server from, that server running on docker at localhost:3000. When I test from the browser, the request is made fine. From Postman it requests fine, too. In my XCode logs the emulator, I see this
[error] - ERROR {"headers":{"normalizedNames":{},"lazyUpdate":null,"headers":{}},"status":0,"statusText":"Unknown Error","url":"http://localhost:3000/pins","ok":false,"name":"HttpErrorResponse","message":"Http failure response for http://localhost:3000/pins: 0 Unknown Error","error":{"isTrusted":true}}
The really interesting part, is that I'm running Fiddler to monitor the request as it's made. Fiddler gets a 200 as well, I can even see the response data. So, Fiddler sees the proper network call, but then my Ionic app gets that error. That makes me feel like it's an Ionic/Emulator/IOS problem, but I don't have enough familiarity with Ionic to know right off the bat what it is.
Here's the code responsible for making the request:
ngOnInit() {
const request = this.http.get('http://localhost:3000/pins');
this.refresh$.subscribe(
(lastPos: { latitude?: any; longitude?: number }) => {
request.subscribe(data => {
if (data) {
this.addMarkersToMap(data, lastPos);
}
});
}
);
}
And the HTTPClient imported in the constructor is from Angular:
import { HttpClient } from '#angular/common/http';
I ended up having to use this package, doing a check on if I'm on mobile or not.
https://ionicframework.com/docs/native/http/
Try with this :
const request = this.http.get('http://localhost:3000/pins', { observe: 'response', withCredentials: true });
Solution 2 : capacitor.config.json
"server": {
"hostname": "localhost", (maybe try precising the port number too)
}
Solution 3 : On your Express server (from https://ionicframework.com/docs/troubleshooting/cors)
const express = require('express');
const cors = require('cors');
const app = express();
const allowedOrigins = [
'capacitor://localhost',
'ionic://localhost',
'http://localhost',
'http://localhost:8080',
'http://localhost:8100'
];
// Reflect the origin if it's in the allowed list or not defined (cURL, Postman, etc.)
const corsOptions = {
origin: (origin, callback) => {
if (allowedOrigins.includes(origin) || !origin) {
callback(null, true);
} else {
callback(new Error('Origin not allowed by CORS'));
}
}
}
// Enable preflight requests for all routes
app.options('*', cors(corsOptions));
app.get('/', cors(corsOptions), (req, res, next) => {
res.json({ message: 'This route is CORS-enabled for an allowed origin.' });
})
app.listen(3000, () => {
console.log('CORS-enabled web server listening on port 3000');
});
I want to ask about how to send an event using firebase & electron.js. A friend of mine has a problem when using firebase analytics and electron that it seems the electron doesn't send any event to the debugger console. When I see the network it seems the function doesn't send anything but the text successfully go in console. can someone help me to figure it? any workaround way will do, since he said he try to implement the solution in this topic
firebase-analytics-log-event-not-working-in-production-build-of-electron
electron-google-analytics
this is the error I got when Try to use A solution in Point 2
For information, my friend used this for the boiler plate electron-react-boilerplate
The solution above still failed. Can someone help me to solve this?
EDIT 1:
As you can see in the image above, the first image is my friend's code when you run it, it will give a very basic example like in the image 2 with a button to send an event.
ah just for information He used this firebase package :
https://www.npmjs.com/package/firebase
You can intercept HTTP protocol and handle your static content though the provided methods, it would allow you to use http:// protocol for the content URLs. What should make Firebase Analytics work as provided in the first question.
References
Protocol interception documentation.
Example
This is an example of how you can serve local app as loaded by HTTP protocol and simulate regular browser work to use http protocol with bundled web application. This will allow you to add Firebase Analytics. It supports poorly HTTP data upload, but you can do it on your own depending on the goals.
index.js
const {app, BrowserWindow, protocol} = require('electron')
const http = require('http')
const {createReadStream, promises: fs} = require('fs')
const path = require('path')
const {PassThrough} = require('stream')
const mime = require('mime')
const MY_HOST = 'somehostname.example'
app.whenReady()
.then(async () => {
await protocol.interceptStreamProtocol('http', (request, callback) => {
const url = new URL(request.url)
const {hostname} = url
const isLocal = hostname === MY_HOST
if (isLocal) {
serveLocalSite({...request, url}, callback)
}
else {
serveRegularSite({...request, url}, callback)
}
})
const win = new BrowserWindow()
win.loadURL(`http://${MY_HOST}/index.html`)
})
.catch((error) => {
console.error(error)
app.exit(1)
})
async function serveLocalSite(request, callback) {
try {
const {pathname} = request.url
const filepath = path.join(__dirname, path.resolve('/', pathname))
const stat = await fs.stat(filepath)
if (stat.isFile() !== true) {
throw new Error('Not a file')
}
callback(
createResponse(
200,
{
'content-type': mime.getType(path.extname(pathname)),
'content-length': stat.size,
},
createReadStream(filepath)
)
)
}
catch (err) {
callback(
errorResponse(err)
)
}
}
function serveRegularSite(request, callback) {
try {
console.log(request)
const req = http.request({
url: request.url,
host: request.url.host,
port: request.url.port,
method: request.method,
headers: request.headers,
})
if (req.uploadData) {
req.write(request.uploadData.bytes)
}
req.on('error', (error) => {
callback(
errorResponse(error)
)
})
req.on('response', (res) => {
console.log(res.statusCode, res.headers)
callback(
createResponse(
res.statusCode,
res.headers,
res,
)
)
})
req.end()
}
catch (err) {
callback(
errorResponse(err)
)
}
}
function toStream(body) {
const stream = new PassThrough()
stream.write(body)
stream.end()
return stream
}
function errorResponse(error) {
return createResponse(
500,
{
'content-type': 'text/plain;charset=utf8',
},
error.stack
)
}
function createResponse(statusCode, headers, body) {
if ('content-length' in headers === false) {
headers['content-length'] = Buffer.byteLength(body)
}
return {
statusCode,
headers,
data: typeof body === 'object' ? body : toStream(body),
}
}
MY_HOST is any non-existent host (like something.example) or host that is controlled by admin (in my case it could be electron-app.rumk.in). This host will serve as replacement for localhost.
index.html
<html>
<body>
Hello
</body>
</html>
In Electron, is it possible to intercept requests against file:/// and redirect them to http?
I have checked the Electron protocol page, but it's not obvious if this is supported or not.
You could use protocol.registerHttpProtocol with the scheme file to intercept file: requests, and instead make an HTTP request.
Example (untested):
const {app, protocol} = require('electron')
const path = require('path')
app.on('ready', () => {
protocol.registerHttpProtocol('file', (request, callback) => {
const url = request.url.substr(8)
callback({url: 'http://example.com/' + url)})
}, (error) => {
if (error) console.error('Failed to register protocol')
})
})
Note: this sample may need refining as the file path may include the drive letter, which would be invalid for an HTTP request.
There is another way I was able to address this and interestingly the word "intercept" in the question has a lot to do with it :)
There is a function interceptHttpProtocol() on the protocol object you can use.
Sample code:
app.on("ready", () => {
protocol.interceptHttpProtocol("http", function(request, callback) {
var parsedUri = url.parse(request.url);
var filePath = path.join(__dirname, parsedUri.pathname);
request.url = "file://" + filePath;
callback(request);
});
var mainWindow = new BrowserWindow();
mainWindow.loadURL("http://localhost/index.html");
});
Hope that helps
When I run the application from command prompt using npm start command it works well. It returning the result from speech api.
I am using binaryServer and binaryclient to stream audio to google cloud API.
When I create package for electron application everything works but it not returning the result from speech api.
Here are my code snippe:
Package.json
{
"name": "test",
"version": "1.0.0",
"description": "test Web Server",
"main": "main.js",
"scripts": {
"start": "electron main.js"
},
"devDependencies": {
"electron": "^1.4.12"
},
"dependencies": {
"binaryjs": "^0.2.1",
"connect": "^3.3.4",
"biased-opener": "^0.2.8",
"serve-static": "^1.9.1",
"uaparser": "^0.0.2",
"#google-cloud/speech" : "^0.5.0"
}
}
Here is my main.js
app.on('ready', function () {
load_app();
});
var workerProcess = child_process.spawn('node', __dirname + '/binaryServer.js');
workerProcess.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
workerProcess.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
workerProcess.on('close', function (code) {
console.log('child process exited with code ' + code);
});
processes.push(workerProcess);
function load_app () {
// Launches the browser window
mainWindow = new BrowserWindow({ width: 1080, height: 1920 });
// Load just launched server in browser window
mainWindow.loadURL("http://localhost:" + config.port);
if (config.devMode) {
mainWindow.webContents.openDevTools();
}
else {
mainWindow.setFullScreen(true);
}
}
here is my binary server
var binaryServer = require('binaryjs').BinaryServer,
https = require('http'),
connect = require('connect'),
serveStatic = require('serve-static');
var config = require('./config');
var server = connect()
.use(serveStatic(__dirname));
var speech = require('#google-cloud/speech')({
projectId: config.speech.projectId,
keyFilename: config.speech.keyFilename
});
httpServer = https.createServer(server);
httpServer.timeout = 0;
httpServer.listen(config.port);
var binarySer = binaryServer({ server: httpServer });
console.log("server pid" + process.pid);
binarySer.on('connection', function (client) {
console.log("new connection...");
client.on('stream', function (stream, meta) {
var options = {
config: {
encoding: 'LINEAR16',
sampleRate: meta.sampleRate,
languageCode: "en-IN"
},
singleUtterance: false,
interimResults: true,
verbose: true
};
// Create a recognize stream
const recognizeStream = speech.createRecognizeStream(options)
.on('error', console.error)
.on('data', function (data) { if (stream.writable && !stream.destroyed) stream.write(data) }); // send data to client
if (recognizeStream.writable && !recognizeStream.destroyed && stream.readable && !stream.destroyed)
stream.pipe(recognizeStream); // pipe audio to cloud speech
});
client.on('close', function () {
console.log("Connection Closed");
});
});
Thanks for your help
Taking a shot in the dark here (without much familiarity with binaryServer, which realistically could be the issue). I'm also a bit unclear about where the audio stream actually comes from:
Electron packages its own version of V8. When you run npm install it will install (or compile on the fly) the native binaries targeted for the version of V8 that are installed on your machine (local version). When you spawn the child process it uses that same local version.
However, when you package your electron app it will try to spawn the process with Electron's version of V8 and there will be binary incompatibilities.
Put simply
[Your version of V8] != [Electron's version of V8]
On to potential solutions
Sonus is compatible with
Electron provided that you
Re-compile dependencies with
electron-recompile