I´m using "#pnp/sp": "^3.0.3", I have this code
const sp = spfi().using(SPFx(props.context));
const item = {
Title: mail,
URL: { Url: url.trim(), Description: name.trim() },
};
await sp.web.lists.getById(props.list).items.add(item);
It works, I can find the item in the list. It´s added.
If I have the page open 30 minutes and insert a new item it fails with this error
Error: Error making HttpClient request in queryable [403] ::> {"odata.error":{"code":"-2130575252, Microsoft.SharePoint.SPException","message":{"lang":"en-US","value":"The security validation for this page is invalid and might be corrupted. Please use your web browser's Back button to try your operation again."}}}
It´s going to be solved in version 3.2.0
But doesn´t work with
const sp = spfi().using(SPFx(props.context));
It does with
import { spfi, SPBrowser } from "#pnp/sp";
....
const sp = spfi().using(
SPBrowser({
baseUrl: props.context.pageContext.web.absoluteUrl,
}));
Related
I managed to subscribe to a Youtube Feed through https://pubsubhubbub.appspot.com/subscribe on a web browser, I've been trying to refresh my subscription to PubSubHubbub through Fetch on NodeJS, the code I used is below
const details = {
'hub.mode': 'subscribe',
'hub.topic': 'https://www.youtube.com/xml/feeds/videos.xml?channel_id=${process.env.ID}',
'hub.callback': process.env.callback,
'hub.secret': process.env.secret
};
const endpoint = 'http://pubsubhubbub.appspot.com/subscribe'
var formBody = [];
for (const property in details) {
const encodedKey = encodeURIComponent(property);
const encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");
const result = await fetch(endpoint, { method: "POST", body: formBody, 'Content-Type': 'application/x-www-form-urlencoded'})
console.log(result.status, await result.text())
Expected:
Status 204
Actual:
Status 400, content: "Invalid value for hub.mode:"
I expected at least for the content to tell me what the invalid value was, however it ended up being blank, it appears to me that it did not manage to read the POSTed content at all. I'm looking for ways to improve my code so that I don't encounter this problem.
I realised that I was supposed to specify in the content type header that charset=UTF-8. I'm not particularly well-versed in sending requests as of yet so this is definitely an eye-opener for me. After adding it in the server responds with 204 as expected and so I'll close my question.
A workout that I tried while trying to fix this was to import the exec() function from child_process module to run cURL and post the request instead. However I would recommend to stick to one language to make things more readable and using exec() runs commands directly from the shell which may have undesirable effects.
I am using the Youtube Data API to insert a video.
The I use the API to insert a "commentThread" to the video, as described here in the doc. Here is my code:
import { google } from "googleapis";
const googleApiClient = new google.auth.OAuth2(
GOOGLE_CLIENT_SECRET.web.client_id,
GOOGLE_CLIENT_SECRET.web.client_secret,
GOOGLE_CLIENT_SECRET.web.redirect_uris[0]
);
googleApiClient.credentials = tokens;
google.options({ auth: googleApiClient });
const apiYoutube = google.youtube({ version: "v3" });
await apiYoutube.commentThreads.insert({
part: ["snippet"],
requestBody: {
snippet: {
videoId,
topLevelComment: {
snippet: {
textOriginal: "Hello world!",
},
},
},
},
});
Depending on the video visibility, the response differs:
if visibility is "private", I get a 403 error:
{
message: 'The comment thread could not be created due to insufficient permissions. The request might not be properly authorized.',
domain: 'youtube.commentThread',
reason: 'forbidden',
location: 'body',
locationType: 'other'
}
I am positive that my access token (acquired through an oauth2 process) has the correct scope: "https://www.googleapis.com/auth/youtube.force-ssl"
if visibility is "public" or "unlisted", I get a 400 error:
{
message: 'This action is not available for the item.',
domain: 'youtube.mfk',
reason: 'mfkWrite'
}
In the youtube console, in Settings > Upload defaults > Avanced settings > comments, it is set to "Hold potentially inappropriate comments for review". I have also tried "Allow all comments".
How can I fix this issue and publish comments to my video?
I am aware of this similar question and tried the various suggestions but it still does not work and the API may have evolved.
When doing write operations(save, delete), Mongo Error occurs on my Nodejs server. Error code is 301.
I'm using TypeORM v0.2.29 and mongodb v3.6.3 right now. The database is AWS DocumentDB.
This is simplified server code:
import { createConnections } from 'typeorm';
import { readFileSync } from 'fs';
import ObjectID from 'bson-objectid';
const [mongodb, ...] = await createConnections([
{
url: 'mongodb://<username>:<password>#docdb~~.amazonaws.com/<database>?replicaSet=rs0&readPreference=secondaryPreferred',
ssl: true,
sslValidate: true,
sslCA: [readFileSync('/path/to/ssl/ca')],
},
{...}
]);
const repository = mongodb.getMongoRepository(SomeEntity);
const entity = new SomeEntity();
entity.id = ObjectID.generate();
entity.someValue = someValue;
await repository.findOne(1); //works fine
const result = await repository.save([entity]); //MongoError occurs
Edit: Turns out id is defined before the entity is persisted. Is that could be a problem?
Edit 2: I tried on development enviornment(it took quite amount of time to set up. sorry for give you the information late), and I got Retryable writes not supported error. This is full error message:
However, no matter if I put retryWrites=false option on query string, it gives the same error.
What I have:
I adapted this example from Microsoft docs.
// functions.js
/**
* Get data
* #customfunction
* #returns {string[][]}
*/
async function getData() {
try {
const url = "https://api.example.com/some/objects/";
const token = await OfficeRuntime.storage.getItem("Token");
const authString = `Token ${token.toString()}`;
const response = await fetch(url, {
headers: { Authorization: authString }
});
if (!response.ok) {
throw new Error(response.statusText);
}
const jsonResponse = await response.json();
return jsonResponse.map(obj => {return [obj.id.toString(), obj.name]};
} catch (error) {
return [["ERROR", error.message]];
}
}
Added api.example.com to <AppDomains>
Item "Token" is present in OfficeRuntime.storage
Same API call with Postman works fine
The Add-In is not served from localhost (because of CORS reasons etc.)
What I get:
Because it is not developed locally it is very hard to debug ui-less custom functions. Therefore the only visible error I get so far, is the one I receive and return to Excel in the catch-block. It is an unhelpful error message: Network request failed
Can anyone help me with any suggestions?
Reason why it did not work was a known issue that custom functions run in a separate JavaScript runtime as described here. This runtime allows only CORS-safelisted request header because it lacks of CORS-Preflight -> therefore the Network request failed error with the Authorization header.
How I solved it:
Configure the Excel-Add-in to use a shared JavaScript runtime as described here.
Add <script src="functions.js"></script> just before the <\head> element in taskpane.html as described here.
Build the project npm run build
Clear the cache as described in the first two steps here.
Run Excel and load your Add-in.
Has anyone been able to get the google-api-nodejs-client to successfully insert a moment?
Whatever I try, I get a generic 400 "Invalid value" error but am unable to narrow down the invalid value because the API Explorer doesn't work either.
Would it be because of the missing data-requestvisibleactions parameter? I'm using passport.js's require('passport-google-oauth').OAuth2Strategy for handling oauth access, and that part is working fine, but I have no idea how to incorporate requestvisibleactions into the oauth request flow since this is definitely not originating from a clientside form.
Here's a snippet of what I'm trying to do (using the latest version of googleapis, v1.0.2):
var google = require('googleapis')
var auth = new google.auth.OAuth2()
auth.setCredentials({
'access_token': user.token
})
google.plus('v1').moments.insert({
collection: 'vault',
userId: 'me',
debug: true,
resource: {
type: "http://schemas.google.com/AddActivity",
target: {
type: "http://schema.org/CreativeWork",
url: "...omitted...",
image: "...omitted...",
description: "test",
name: "test"
}
},
auth: auth
}, function (err, response) {
if (err) {
console.error(err)
res.send(err.code, err)
} else {
console.log(response)
res.send(200)
}
})
ref 1 (out-of-date w.r.t. an older version of googleapis)
ref 2 (client-side, where the use of data-requestvisibleactions is more obvious)
As you speculated, you need the request_visible_actions parameter as part of the URL calling the oauth endpoint.
It looks like the current version of passport-google-oauth doesn't support this parameter. Judging by several of the open issues and pull requests, it isn't clear that the author will respond to requests to add it either. You have two possible options:
Switch to using the OAuth support that is included in google-api-nodejs-client
Patch the passport-google-oauth code. (And possibly submit a pull request in the hopes it will be useful to someone else.)
I don't use passport.js or the passport module in question, so I can't test this, but based on the github repository, I think you can insert the following in lib/passport-google-oauth/oauth2.js after line 136 and before the return statement:
if (options.requestVisibleActions) {
// Space separated list of allowed app actions
// as documented at:
// https://developers.google.com/+/web/app-activities/#writing_an_app_activity_using_the_google_apis_client_libraries
// https://developers.google.com/+/api/moment-types/
params['request_visible_actions'] = options.requestVisibleActions;
}