Migrating webRequest to declarativeNetRequest - google-chrome

Hi I was using webRequest in manifest V2 , I started getting below error
'webRequestBlocking' requires manifest version of 2 or lower.
So I am trying to convert my below existing code to declarativenetrequest
var responseListener = function (details) {
var rule = {
name: "Access-Control-Allow-Origin",
value: "*",
};
details.responseHeaders.push(rule);
var rule1 = {
name: "Access-Control-Allow-Methods",
value: "GET, PUT, POST, DELETE, HEAD, OPTIONS",
};
details.responseHeaders.push(rule1);
return { responseHeaders: details.responseHeaders };
};
chrome.webRequest.onHeadersReceived.addListener(
responseListener,
{
urls: [
"https://example.com/*",
"*://*.example1.com?test",
],
},
// extraInfoSpec
["blocking", "responseHeaders", "extraHeaders"]
);
So i tried replacing to chrome.declarativeNetRequest.onHeadersReceived.addListener(
And I got Uncaught TypeError: Cannot read properties of undefined (reading 'addListener').Can some one help me how the current function can be migrated to declarativeNetRequest.

The error you're seeing is because declarativeNetRequest provides a different API to webRequest and there are some additional steps for migration. You can learn more about the API in general here: https://developer.chrome.com/docs/extensions/reference/declarativeNetRequest/
For your use case, you can actually setup a rule declaratively in the manifest without needing to call any APIs at all! This is one of the benefits of the new API in general, which tries to move towards declarative rules rather than giving extensions access to web requests in-flight.
To start with, add the following to your extension manifest:
Copyright 2023 Google LLC.
SPDX-License-Identifier: Apache-2.0
"declarative_net_request" : {
"rule_resources" : [{
"id": "ruleset_1",
"enabled": true,
"path": "rules_1.json"
}]
},
"permissions": [
"declarativeNetRequest"
],
"host_permissions": [
"https://example.com/*"
]
This defines a new "ruleset" and also adds the required API and host permissions.
You can then create the file rules_1.json and put the desired rule inside:
Copyright 2023 Google LLC.
SPDX-License-Identifier: Apache-2.0
[
{
"id" : 1,
"priority": 1,
"action": {
"type": "modifyHeaders",
"responseHeaders": [
{ "header": "Access-Control-Allow-Origin", "operation": "set", "value": "*" },
{ "header": "Access-Control-Allow-Methods", "operation": "set", "value": "GET, PUT, POST, DELETE, HEAD, OPTIONS" }
]
},
"condition" : {
"urlFilter": "||example.com"
}
}
]
This adds the two headers as required. You can then reload your extension and should be good to go!
As a note, you won't see these headers reflected in Dev Tools. This is a bug which will hopefully be fixed in the future: https://bugs.chromium.org/p/chromium/issues/detail?id=1247400
If you want to check it's working, going to https://example.com and running the following in the console will output a list of headers, including the ones added by your extension: [...(await fetch("https://example.com")).headers].

Related

Can my bot server retrieve any information in the app manifest?

I am adding a new static tab to an existing teams app.
One of the new features is that the chat will publish a deep link to the static tab. This is creating a dilemna when I am contemplating deployment.
Obviously I can’t put my entire application up here, but we can assume a situation like this:
The manifest I have in production that is in the App Store looks like this:
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.9/MicrosoftTeams.schema.json",
"manifestVersion": "1.9",
"version": "2.0.1",
"id": "23232322-7676-4848-5555-44444444444",
"packageName": "xxxxx",
"developer": {
"name": "xxxxx",
"websiteUrl": "https://www.xxxx.com/",
"privacyUrl": "https://www.xxxx.com/legal/privacy",
"termsOfUseUrl": "https://www.xxxxx.com/legal/privacy"
},
"icons": {
"color": "color.png",
"outline": "outline.png"
},
"name": {
"short": "abra",
"full": "abra cadabra"
},
"description": {
"short": "short",
"full": "full"
},
"accentColor": "#FFFFFF",
"bots": [
{
"botId": "11111111-2222-3333-4444-555555555555",
"scopes": [
"personal"
],
"commandLists": [
{
"scopes": [
"personal"
],
"commands": [
{
"title": "Test",
"description": "Test"
}
]
}
],
"supportsFiles": false,
"isNotificationOnly": false
}
],
"permissions": [
"identity",
"messageTeamMembers"
],
"validDomains": [
"token.botframework.com",
"teams.microsoft.com",
"*.ngroc.io"
]
}
And in my bot in response to the “Test” command I return a simple text message, i.e.
return await step.prompt('textPrompt', { prompt: 'In the next version we will have a test tab' })
Now in development, I have added the following section to the manifest (after “bots”)
"staticTabs": [
{
"entityId": "conversations",
"scopes": [
"personal"
]
},
{
"entityId": "testtab”,
"contentBotId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"name": “Go To Test Tab",
"scopes": [ "personal" ]
},
{
"entityId": "about",
"scopes": [
"personal"
]
}
],
And I have updated the value of the version from 2.0.1 to 2.1.0
Now, in response to the “Test” message I am returning an adaptiveCard that looks like this:
{
type: 'AdaptiveCard',
version: '1.3',
body: [],
actions: [
{
type: 'Action.OpenUrl',
title: 'Go To Test Tab',
url: ‘https://teams.microsoft.com/l/entity/23232322-7676-4848-5555-44444444444/testtab’
}
]
}
This works very nicely and when I press the “go to Test Tab” it opens up the test tab as desired.
My problem is with deploying.
If I submit my new manifest to the App Store, without updating my production server, those testing the new version will continue to get the message “In the next version we will have a test tab” and be missing the link to the new tab.
If I update my production server now, before the update in the App Store, my current users will get the adaptive card with the button that will fail if they press it.
Clearly, neither of these options are good.
Ideally, my response should be something like:
If tabExists() {
Return {… the adaptive card }
Else {
return await step.prompt('textPrompt', { prompt: 'In the next version we will have a ‘test tab })
}
However, I don't know how to write "tabExists()" - I was thinking maybe there was some way to access the version number from the bot manifest, or the list of static tabs, and use that information, but I am happy for alternative suggestions.
We can get the manifest version using below Graph API or using SDK method:
https://learn.microsoft.com/en-us/graph/api/appcatalogs-list-teamsapps?view=graph-rest-1.0&tabs=http#example-4-list-applications-with-a-given-id-and-return-the-submission-review-state
So, before sending the Adaptive Card or message, you can put a custom condition to check the manifest version and send the message accordingly.
You can check the manifest version as explained by Chetan, i tried the same and figured its actually not the best idea.
It always should be best practice to have a "production" and "test" server or something like that.
Having different manifest versions point to the same server and running checks which version you're on will more than likely lead to issues sooner or later.
I sometimes even have 3 different instances running (prod, staging, test) to try various builds and things.
You can check that in your code but imo its not advisable to do so.

How to executeScript for webRequest event onBeforeRequest in Google Chrome Extension

Following Chrome Extension Manifest V3 rule I want to create an extension, that listens to particular network request and, for startes, just log them to the console of the currently opened tab (later I want to add custom script and styles to the page in the current tab).
For this I try to utilize chrome.scripting.executeScript.
When I implement the sample from https://github.com/GoogleChrome/chrome-extensions-samples/blob/main/examples/page-redder/manifest.json it works like expected for the chrome.action.onClicked listener.
As soon as I try to execute a script within the chrome.webRequest.onBeforeRequest listener, this error pops up:
Error in event handler: TypeError: Error in invocation of
scripting.executeScript(scripting.ScriptInjection injection, optional
function callback): Error at parameter 'injection': Error at property
'target': Missing required property 'tabId'.
at chrome.webRequest.onBeforeRequest.addListener.urls ()
Missing required property tabId? I assume it has to do with the lifecycle, but I cannot figure out what to do. This is my manifest:
{
"name": "Getting Started Example",
"description": "Build an Extension!",
"version": "1.0",
"manifest_version": 3,
"background": {
"service_worker": "background.js",
"matches": [ "<all_urls>"]
},
"host_permissions": [
"<all_urls>"
],
"permissions": [
"activeTab",
"tabs",
"webRequest",
"webNavigation",
"management",
"scripting"
]
}
And this is my script, I just slightly modified the "redden"-example:
function reddenPage(url) {
console.log(url);
}
chrome.webRequest.onBeforeRequest.addListener((tab) => {
chrome.scripting.executeScript({
target: { tabId: tab.id },
function: reddenPage,
args: [tab.url],
});
},
{urls: ["*://*.google.com/*"]},
[]);
I don't know exactly why, but the script from Github seems not work. This is how it works:
It's not only a couple of changed brackets, look at tab instead of (tab), but also tab.tabId instead of tab.id:
chrome.webRequest.onBeforeRequest.addListener(tab => {
chrome.scripting.executeScript(
{
target: { tabId: tab.tabId },
function: reddenPage,
args: [details.url],
},
() => { console.log('ZZZ') });
}, {
urls: ['<all_urls>']
});

{fault.name} - The client_id specified does not have access to the api product

I'm following this tutorial :
https://developer.autodesk.com/en/docs/model-derivative/v2/tutorials/prepare-file-for-viewer/
In previous steps, I get the token, get a token for bucket, create one and upload a file in it.
But, when I try, on the next step, to convert my file to svg, I get this message :
{fault.name} - The client_id specified does not have access to the api product
In Postman, I've do that :
POST https://developer.api.autodesk.com/modelderivative/v2/designdata/job
-- Header
Content-Type:application/json
Authorization:Bearer eyJhbGciOiJIUzI1...
-- Body
{
"input": {
"urn": "dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6ZGV2c3RlZWxidWNrZXQvc2t5c2NwcjEuXXXX"
},
"output": {
"formats": [
{
"type": "svf",
"views": [
"2d",
"3d"
]
}
]
}
}
And I do not find any solution in Google.
You need to activate your account.
If you face same issue even after activating your account, another possibility could be-
you might have missed "Model derivative API" while creating forge APP.

Parse Dynamic Property name in Azure Logic App

I have been playing around with Azure Logic Apps and trying to retrieve a Pocket (ReadItLater) article so that I can create a new task in my preferred Task Manager. I have Two HTTP Connectors (one for Retrieve Operation using Pocket API and another post data to Todoist (my preferred task manager).
I can retrieve the Article and the response looks like (removed a few properties below for easy reading):
{
"statusCode": 200,
"headers": {
"pragma": "no-cache",
"status": "200 OK"
},
"body": {
"status": 1,
"complete": 1,
"list": {
"586327616": {
"item_id": "586327616",
"resolved_id": "586327616",
"given_url": "http://kenwheeler.github.io/slick/?utm_source=hackernewsletter&utm_medium=email&utm_term=design&mc_cid=58c9499fa2&mc_eid=3aaf6c4e47",
"given_title": "slick - the last carousel you'll ever need",
"time_added": "1396652224",
"time_updated": "1405156517",
"resolved_title": "slick",
"resolved_url": "http://kenwheeler.github.io/slick/?utm_source=hackernewsletter&utm_medium=email&utm_term=design&mc_cid=58c9499fa2&mc_eid=3aaf6c4e47",
"excerpt": "Add slick.js before your closing <body> tag, after jQuery (requires jQuery 1.7 +) <script type=\"text/javascript\" src=\"slick/slick.min.",
"word_count": "22"
}
}
}
}
Now I want to parse the above response to retrieve individual article properties (i.e. resolved_title). The issue here is the object under the list "586327616" is dynamic and changes for every article, and I can't seem to parse this as an expression in Logic App. My current action in Logic App looks like:
"postToTodoist": {
"conditions": [
{
"expression": "#equals(outputs('getPocketArticles')['statusCode'], 200)"
},
{
"dependsOn": "getPocketArticles"
}
],
"inputs": {
"body": "#{outputs('getPocketArticles')['body']['list'][0]['resolved_title']}",
"headers": {
"Content-Type": "application/x-www-form-urlencoded"
},
"method": "POST",
"repeat": {},
"uri": "https://todoist.com/API/v6/add_item"
},
"type": "Http"
}
For the expression I have tried converting the response to string, using coalesce and trying to access using an index, but nothing seem to work. In the error, it tells me what that the available property is i.e.:
{"code":"InvalidTemplate","message":"Unable to process template language expressions in action 'postToTodoist' inputs at line '1' and column '11': 'The template language expression 'coalesce(body('getPocketArticles')['list']).resolved_title' cannot be evaluated because property 'resolved_title' doesn't exist, available properties are '586327616'. Please see https://aka.ms/logicexpressions for usage details.'."}
I feel that it is not possible to construct an expression without knowing the name of the property, has anyone done something similar?

400 Parser error with Google API POST call

I am trying to make POST call towards Search Console API. I got my example running under API Explorer, however when I try to make the same call from my meteor project, I am getting error:
Object {error: Object} error: Object code: 400 errors: Array[1]
message: "Parse Error"
My code:
function fetchSEOForWebsite(website) {
var call = 'webmasters/v3/sites/' + 'mdbootstrap.com' + '/searchAnalytics/query'
var params = {
"searchType": "web",
"dimensions": [
"query",
"date",
"page"
],
"startDate": "2016-02-06",
"endDate": "2016-02-08"
}
GoogleApi.post(call, {
params: params
}, function(error, answer) {
console.log(answer);
});
}
From Chrome console I can see POST payload:
searchType=web&dimensions=query%2Cdate%2Cpage&startDate=2016-02-06&endDate=2016-02-08
The same query works perfectly fine from API Explorer :
POST https://www.googleapis.com/webmasters/v3/sites/http%3A%2F%2Fmdbootstrap.com/searchAnalytics/query?key={YOUR_API_KEY}
{
"searchType": "web",
"dimensions": [
"query",
"date",
"page"
],
"startDate": "2016-02-06",
"endDate": "2016-02-08"
}
What am I doing wrong?
I am using Meteor Google Api
https://github.com/percolatestudio/meteor-google-api
UPDATE:
I also checked paylod sent via API Explorer and it's different:
{ "searchType": "web", "dimensions": ["query","date","page"
], "startDate": "2016-02-06", "endDate": "2016-02-08" }
So it looks like for some reason my params are not passed as a JSON object to call...
From percolate:google-api package Readme
GoogleApi is a Google OAuth authentication wrapper around HTTP, so it
takes the same arguments. For example, to pass a JSON body in
GoogleApi.post, use:
GoogleApi.post('/your/api/path', { data: jsonBody });
So I would try with data: instead of params: