Skip to content

Commit c8d7a6e

Browse files
committed
feat(facebook and instagram embeds): support instagram and facebook embeds
This needs a access_token from your FB app set as env var (FB_APP_TOKEN)
1 parent 9a7252f commit c8d7a6e

9 files changed

Lines changed: 177 additions & 128 deletions

File tree

example.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,12 @@
3838

3939
%[https://www.canva.com/design/DAEWRhUKdvg/view]
4040

41-
%[https://giphy.com/gifs/cbsnews-inauguration-2021-XEMbxm9vl9JIIMcE7M]
41+
%[https://giphy.com/gifs/cbsnews-inauguration-2021-XEMbxm9vl9JIIMcE7M]
42+
43+
%[https://www.instagram.com/p/CL8vNB_n_I3/]
44+
45+
%[https://www.facebook.com/barackobama/posts/10158541668386749]
46+
47+
%[https://fb.watch/4yOE3vHgMr]
48+
49+
%[https://www.instagram.com/reel/CMgbGuOgo9l/?igshid=1pty8jxruxsd6]

packages/webembeds-core/src/modules/WebembedHandler.ts

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable camelcase */
12
import oembed from "oembed";
23
import tryEach from "async/tryEach";
34
import Platform from "./Platform";
@@ -45,29 +46,37 @@ export default class WebembedHandler {
4546
* must be made with embedURL, if no targetURL found, it will be the embedURL itself.
4647
*/
4748
detectProvider = () => {
48-
let destinationProvider: { endpoints: any; } | null = null;
49+
let destinationProvider: { endpoints: any, provider_name: string } | null = null;
4950
let targetURL = null; // The endpoint that the embedURL should be queried upon
5051

51-
oEmbedProviders.forEach((provider: { endpoints: any[]; }) => {
52-
provider.endpoints.forEach((endpoint) => {
53-
if (endpoint.schemes && endpoint.schemes.length > 0) {
54-
endpoint.schemes.forEach((scheme: string) => {
55-
// eslint-disable-next-line no-useless-escape
56-
if (this.embedURL.match(scheme.replace(/\*/g, ".*").replace(/\//g, "\/").replace(/\//g, "\\/"))) {
57-
// TODO: Pattern match here
58-
targetURL = endpoint.url;
59-
destinationProvider = provider;
60-
}
61-
});
62-
} else if (endpoint.url.match(this.embedURL)) {
52+
let found = false;
53+
oEmbedProviders.some((provider: { endpoints: any[], provider_name: string }) => {
54+
provider.endpoints.some((endpoint) => {
55+
if (!endpoint.schemes || endpoint.schemes.length === 0) {
6356
// If there are no schemes Ex. https://www.beautiful.ai/
6457
// Consider the url to be the targetURL
65-
destinationProvider = provider;
66-
targetURL = endpoint.url;
58+
59+
if (this.embedURL.match(endpoint.url.replace(/\*/g, ".*").replace(/\//g, "\/").replace(/\//g, "\\/"))) {
60+
targetURL = endpoint.url;
61+
destinationProvider = provider;
62+
return true;
63+
}
64+
return false;
6765
}
66+
67+
found = endpoint.schemes.some((scheme: string) => {
68+
// eslint-disable-next-line no-useless-escape
69+
if (this.embedURL.match(scheme.replace(/\*/g, ".*").replace(/\//g, "\/").replace(/\//g, "\\/"))) {
70+
targetURL = endpoint.url;
71+
destinationProvider = provider;
72+
return true;
73+
}
74+
return false;
75+
});
76+
return found;
6877
});
78+
return found;
6979
});
70-
7180
return {
7281
provider: destinationProvider,
7382
targetURL: targetURL || this.embedURL,

packages/webembeds-core/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type Provider = {
3535
customClass?: any,
3636
discover: boolean,
3737
noCustomWrap: boolean,
38+
provider_name: string,
3839
}
3940

4041
type PlatformType = {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { makeRequest } from "../requestHandler";
2+
import Platform from "../../modules/Platform";
3+
import type { OEmbedResponseType, PlatformType } from "../../types";
4+
5+
const { FB_APP_TOKEN } = process.env;
6+
7+
export default class Facebook extends Platform {
8+
hasError: boolean = false;
9+
10+
// eslint-disable-next-line no-useless-constructor
11+
constructor(args: PlatformType) {
12+
super(args);
13+
if (!FB_APP_TOKEN) {
14+
this.hasError = true;
15+
}
16+
}
17+
18+
run = async (): Promise<OEmbedResponseType | null> => {
19+
if (this.hasError) {
20+
return null;
21+
}
22+
23+
const response = await makeRequest(`${this.targetURL}?url=${encodeURIComponent(this.embedURL)}&access_token=${FB_APP_TOKEN}`);
24+
const data = response ? response.data : null;
25+
26+
if (!data) {
27+
return null;
28+
}
29+
30+
return data;
31+
}
32+
}
33+
34+
export {};

packages/webembeds-core/src/utils/providers/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as Giphy from "./giphy.provider";
44
import * as Instagram from "./instagram.provider";
55
import * as Twitch from "./twitch.provider";
66
import * as Glitch from "./glitch.provider";
7+
import * as Facebook from "./facebook.provider";
78

89
export default {
910
GithubGist,
@@ -12,4 +13,5 @@ export default {
1213
Instagram,
1314
Twitch,
1415
Glitch,
16+
Facebook,
1517
};
Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,36 @@
1+
/* eslint-disable camelcase */
2+
import { makeRequest } from "../requestHandler";
13
import Platform from "../../modules/Platform";
24
import type { OEmbedResponseType, PlatformType } from "../../types";
5+
import { wrapHTML } from "../html.utils";
6+
7+
const { FB_APP_TOKEN } = process.env;
38

49
export default class Instagram extends Platform {
10+
hasError: boolean = false;
11+
512
// eslint-disable-next-line no-useless-constructor
613
constructor(args: PlatformType) {
714
super(args);
15+
if (!FB_APP_TOKEN) {
16+
this.hasError = true;
17+
}
818
}
919

10-
run = async (): Promise<OEmbedResponseType> => {
11-
console.log("Custom Instagram pull");
20+
run = async (): Promise<OEmbedResponseType | null> => {
21+
if (this.hasError) {
22+
return null;
23+
}
24+
25+
const response = await makeRequest(`${this.targetURL}?url=${encodeURIComponent(this.embedURL)}&access_token=${FB_APP_TOKEN}`);
26+
const data = response ? response.data : null;
1227

13-
// const id = this.embedURL.replace("https://www.instagram.com/p/", "").trim().replace(/\//g, "");
14-
return {
15-
version: 0.1,
16-
type: "rich",
17-
title: "Instagram",
18-
html: "<h1>Not supported yet</h1>",
19-
};
28+
if (!data) {
29+
return null;
30+
}
31+
32+
return data;
2033
}
2134
}
35+
36+
export {};

packages/webembeds-core/src/utils/providers/oembed.providers.js

Lines changed: 80 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Twitch from "./twitch.provider";
66
import Glitch from "./glitch.provider";
77
import Loom from "./loom.provider";
88
import Codepen from "./codepen.provider";
9+
import Facebook from "./facebook.provider";
910

1011
const oEmbedProviders = [
1112
{
@@ -875,42 +876,6 @@ const oEmbedProviders = [
875876
},
876877
],
877878
},
878-
// {
879-
// provider_name: "Facebook",
880-
// provider_url: "https://www.facebook.com/",
881-
// endpoints: [
882-
// {
883-
// schemes: [
884-
// "https://www.facebook.com/*/posts/*",
885-
// "https://www.facebook.com/*/activity/*",
886-
// "https://www.facebook.com/photo.php?fbid=*",
887-
// "https://www.facebook.com/photos/*",
888-
// "https://www.facebook.com/permalink.php?story_fbid=*",
889-
// "https://www.facebook.com/media/set?set=*",
890-
// "https://www.facebook.com/questions/*",
891-
// "https://www.facebook.com/notes/*/*/*",
892-
// ],
893-
// url: "https://graph.facebook.com/v8.0/oembed_post",
894-
// discovery: false,
895-
// },
896-
// {
897-
// schemes: [
898-
// "https://www.facebook.com/*/videos/*",
899-
// "https://www.facebook.com/video.php?id=*",
900-
// "https://www.facebook.com/video.php?v=*",
901-
// ],
902-
// url: "https://graph.facebook.com/v8.0/oembed_video",
903-
// discovery: false,
904-
// },
905-
// {
906-
// schemes: [
907-
// "https://www.facebook.com/*",
908-
// ],
909-
// url: "https://graph.facebook.com/v8.0/oembed_page",
910-
// discovery: false,
911-
// },
912-
// ],
913-
// },
914879
{
915880
provider_name: "Fader",
916881
provider_url: "https://app.getfader.com",
@@ -1383,70 +1348,6 @@ const oEmbedProviders = [
13831348
},
13841349
],
13851350
},
1386-
// {
1387-
// provider_name: "Instagram",
1388-
// provider_url: "https://instagram.com",
1389-
// custom: true,
1390-
// customClass: Instagram,
1391-
// endpoints: [
1392-
// {
1393-
// schemes: [
1394-
// "http://instagram.com/*/p/*,",
1395-
// "http://www.instagram.com/*/p/*,",
1396-
// "https://instagram.com/*/p/*,",
1397-
// "https://www.instagram.com/*/p/*,",
1398-
// "http://instagram.com/p/*",
1399-
// "http://instagr.am/p/*",
1400-
// "http://www.instagram.com/p/*",
1401-
// "http://www.instagr.am/p/*",
1402-
// "https://instagram.com/p/*",
1403-
// "https://instagr.am/p/*",
1404-
// "https://www.instagram.com/p/*",
1405-
// "https://www.instagr.am/p/*",
1406-
// "http://instagram.com/tv/*",
1407-
// "http://instagr.am/tv/*",
1408-
// "http://www.instagram.com/tv/*",
1409-
// "http://www.instagr.am/tv/*",
1410-
// "https://instagram.com/tv/*",
1411-
// "https://instagr.am/tv/*",
1412-
// "https://www.instagram.com/tv/*",
1413-
// "https://www.instagr.am/tv/*",
1414-
// ],
1415-
// url: "https://api.instagram.com/oembed",
1416-
// formats: [
1417-
// "json",
1418-
// ],
1419-
// },
1420-
// // {
1421-
// // schemes: [
1422-
// // "http://instagram.com/*/p/*,",
1423-
// // "http://www.instagram.com/*/p/*,",
1424-
// // "https://instagram.com/*/p/*,",
1425-
// // "https://www.instagram.com/*/p/*,",
1426-
// // "http://instagram.com/p/*",
1427-
// // "http://instagr.am/p/*",
1428-
// // "http://www.instagram.com/p/*",
1429-
// // "http://www.instagr.am/p/*",
1430-
// // "https://instagram.com/p/*",
1431-
// // "https://instagr.am/p/*",
1432-
// // "https://www.instagram.com/p/*",
1433-
// // "https://www.instagr.am/p/*",
1434-
// // "http://instagram.com/tv/*",
1435-
// // "http://instagr.am/tv/*",
1436-
// // "http://www.instagram.com/tv/*",
1437-
// // "http://www.instagr.am/tv/*",
1438-
// // "https://instagram.com/tv/*",
1439-
// // "https://instagr.am/tv/*",
1440-
// // "https://www.instagram.com/tv/*",
1441-
// // "https://www.instagr.am/tv/*",
1442-
// // ],
1443-
// // url: "https://graph.facebook.com/v8.0/instagram_oembed",
1444-
// // formats: [
1445-
// // "json",
1446-
// // ],
1447-
// // },
1448-
// ],
1449-
// },
14501351
{
14511352
provider_name: "Issuu",
14521353
provider_url: "https://issuu.com/",
@@ -3903,6 +3804,85 @@ const customProviders = [
39033804
},
39043805
],
39053806
},
3807+
{
3808+
provider_name: "Facebook",
3809+
provider_url: "https://www.facebook.com/",
3810+
endpoints: [
3811+
{
3812+
schemes: [
3813+
"https://www.facebook.com/*/posts/*",
3814+
"https://www.facebook.com/*/activity/*",
3815+
"https://www.facebook.com/photo.php?fbid=*",
3816+
"https://www.facebook.com/photos/*",
3817+
"https://www.facebook.com/permalink.php?story_fbid=*",
3818+
"https://www.facebook.com/media/set?set=*",
3819+
"https://www.facebook.com/questions/*",
3820+
"https://www.facebook.com/notes/*/*/*",
3821+
],
3822+
url: "https://graph.facebook.com/v10.0/oembed_post",
3823+
discovery: false,
3824+
},
3825+
{
3826+
schemes: [
3827+
"https://www.facebook.com/*/videos/*",
3828+
"https://www.facebook.com/*/videos/{video-id}",
3829+
"https://www.facebook.com/video.php?id=*",
3830+
"https://www.facebook.com/video.php?v=*",
3831+
"https://fb.watch/*",
3832+
],
3833+
url: "https://graph.facebook.com/v10.0/oembed_video",
3834+
discovery: false,
3835+
},
3836+
{
3837+
schemes: [
3838+
"https://www.facebook.com/*",
3839+
],
3840+
url: "https://graph.facebook.com/v10.0/oembed_page",
3841+
discovery: false,
3842+
},
3843+
],
3844+
custom: true,
3845+
customClass: Facebook,
3846+
},
3847+
{
3848+
provider_name: "Instagram",
3849+
provider_url: "https://instagram.com",
3850+
endpoints: [
3851+
{
3852+
schemes: [
3853+
"http://instagram.com/*/p/*,",
3854+
"http://www.instagram.com/*/p/*,",
3855+
"https://instagram.com/*/p/*,",
3856+
"https://www.instagram.com/*/p/*,",
3857+
"http://instagram.com/p/*",
3858+
"http://instagr.am/p/*",
3859+
"http://www.instagram.com/p/*",
3860+
"http://www.instagr.am/p/*",
3861+
"https://instagram.com/p/*",
3862+
"https://instagr.am/p/*",
3863+
"https://www.instagram.com/p/*",
3864+
"https://www.instagr.am/p/*",
3865+
"http://instagram.com/tv/*",
3866+
"http://instagr.am/tv/*",
3867+
"http://www.instagram.com/tv/*",
3868+
"http://www.instagr.am/tv/*",
3869+
"https://instagram.com/tv/*",
3870+
"https://instagr.am/tv/*",
3871+
"https://www.instagram.com/tv/*",
3872+
"https://www.instagr.am/tv/*",
3873+
"https://www.instagram.com/reel/*",
3874+
"https://instagram.com/reel/*",
3875+
"https://www.instagr.am/reel/*",
3876+
],
3877+
url: "https://graph.facebook.com/v9.0/instagram_oembed",
3878+
formats: [
3879+
"json",
3880+
],
3881+
},
3882+
],
3883+
custom: true,
3884+
customClass: Instagram,
3885+
},
39063886
];
39073887

39083888
export default [...oEmbedProviders, ...additionalOEmbedProviders, ...customProviders];

packages/webembeds-core/src/utils/requestHandler.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const makeRequest = async (url: string): Promise<RequestResponseType> =>
1919
});
2020
return response;
2121
} catch (error) {
22+
// console.log(error);
2223
return null;
2324
}
2425
};

0 commit comments

Comments
 (0)