How to extract 100% correct data from website by node-email-extractor? - email-ext

I am using a node email extractor for email extraction from websites. But it's just giving 10-15% of the data. Rest of the data are either incorrect or null. What would be the best package manager for nodejs for extracting email from websites?
Codes are below:
const email = require("node-email-extractor").default
const Excel = require('exceljs');
(async () => {
var emailData = await email.url('https://www.studioonesevensalon.com/')
console.log(emailData);
})()
Output is not valid here
I am expecting a valid email which is present in that website.

Related

XERO-NODE SDK => How to choose a specific email template

I am using the Xero-node SDK to automatically create client invoices which works well.
At the end of the process, I would like to automatically email the client the invoice.
In the documentation it has the following example:
const xeroTenantId = 'YOUR_XERO_TENANT_ID';
const invoiceID = '00000000-0000-0000-0000-000000000000';
const requestEmpty: RequestEmpty = { };
try {
const response = await xero.accountingApi.emailInvoice(xeroTenantId, invoiceID, requestEmpty);
console.log(response.body || response.response.statusCode)
} catch (err) {
const error = JSON.stringify(err.response.body, null, 2)
console.log(`Status Code: ${err.response.statusCode} => ${error}`);
}
I have 2 questions:
The requestEmpty method does not work in javascript. Does anyone know the correct structure of requestEmpty?
I have used requestEmpty = { } but this throws an error => even though the system does actually send an email (probably a bug)
AND....
Is there a way for me to specify the email template that I would like the invoice to use (if I have specific templates setup in the web version)? Currently it seems to use the default Xero email template.
If you don't get an answer to your first query here, please can you raise it on the SDK page in Github and the Xero SDK team will look into this for you.
With regards to point 2, it is not possible to choose the email template when sending through the API, a basic template is used.

How to pass tokenID to queryFilter provided by ethers in ERC1155 standard?

I want to get all the transfers from block_B to block_B but for specific token.
I have faced similar issue while trying to get ERC721 transfers.
It looked like this:
const contract = new ethers.
const filter = contract.filters.Transfer();
const events = await contract.queryFilters(filter, block_A, block_B);

Issue when downloading a file from a folder in sharepoint document library in OFfice 365 using Microsoft Graph

I was able to get Drive object for my IT folder under my xxx.sharepoint.com teamsite in office 365
var drives = await graphClient.Sites["xxx.sharepoint.com"].Drives.Request().GetAsync();
//// Get https://xxx.sharepoint.com/IT drive
var driveIT = drives.CurrentPage.Where(d => d.DriveType == "documentLibrary" && d.Name == "IT").FirstOrDefault();
And, I was able to get the DriveItem object for a test.txt file under that IT folder
var testfile = await graphClient.Sites["xxx.sharepoint.com"].Drives[driveIT.Id].Root.ItemWithPath("test.txt").Request().GetAsync();
However, when I try to download the content I get this error
Code: invalidRequest
Message: Provided identifier is malformed - site collection id is not valid
// this cause the error
var streamtest = await graphClient.Sites["xxx.sharepoint.com"].Drives[driveIT.Id].Root.ItemWithPath("test.txt").Content
.Request()
.GetAsync();
// this also cause the same error.
//var streamtest = await graphClient.Sites["xxx.sharepoint.com"].Drives[driveIT.Id].Items[$"{testfile.Id}"].Content
// .Request()
// .GetAsync();
However, I am able to upload a text file under my IT folder.
var uploadedFile1 = await graphClient.Sites["xxx.sharepoint.com"].Drives[driveIT.Id].Root.ItemWithPath("New_testupload_msgraph.txt").Content.Request().PutAsync(stream1);
And, I was able to upload and download test files to/from my onedrive
var uploadedFile1 = await graphClient.Sites["xxx.sharepoint.com"].Drives[driveIT.Id].Root.ItemWithPath("New_testupload_msgraph.txt").Content.Request().PutAsync<DriveItem>(stream1);
var dlteststream = await graphClient.Me.Drive.Items["01JZT44T6EFIIYDTEEJNHLPJGYC3A4VO2H"].Content.Request().GetAsync();
Can any body help with this issue?
I tested your code in my SPO environment and i am able to reproduce this error.
I modified the code as below then it works well:
Change ...graphClient.Sites["xxx.sharepoint.com"]... to :
graphClient.Sites[siteid]
site id is like:
"abc.sharepoint.com,8f9xxxxxxx80e1e40d31,af1659xxxx-a12d-2a47800cc52d"
Here is my test demo, you may take a reference:
https://github.com/kongmengfei/sharedproject/blob/master/TeamifySharePointClassicSite/TeamifySharePointClassicSite/DownloadfileGraph.cs
BR

Using wildcards in firestore get query

