diff --git a/README.md b/README.md
index 666d89a..b25bbc2 100644
--- a/README.md
+++ b/README.md
@@ -8,46 +8,53 @@ This proxy does not depend on Cloudflare and launches on express server.
`<20.5.1`
-If using version 21.x or above, it will generate a deprecation warning indicating the use of the deprecated punycode module.
+If using version 21.x or above, it will generate a deprecation warning indicating the use of the
+deprecated punycode module.
## Environment variable
-| ProxyConfig | Description | Default |
-|-------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------|
-| PROXY_PORT | Proxy port number | "3456" |
-| DOMAIN | Proxy domain for rewrite | "localhost:3456" |
-| IS_TLS | Proxy tls(http/https) for rewrite | "false" |
-| NOTION_PAGE_ID | Notion public page id | "f1db0cfbe246475784c67f279289abea" |
-| CUSTOM_SCRIPT | Custom script | "" |
-| CONTENT_CACHE_SEC | Cache time for loaded content (sec) | "300" |
-| GOOGLE_FONT | See: `https://developers.google.com/fonts` | "" |
-| AUTO_SET_OGP | The server automatically extracts Open Graph Protocol (OGP) data from your NotionId upon startup.
When this feature is enabled, the values of `OG_TAG_TITLE` and `OG_TAG_IMAGE_URL` are utilized for automatic configuration.
If you prefer to wait until the OGP tags are fetched automatically, you can use the `/readyz` command.
Requirements
- Headless chrome
- CPU is always allocated
- At least 512MB of memory for better | "false" |
-| OG_TAG_TITLE | Title for og tag | "" |
-| OG_TAG_DESC | Description for og tag | "" |
-| OG_TAG_IMAGE_URL | Image url for og tag | "" |
-| OG_TAG_TYPE | Type for og tag | "website" |
-| TWITTER_CARD | Twitter card for og tag | "summary_large_image" |
-
-### Note for AUTO_SET_OGP variable
+(※) is required.
+
+| ProxyConfig | Description | Default |
+|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------|
+| PROXY_PORT (※) | Proxy port number | "3456" |
+| DOMAIN (※) | Proxy domain (*Your domain*) for rewrite | "localhost:3456" |
+| IS_TLS (※) | Proxy tls(http/https) for rewrite | "false" |
+| NOTION_PAGE_ID (※) | Notion public page id | "f1db0cfbe246475784c67f279289abea" |
+| CUSTOM_SCRIPT | Custom script | "" |
+| CONTENT_CACHE_SEC | Cache time for loaded content (sec) | "300" |
+| GOOGLE_FONT | See: https://developers.google.com/fonts | "" |
+| AUTO_SET_OG_TAG | The server automatically extracts Open Graph Protocol (OGP) data from your NotionId upon startup.
When this feature is enabled, the values of `OG_TAG_TITLE` and `OG_TAG_IMAGE_URL` and `ICON_URL` are utilized for automatic configuration.
If you prefer to wait until the OGP tags are fetched automatically, you can use the `/readyz` endpoint.
Requirements
- Headless chrome
- CPU is always allocated
- At least 512MB of memory for better | "false" |
+| OG_TAG_TITLE | Title for og tag for rewrite.
If you use default value, there is no data to rewrite, so the data from when it back post to Notion will be used. | "" |
+| OG_TAG_DESC | Description for og tag for rewrite.
If you use default value, there is no data to rewrite, so the data from when it back post to Notion will be used. | "" |
+| OG_TAG_IMAGE_URL | Image url for og tag for rewrite.
If you use default value, there is no data to rewrite, so the data from when it back post to Notion will be used. | "" |
+| OG_TAG_TYPE | Type for og tag for rewrite | "website" |
+| ICON_URL | Icon url for rewrite.
If you use default value, there is no data to rewrite, so the data from when it back post to Notion will be used. | "" | |
+| TWITTER_CARD | Twitter card for og tag for rewrite | "summary_large_image" |
+
+### Note for AUTO_SET_OG_TAG variable
**OgTag setting priority**
Environment variables with OG_xxx in prefix are set with the highest priority.
-So, if AUTO_SET_OGP is enabled but the OG_xxx environment variable is set, OG_xxx will have priority.
+So, if AUTO_SET_OG_TAG is enabled but the OG_xxx environment variable is set, OG_xxx will have
+priority.
**Headless chrome Requirements**
At startup, we are extracting og tags from the NotionId page using Chrome Headless.
-So, CPU allocation is necessary. Please be cautious when using request allocation in services like Cloud Functions or Cloud Run or Other.
+So, CPU allocation is necessary. Please be cautious when using request allocation in services like
+Cloud Functions or Cloud Run or Other.
## Getting started
Start proxy for debug on local.
```bash
-$ npm ci
-$ npm test
-$ npm start_proxy
+npm ci
+npm test
+npm run start_proxy
+
> notion-proxy@1.0.0 start
> node src/index.js
Proxy listening at localhost:3456, NotionId: f1db0cfbe246475784c67f279289abea
@@ -56,8 +63,19 @@ Proxy listening at localhost:3456, NotionId: f1db0cfbe246475784c67f279289abea
Start proxy binary.
```bash
-$ npm install -g pkg
-$ npm run build
-$ ./notion-proxy
+npm install -g pkg
+npm run build
+./notion-proxy
+
Proxy listening at localhost:3456, NotionId: f1db0cfbe246475784c67f279289abea
-```
\ No newline at end of file
+```
+
+## Proxy example with your domain
+
+```bash
+export DOMAIN="CHANGE IT" && \
+export NOTION_PAGE_ID="CHANGE IT" && \
+export IS_TLS="true" && \
+export AUTO_SET_OG_TAG="true" && \
+npm run start_proxy
+```
diff --git a/src/config/proxyConfig.js b/src/config/proxyConfig.js
index e23c4ba..db40054 100644
--- a/src/config/proxyConfig.js
+++ b/src/config/proxyConfig.js
@@ -8,8 +8,9 @@ class ProxyConfig {
this.notionPageId = process.env.NOTION_PAGE_ID || 'f1db0cfbe246475784c67f279289abea';
this.customScript = process.env.CUSTOM_SCRIPT || '';
this.contentCacheSec = process.env.CONTENT_CACHE_SEC || '300';
- this.autoSetOgp = process.env.AUTO_SET_OGP || 'false';
- this.autoSetOgp = this.autoSetOgp === 'true';
+ this.iconUrl = process.env.ICON_URL || '';
+ this.autoSetOgTag = process.env.AUTO_SET_OG_TAG || 'false';
+ this.autoSetOgTag = this.autoSetOgTag === 'true';
this.slugToPage = {
"": this.notionPageId
}
@@ -52,6 +53,10 @@ class ProxyConfig {
throw new Error("Invalid CONTENT_CACHE_SEC environment. Allow number");
}
}
+
+ replaceIconUrl(v) {
+ this.iconUrl = v;
+ }
}
class TwitterTag {
diff --git a/src/lib/autoOgpExtractor.js b/src/lib/autoOgpExtractor.js
index 62eac30..61f8d30 100644
--- a/src/lib/autoOgpExtractor.js
+++ b/src/lib/autoOgpExtractor.js
@@ -10,10 +10,11 @@ const {JSDOM} = require("jsdom");
* The image has Chrome installed if the notion proxy is running on a container. See Dockerfile.
*/
class AutoOgpExtractor {
- constructor(notionId, domain, isTls) {
+ constructor(notionId, domain, isTls, proxyPort) {
this.notionId = notionId;
this.domain = domain;
this.isTls = isTls;
+ this.proxyPort = proxyPort;
}
async fetchHtmlAfterExecutedJs() {
@@ -24,7 +25,7 @@ class AutoOgpExtractor {
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage']
});
const page = await browser.newPage();
- await page.goto(`http://localhost:3456/${this.notionId}`);
+ await page.goto(`http://localhost:${this.proxyPort}/${this.notionId}`);
await page.waitForSelector('.notion-topbar');
const html = await page.content();
await browser.close();
@@ -66,6 +67,22 @@ class AutoOgpExtractor {
return `${protocol}://${this.domain}/${uri}`;
}
+ extractIcon(htmlStr) {
+ if (htmlStr === '' || htmlStr === null) {
+ return null;
+ }
+ const dom = new JSDOM(htmlStr);
+ const imgElements = dom.window.document.querySelectorAll('img[alt="Page icon"]');
+ const srcValues = Array.from(imgElements).map(img => img.getAttribute('src'));
+ if (!srcValues || srcValues.length === 0) {
+ return null;
+ }
+
+ const protocol = this.isTls ? 'https' : 'http';
+ let uri = srcValues[0].substring(1);;
+ return `${protocol}://${this.domain}/${uri}`;
+ }
+
extractOgDesc(htmlStr) {
if (htmlStr === '' || htmlStr === null) {
return null;
diff --git a/src/lib/autoOgpExtractor.test.js b/src/lib/autoOgpExtractor.test.js
index dc95b17..c90cb59 100644
--- a/src/lib/autoOgpExtractor.test.js
+++ b/src/lib/autoOgpExtractor.test.js
@@ -17,6 +17,9 @@ const testHtmlStr = `
Hello
+Hello
@@ -59,14 +62,16 @@ test('Parse html for Notion', () => {Hello
@@ -97,7 +102,19 @@ test('Parse html for Notion', () => { history.replaceState(history.state, '', '/' + slug); } } - const observer = new MutationObserver(function() { + var linkElement = document.querySelector('link[rel="shortcut icon"]'); + const observer = new MutationObserver(function(mutationsList) { + if ('https://reearth.io/img/logo.svg' !== '') { + for (var mutation of mutationsList) { + if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { + for (var node of mutation.addedNodes) { + if (node.nodeType === 1 && node.classList.contains('notion-presence-container') && linkElement) { + linkElement.href = 'https://reearth.io/img/logo.svg'; + } + } + } + } + } if (redirected) { return; } diff --git a/src/proxy/proxy.js b/src/proxy/proxy.js index 48c705b..406c518 100644 --- a/src/proxy/proxy.js +++ b/src/proxy/proxy.js @@ -14,22 +14,24 @@ class Proxy { * @param config ProxyConfig class */ constructor(config) { - this.initialize(config); + let isReady = !config.autoSetOgTag; + this.initVariable(config, isReady); } /** * Init field variable. * * @param config ProxyConfig class - * @param isReloadedVariable Reloaded variable for automatic set OGP + * @param isReady Whether automatic OGP extraction is successful or not */ - initialize(config, isReloadedVariable = false) { + initVariable(config, isReady) { this.proxyConfig = config; this.cacheStore = new ContentCache(config.contentCacheSec); this.autoOgpExtractor = new AutoOgpExtractor( config.notionPageId, config.domain, - config.isTls + config.isTls, + config.proxyPort ); this.htmlParser = new HtmlParser( config.ogTag.title, @@ -38,6 +40,7 @@ class Proxy { config.ogTag.url, config.ogTag.type, config.twitterTag.card, + config.iconUrl, config.googleFont, config.domain, config.customScript, @@ -45,48 +48,56 @@ class Proxy { config.slugToPage ); - if (config.autoSetOgp && isReloadedVariable) { - this.readyz = true; - this.livez = true; - } else if (config.autoSetOgp && !isReloadedVariable) { - this.readyz = false; - this.livez = true; - } else { - this.readyz = true; - this.livez = true; - } + this.readyz = isReady; + this.livez = true; } /** * Reload proxy config if AUTO_SET_OGP enabled. + * Failure safe processing * * @returns {Promise