It's the first time that I work with evernote,
Like the example given in the JS SDK, I create my client with the token that I get from the OAuth and I get all the notebooks of my current user so it was good for me.
But I'm facing a problem that I can't understand, when I use any method of my shared store it throw an Thrift exception with error code 12 and giving the shard id in the message.
I know that 12 error code is that the shard is temporary unavailable..
But I know that it's another thing because it's not temporary...
I have a full access api key, it work with the note store, did I miss something ?
// This is the example in the JS SDK
var linkedNotebook = noteStore.listLinkedNotebooks()
.then(function(linkedNotebooks) {
// just pick the first LinkedNotebook for this example
return client.getSharedNoteStore(linkedNotebooks[0]);
}).then(function(sharedNoteStore) {
// /!\ There is the problem, throw Thrift exception !
return sharedNoteStore.listNotebooks().then(function(notebooks) {
return sharedNoteStore.listTagsByNotebook(notebooks[0].guid);
}).then(function(tags) {
// tags here is a list of Tag objects
});
});
this seems to be an error with the SDK. I created a PR (https://github.com/evernote/evernote-sdk-js/pull/90).
You can work around this by using authenticateToSharedNotebook yourself.
const client = new Evernote.Client({ token, sandbox });
const noteStore = client.getNoteStore();
const notebooks = await noteStore
.listLinkedNotebooks()
.catch(err => console.error(err));
const notebook = notebooks.find(x => x.guid === guid);
const { authenticationToken } = await client
.getNoteStore(notebook.noteStoreUrl)
.authenticateToSharedNotebook(notebook.sharedNotebookGlobalId);
const client2 = new Evernote.Client({
token: authenticationToken,
sandbox
});
const noteStore2 = client2.getNoteStore();
const [notebook2] = await noteStore2.listNotebooks();
noteStore2.listTagsByNotebook(notebook2.guid)
Related
I'm trying to use javascript to implement this Telegram PHP example, but the hashes don't match. I ran the example's php code; it also failed, and the hash returned by the example and mine are identical. I'm wondering if it has anything to do with my bot settings (I set my domain to 127.0.0.1 and try another https domain - still failed). I'm completely stuck and have no idea how to make it work.
My code is as follows:
'use strict';
const sha256 = require('crypto-js/sha256');
const hmacSHA256 = require('crypto-js/hmac-sha256');
const Hex = require('crypto-js/enc-hex');
const { ValidationError } = require('objection');
const data = {
id: 5528016998,
first_name: 'Lê Văn',
last_name: 'Hùng',
username: 'HungLV46',
photo_url: 'https://t.me/i/userpic/320/gy_L5Q2zLLZyUrtCw0Fh9D0oy0CuabiM2A0-68FY27Inz94yP7ypxCrAF7G7_asy.jpg',
auth_date: 1670774122,
hash: '893e4bd66128d8696d63aa285b0aff6e8b970cbe9c9e43dacfa9e2da7420c16c'
};
function verifyAuthorization(params) {
if ((new Date() - new Date(params.auth_date * 1000)) > 86400000) { // milisecond
throw new ValidationError('Authorization data is outdated');
}
const verificationParams = { ...params };
delete verificationParams.hash;
const message = Object.keys(verificationParams)
.map(key => `${key}=${verificationParams[key]}`)
.sort().join('\n');
const secretKey = sha256('xxxx'); // replace with the token of my bot
const hash = Hex.stringify(hmacSHA256(message, secretKey));
if (hash !== params.hash) {
throw new ValidationError('Authorization data is not from telegram!');
}
}
verifyAuthorization(data);
similar question
Edit:
After experimenting with the login widget for some time, I tried to print return value to the developer console of Chrome (pressing f12, console tab), and then run my code again. The 2 hashes awardly match!.
I initially got the user info and hash from the response of this API, POST https://oauth.telegram.org/auth/get?bot_id=xxx in network-tab, and it turned out the response of API in network-tab was different from the response printed in console-tab.
I tried some more time, and the response of the API suddenly worked well with my function. Now I am just curious about why?
Description of the problem:
My App aim is to store family spending in Firebase Realtime Database. I want that, when a new spending is stored, a notification is sent to all other devices.
I try to send a notification to a single device and it works fine, but when I try to get all the tokens in an array, I have an error:
TypeError: Cannot convert undefined or null to object at Function.keys ().
code of index.js :
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
exports.androidPushNotification = functions.database
.ref("{nodo}/spese/{spesaPush}")
.onCreate(async (snapshot, context) => {
const original = snapshot.val();
const getDeviceTokensPromise = admin.database()
.ref(`/utenti/{tutti}/token`).once('value');
let tokensSnapshot;
let tokens;
tokensSnapshot = await getDeviceTokensPromise;
// This is the line generating the errors.
// If I get only a specific token and
// use tokens = tokensSnapshot.val(); anything works fine
tokens = Object.keys(tokensSnapshot.val());
const result = original.chi + " ha speso " +
original.costo + " € per acquistare " +
original.desc;
console.log(result);
const payload = {
notification: {
title: 'New spending inserted!',
body: result,
}
};
const response = await admin.messaging().sendToDevice(tokens, payload);
return result;
});
It seems that values are not reached yet, but I thought that the keyword await lets system to wait until all data are available. From the log I noticed that the value I need is null and I don't understand why.
If I use this line of code:
const getDeviceTokensPromise = admin.database()
.ref(`/utenti/SpecificUser/token`).once('value');
....
//then
tokens = tokensSnapshot.val();
The notification is sent to the device that has the token under the name of "SpecificUser"
EDIT:
I provide a pic of my db. I notice that none of the field is null, so I don't know why I see this error
Thank you to anyone that helps me
i had same error and it is solve by database...
when i saw my database values unfortunately i stored undefined value so my whole result got error like you...
see your whole values and fields that store values properly.
const Discord = require("discord.js")
const snekfetch = require("snekfetch")
const client = new Discord.Client({disableEveryone: false});
//const CSGO = require("csgo-api"); // Import the npm package.
//const jb = new CSGO.Server('185.198.75.5', '27015') // Set the IP with port.
var prefix2 = "!"
client.on('ready', async ()=> {
snekfetch.get("http://query.li/api/csgo/185.198.75.5/27015").then(r => console.log(r.body.game.players.name));
//jb.getOnlinePlayers().then(data => console.log(data)) // Get & log the data
});
Hello friends, I'm trying to print the players section on http://query.li/api/csgo/185.198.75.5/27015 to message.channel.send but it gives undefined can you help me?
I'm using Google Translate sorry my English so bad :/
You are trying to get the body of the result. But it is null. Your result contains these children: game, whois, status, banner_url, and cached.
And also, your players are an array. So you should select an index to console.log().
Try this:
snekfetch.get("http://query.li/api/csgo/185.198.75.5/27015").then(r => console.log(r.game.players[0].name));
You can use this web site to beautify your response JSON.
EDIT:
If you want to print the names of all players then you can use a foreach() loop for players. Like this:
snekfetch.get("http://query.li/api/csgo/185.198.75.5/27015").then(r => {
r.game.players.forEach(player => {
console.log(player.name)
});
}
);
I have no clue, but it seems that when I try to get into an attribute of an element from the JSON file it says that it's null.
Still got npm audit problems :(, what do you think about that?
Here is the EDITED code that I did so far:
export const data = require('./file.json');
export let DATA = data as Type[];
let temp = DATA;
app.post('/api/tickets', (req, res) => {
// load past data into json string
const past_data = JSON.stringify(temp);
// load new data into json string
const new_element = JSON.stringify(req.params.formData)
if (new_element !== "")
{
// concat both string to 1 json string, then write into fs
fs.writeFile("./file.json",[past_data,new_element],(err) => {
if (err) throw err;
});
}
// send it back as response to request
const new_data = JSON.parse([past_data,new_element].toString());
res.send(new_data);
});
app.delete('/api/tickets/:id', (req,res) => {
// fined requested ticket based on id in global temp
const ticket = temp.find(t => t.id === (req.params.id));
if (typeof ticket !== 'undefined') {
const index = temp.indexOf(ticket);
// remove it from global temp
temp.splice(index, 1)
}
// create json string out of global temp
const data_after_delete = JSON.stringify(temp);
// write it straight into fs
fs.writeFile("./file.json",data_after_delete,(err) => {
if (err) throw err;
});
// send it back to requester
const new_data = JSON.parse(data_after_delete);
res.send(new_data);
});
One object from the json file before I write into it:
[
{
"id": "81a885d6-8f68-5bc0-bbbc-1c7b32e4b4e4",
"title": "Need a Little Help with Your Site? Hire a Corvid Web Developer",
"content": "Here at Wix we strive to support you with this community forum, API references, articles, videos and code examples. But sometimes you might need a little extra help to get your site exactly the way you want it. \nHire a developer from the Wix Arena, an online marketplace with top Corvid web developers from around the world. Submit your project details here, and we’ll find the right professional for you.",
"userEmail": "jug#nesetal.af",
"creationTime": 1542111235544,
"labels": ["Corvid", "Api"]
},
One object from the json file after I write into it:
["[\"[\\\"[\\\\\\\"[{\\\\\\\\\\\\\\\"id\\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\"81a885d6-8f68-5bc0-bbbc-1c7b32e4b4e4\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"title\\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\"Need a Little Help with Your Site? Hire a Corvid Web Developer\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"content\\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\"Here at Wix we strive to support you with this community forum, API references, articles, videos and code examples. But sometimes you might need a little extra help to get your site exactly the way you want it. \\\\\\\\\\\\\\\\nHire a developer from the Wix Arena, an online marketplace with top Corvid web developers from around the world. Submit your project details here, and we’ll find the right professional for you.\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"userEmail\\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\"jug#nesetal.af\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"creationTime\\\\\\\\\\\\\\\":1542111235544,\\\\\\\\\\\\\\\"labels\\\\\\\\\\\\\\\":[\\\\\\\\\\\\\\\"Corvid\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"Api\\\\\\\\\\\\\\\"]},
You should only use JSON.stringify when writing to a file, and JSON.parse when reading from a file (if you don't use require which does the parsing implicitly). Manipulate your data as plain objects and arrays, not as JSON strings - that will only damage the structure as you noticed.
export let DATA: Type[] = require('./file.json');
function save() {
const jsonString = JSON.stringify(DATA);
// ^^^^^^^^^^^^^^^^^^^^^ only call it here
fs.writeFile("./file.json", jsonString, (err) => {
if (err) throw err;
});
}
app.post('/api/tickets', (req, res) => {
if (req.params.formData) {
const new_element = req.params.formData; // might need a JSON.parse() if it's a a json string
// add to global temp by array manipulation
DATA.push(new_element);
save();
}
// send it back as response to request
res.send(DATA);
});
app.delete('/api/tickets/:id', (req,res) => {
// find requested ticket based on id in global temp
const ticket = DATA.findIndex(t => t.id === (req.params.id));
if (ticket !== -1) {
// remove it from global temp
DATA.splice(index, 1);
save();
}
// send it back to requester
res.send(DATA);
});
I am attempting to perform an update to a MongoDB document (using mongoose) by first using .findById to get the document, then updating the fields in that document with new values. I am still a bit new to this so I used a tutorial to figure out how to get it working, then I have been updating my code for my needs. Here is the tutorial: MEAN App Tutorial with Angular 4. The original code had a schema defined, but my requirement is for a generic MongoDB interface that will simply take whatever payload is sent to it and send it along to MongoDB. The original tutorial had something like this:
exports.updateTodo = async function(todo){
var id = todo.id
try{
//Find the old Todo Object by the Id
var oldTodo = await ToDo.findById(id);
}catch(e){
throw Error("Error occured while Finding the Todo")
}
// If no old Todo Object exists return false
if(!oldTodo){
return false;
}
console.log(oldTodo)
//Edit the Todo Object
oldTodo.title = todo.title
oldTodo.description = todo.description
oldTodo.status = todo.status
console.log(oldTodo)
try{
var savedTodo = await oldTodo.save()
return savedTodo;
}catch(e){
throw Error("And Error occured while updating the Todo");
}
}
However, since I don't want a schema and want to allow anything through, I don't want to assign static values to specific field names like, title, description, status, etc. So, I came up with this:
exports.updateData = async function(update){
var id = update.id
// Check the existence of the query parameters, If they don't exist then assign a default value
var dbName = update.dbName ? update.dbName : 'test'
var collection = update.collection ? update.collection : 'testing';
const Test = mongoose.model(dbName, TestSchema, collection);
try{
//Find the existing Test object by the Id
var existingData = await Test.findById(id);
}catch(e){
throw Error("Error occurred while finding the Test document - " + e)
}
// If no existing Test object exists return false
if(!existingData){
return false;
}
console.log("Existing document is " + existingData)
//Edit the Test object
existingData = JSON.parse(JSON.stringify(update))
//This was another way to overwrite existing field values, but
//performs a "shallow copy" so it's not desireable
//existingData = Object.assign({}, existingData, update)
//existingData.title = update.title
//existingData.description = update.description
//existingData.status = update.status
console.log("New data is " + existingData)
try{
var savedOutput = await existingData.save()
return savedOutput;
}catch(e){
throw Error("An error occurred while updating the Test document - " + e);
}
}
My original problem with this was that I had a lot of issues getting the new values to overwrite the old ones. Now that that's been solved, I am getting the error of "TypeError: existingData.save is not a function". I am thinking the data type changed or something, and now it is not being accepted. When I uncomment the static values that were in the old tutorial code, it works. This is further supported by my console logging before and after I join the objects, because the first one prints the actual data and the second one prints [object Object]. However, I can't seem to figure out what it's expecting. Any help would be greatly appreciated.
EDIT: I figured it out. Apparently Mongoose has its own data type of "Model" which gets changed if you do anything crazy to the underlying data by using things like JSON.stringify. I used Object.prototype.constructor to figure out the actual object type like so:
console.log("THIS IS BEFORE: " + existingData.constructor);
existingData = JSON.parse(JSON.stringify(update));
console.log("THIS IS AFTER: " + existingData.constructor);
And I got this:
THIS IS BEFORE: function model(doc, fields, skipId) {
model.hooks.execPreSync('createModel', doc);
if (!(this instanceof model)) {
return new model(doc, fields, skipId);
}
Model.call(this, doc, fields, skipId);
}
THIS IS AFTER: function Object() { [native code] }
Which showed me what was actually going on. I added this to fix it:
existingData = new Test(JSON.parse(JSON.stringify(update)));
On a related note, I should probably just use the native MongoDB driver at this point, but it's working, so I'll just put it on my to do list for now.
You've now found a solution but I would suggest using the MongoDB driver which would make your code look something along the lines of this and would make the origional issue disappear:
// MongoDB Settings
const MongoClient = require(`mongodb`).MongoClient;
const mongodb_uri = `mongodb+srv://${REPLACE_mongodb_username}:${REPLACE_mongodb_password}#url-here.gcp.mongodb.net/test`;
const db_name = `test`;
let db; // allows us to reuse the database connection once it is opened
// Open MongoDB Connection
const open_database_connection = async () => {
try {
client = await MongoClient.connect(mongodb_uri);
} catch (err) { throw new Error(err); }
db = client.db(db_name);
};
exports.updateData = async update => {
// open database connection if it isn't already open
try {
if (!db) await open_database_connection();
} catch (err) { throw new Error(err); }
// update document
let savedOutput;
try {
savedOutput = await db.collection(`testing`).updateOne( // .save() is being depreciated
{ // filter
_id: update.id // the '_id' might need to be 'id' depending on how you have set your collection up, usually it is '_id'
},
$set: { // I've assumed that you are overwriting the fields you are updating hence the '$set' operator
update // update here - this is assuming that the update object only contains fields that should be updated
}
// If you want to add a new document if the id isn't found add the below line
// ,{ upsert: true }
);
} catch (err) { throw new Error(`An error occurred while updating the Test document - ${err}`); }
if (savedOutput.matchedCount !== 1) return false; // if you add in '{ upsert: true }' above, then remove this line as it will create a new document
return savedOutput;
}
The collection testing would need to be created before this code but this is only a one-time thing and is very easy - if you are using MongoDB Atlas then you can use MongoDB Compass / go in your online admin to create the collection without a single line of code...
As far as I can see you should need to duplicate the update object. The above reduces the database calls from 2 to one and allows you to reuse the database connection, potentially anywhere else in the application which would help to speed things up. Also don't store your MongoDB credentials directly in the code.