I want to create a cloud function in firebase that gets triggered whenever a user logs in for the first time. The function needs to add the UID from the authentication of the specific user to a specific, already existing document in firestore. The problem is that the UID needs to be added to a document of which I do not know the location. The code I have right now doesn't completely do that, but this is the part where it goes wrong. The database looks like this when simplified
organisations
[randomly generated id]
people
[randomly generated id] (in here, a specific document needs to be found based on known email
adress)
There are multiple different organisations and it is unknown to which organisation the user belongs. I thought of using a wildcard, something like the following:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
console.log('function ready');
//Detect first login from user
//if(firebase.auth.UserCredential.isNewUser()){
if(true){
//User is logged in for the first time
//const userID = firebase.auth().currentUser.UID;
//const userEmail = firebase.auth().currentUser.email;
const userID = '1234567890';
const userEmail = 'example#example.com';
//Get email, either personal or work
console.log('Taking a snapshot...');
const snapshot = db.collection('organisations/{orgID}/people').get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
console.log(doc.data());
});
});
}
I commented out some authentication-based lines for testing purposes. I know the code still runs, because hardcoding the orgID does return the right values. Also, looping trough every organisation is not an option, because I need to have the possibility of having a lot of organisations.
A lot of solutions are based on firestore triggers, like onWrite, where you can use wildcards like this.
However, I don't think that's possible in this case
The solution to the problem above:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
//Add UID to document in DB[FMIS-94]
//Detect first login from user
//if(firebase.auth.UserCredential.isNewUser()){
if(true){
//User is logged in for the first time
//const userID = firebase.auth().currentUser.UID;
//const userEmail = firebase.auth().currentUser.email;
const userID = '1234567890';
const userEmail = 'example#example.com';
var docFound = false;
//Get email, either personal or work
console.log('Taking a snapshot...');
//Test for work email
const snapshot = db.collectionGroup('people').where('email.work', '==', userEmail).get()
.then(function(querySnapshot){
querySnapshot.forEach(function(doc){
//work email found
console.log('work email found');
console.log(doc.data());
docFound = true;
const organisationID = doc.ref.parent.parent.id;
writeUID(doc.id, userID, organisationID);
});
});
if(!docFound){
//Test for personal email
const snapshot = db.collectionGroup('people').where('email.personal', '==', userEmail).get()
.then(function(querySnapshot){
querySnapshot.forEach(function(doc){
//personal email found
console.log('personal email found');
console.log(doc.data());
const organisationID = doc.ref.parent.parent.id;
writeUID(doc.id, userID, organisationID);
});
});
}
}
async function writeUID(doc, uid, organisationID){
const res = db.collection(`organisations/${organisationID}/people`).doc(doc).set({
userId: uid
}, { merge: true });
}
This was exactly what I needed, thanks for all your help everyone!
It is not possible to trigger a Cloud Function when a user logs in to your frontend application. There is no such trigger among the Firebase Authentication triggers.
If you want to update a document based on some characteristics of the user (uid or email), you can do that from the app, after the user has logged in.
You mention, in your question, "in here, a specific document needs to be found based on known email address". You should first build a query to find this document and then update it, all of that from the app.
Another classical approach is to create, for each user, a specific document which uses the user uid as document ID, for example in a users collection. It is then very easy to identify/find this document, since, as soon the user is logged in you know his uid.
I'm not sure I understand you correctly, but if you want to search across all people collections not matter what organizations document they're under, the solution is to use a collection group query for that.
db.collectionGroup('people').get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
console.log("user: "+doc.id+" in organization: "+doc.ref.parent.parent.id);
});
});
This will return a snapshot across all people collections in your entire Firestore database.
First setup Cloud Functions according to the official Documentation.
Then after setting up create functions like this:
exports.YOURFUNCTIONNAME= functions.firestore
.document('organisations/[randomly generated id]/people/[randomly generated id]')
.oncreate(res => {
const data = res.data();
const email = data.email;/----Your field name goes here-----/
/-----------------Then apply your logic here---------/
)}
This will triggers the function whenever you create the People -> Random ID

Microsoft Azure Custom Vision API nodeJS - classifyImageUrl() error "BadRequestImageUrl"

I try atm to classify an image via the API from Microsoft on nodeJS.
The network is alreaday trained and I can "connect" to the my algorithm. I want to send a base64 string as a dataUri but then I get this error-message: "Code: BadRequestImageUrl, message: Invalid image url"
The variable "img" is a base64 string (from a FHIR-Observation-Object) and correct (on a webside the url works with the base64).
I try out to senda image from Wikipedia. But then I have an other error: "NoFoundIteration / Invalid iteration"
const PredictionAPIClient = require("azure-cognitiveservices-customvision-prediction");
const predictionKey = "xxxx";
const endPoint = "https://southcentralus.api.cognitive.microsoft.com"
const projectId = "xxxxx";
const publishedName = "myMLName";
...
var img = 'iVBORw0KGgoAAAANSUhEUgAAAgAAAAJmCAYAAA...'; //base64
...
tempUrl= { url: 'data:image/png;base64,' + img };
...
predictor.classifyImageUrl(projectId, publishedName, tempUrl)
.then((resultJSON) => {
console.log("RESULT ######################")
//console.log(resultJSON);})
.catch((error) => {
console.log("ERROR #####################");
console.log(error);}
);
I should get a JSON form Microsoft Azure with the results.
Have a look to the documentation of the API behind the package you are using: https://southcentralus.dev.cognitive.microsoft.com/docs/services/Custom_Vision_Prediction_3.0/operations/5c82db60bf6a2b11a8247c14
You can see that Classify has 2 methods:
ClassifyImage, which is using an image in application/octet-stream
ClassifyImageUrl, which is using an url for input
Data URL are not supported, you must use classic URL (and the image must be publicly accessible: don't use an URL pointing to an endpoint that need an authentication)
For your iteration error, make sure that you use your iteration name in publishedName, not your project name.
Example here, with value in field "Published as":

Resources