Closed digitalcraftsman closed 7 months ago
As per this document the existing API is deprecated since today October the 24th 2020.
The Facebook Developers documentation points users to a new oEmbed endpoint for Instagram and this document offers instructions about the necessary changes.
As per the doc:
The Instagram oEmbed endpoint requires either an App Access Token (recommended) or Client Access Token.
Basically Facebook has ended free access to the Instagram API.
This affects both the regular and simple Instagram shortcodes.
So will the built-in GoHugo snippet be updated accordingly? We could imagine an update with this new API, where the API key would be set in the projet config.
@monsieurnebo
It's more complicated than that.
Facebook now requires registering a website as an app to provide the API keys. A website's calls to the Instagram API will now be tracked and subject to rate limits etc. It is also possible that the Instagram simple shortcode can no longer be refactored in a GDPR compliant way. Website admins will have to gain user consent if they want to serve Instagram content in the EU.
I honestly think that times have changed. Hugo should not enable Facebook's tracking anymore (as well as Google's etc).
Also these built-in shortcodes require maintenance time that could be spent more productively in other areas (hint: remote reesources, pages for data etc.).
Here is my "quick fix"
Go to your Facebook Developer Account (or create one). Go to your app (or create one).
Find your App-ID in the top left corner.
Go to Dashboard
and activate oEmbed.
Go to Settings -> Extended -> Security
and copy your client token.
Create a file layouts/shortcodes/instagram.html
in your project.
Paste the following content and replace <APPID>
and <CLIENTTOKEN>
with your credentials:
{{- $pc := .Page.Site.Config.Privacy.Instagram -}}
{{- if not $pc.Disable -}}
{{- if $pc.Simple -}}
{{ template "_internal/shortcodes/instagram_simple.html" . }}
{{- else -}}
{{ $id := .Get 0 }}
{{ $hideCaption := cond (eq (.Get 1) "hidecaption") "1" "0" }}
{{ with getJSON "https://graph.facebook.com/v8.0/instagram_oembed/?url=https://instagram.com/p/" $id "/&hidecaption=" $hideCaption "&access_token=<APPID>|<CLIENTTOKEN>" }}{{ .html | safeHTML }}{{ end }}
{{- end -}}
{{- end -}}
I would say that Hugo should include the information of the api being deprecated, with documentation on how to implement a shortcode yourself, but deprecating the shortcode more generally.
Here is my "quick fix"
- Go to your Facebook Developer Account (or create one). Go to your app (or create one).
- Find your App-ID in the top left corner.
- Go to
Dashboard
and activate oEmbed.- Go to
Settings -> Extended -> Security
and copy your client token.- Create a file
layouts/shortcodes/instagram.html
in your project.- Paste the following content and replace
<APPID>
and<CLIENTTOKEN>
with your credentials:{{- $pc := .Page.Site.Config.Privacy.Instagram -}} {{- if not $pc.Disable -}} {{- if $pc.Simple -}} {{ template "_internal/shortcodes/instagram_simple.html" . }} {{- else -}} {{ $id := .Get 0 }} {{ $hideCaption := cond (eq (.Get 1) "hidecaption") "1" "0" }} {{ with getJSON "https://graph.facebook.com/v8.0/instagram_oembed/?url=https://instagram.com/p/" $id "/&hidecaption=" $hideCaption "&access_token=<APPID>|<CLIENTTOKEN>" }}{{ .html | safeHTML }}{{ end }} {{- end -}} {{- end -}}
Not sure if it's just me, but getting an error
(#10) To use 'Oembed API', your use of this endpoint must be reviewed and approved by Facebook. To submit this 'Oembed API' feature for review please read our documentation on reviewable features: https://developers.facebook.com/docs/apps/review.
Here is my "quick fix"
* Go to your Facebook Developer Account (or create one). Go to your app (or create one). * Find your App-ID in the top left corner. * Go to `Dashboard` and activate _oEmbed_. * Go to `Settings -> Extended -> Security` and copy your client token. * Create a file `layouts/shortcodes/instagram.html` in your project. * Paste the following content and replace `<APPID>` and `<CLIENTTOKEN>` with your credentials:
{{- $pc := .Page.Site.Config.Privacy.Instagram -}} {{- if not $pc.Disable -}} {{- if $pc.Simple -}} {{ template "_internal/shortcodes/instagram_simple.html" . }} {{- else -}} {{ $id := .Get 0 }} {{ $hideCaption := cond (eq (.Get 1) "hidecaption") "1" "0" }} {{ with getJSON "https://graph.facebook.com/v8.0/instagram_oembed/?url=https://instagram.com/p/" $id "/&hidecaption=" $hideCaption "&access_token=<APPID>|<CLIENTTOKEN>" }}{{ .html | safeHTML }}{{ end }} {{- end -}} {{- end -}}
Did not work for me.
I have another solution:
Instead of embeding it, what if we crawl it. Add the param __a=1
to the instagram URL and you will get JSON of the page.
For example:
https://www.instagram.com/p/CH04mIdlmxg/
Add the __a=1
https://www.instagram.com/p/CH04mIdlmxg/?__a=1
Here what will we get:
Then create custom instagram shortcode: layouts/shortcodes/instagram.html
{{- $pc := .Page.Site.Config.Privacy.Instagram -}}
{{- if not $pc.Disable -}}
{{- if $pc.Simple -}}
{{ template "_internal/shortcodes/instagram_simple.html" . }}
{{- else -}}
{{ $id := .Get 0 }}
{{ $hideCaption := cond (eq (.Get 1) "hidecaption") "1" "0" }}
{{ with getJSON "https://instagram.com/p/" $id "?__a=1" }}
<figure>
<img src="{{ .graphql.shortcode_media.display_url }}" alt="{{ .graphql.shortcode_media.accessibility_caption }}" />
{{- if eq $hideCaption "0" -}}
{{ $caption := (index .graphql.shortcode_media.edge_media_to_caption.edges 0).node.text }}
<figcaption>{{ $caption }}</figcaption>
{{ end }}
</figure>
{{ end }}
{{- end -}}
{{- end -}}
@ardianta
This is a hack that broke in the past
No way are we going to refactor the Hugo internal shortcodes to use hacks.
The @ToniTornado 's fix is working fine (thanks!). His code contains some extra features you may not need, so here is a light version of it where Instagram API credentials are stored in the site config (seems cleaner to me):
config.yaml
params:
instagram:
appId: "xxxxxx"
clientToken: "xxxxxx"
layouts/shortcodes/instagram.html
{{- $appId := .Site.Params.Instagram.AppId -}}
{{- $clientToken := .Site.Params.Instagram.ClientToken -}}
{{ $id := .Get 0 }}
{{ with getJSON "https://graph.facebook.com/v8.0/instagram_oembed/?url=https://instagram.com/p/" $id "&access_token=" $appId "|" $clientToken }}{{ .html | safeHTML }}{{ end }}
@monsieurnebo, yes, that looks much cleaner! I'm using Hugo only for some side projects. All I did was slightly modifying the original source code to use my id & token.
I believe that most people's issues with my fix are not related to the fix itself but to the corresponding configuration in the Facebook Developer Account. You can debug that by just opening this URL in your browser (replace placeholders with your id & token):
https://graph.facebook.com/v8.0/instagram_oembed/?url=https://instagram.com/p/CHc_BmNgRCW&access_token=<YOU_APP_ID>|<YOUR_CLIENT_TOKEN>
You should get the full post as a response in JON format like this:
{
"version": "1.0",
"author_name": "kittens_of_world",
"provider_name": "Instagram",
"provider_url": "https://www.instagram.com/",
"type": "rich",
"width": 658,
"html": "\u003Cbl.......",
"...": "...",
}
If you get an error message, you can use that to fix your Facebook setup.
Hello,
Thanks for the hard work here for the fix folks. I just want to note @monsieurnebo that while I love this more fancy/brief method, it didn't work for me. The information from my config file never made it into the shortcode. So my API calls never had properly filled information for the AppID and token.
@ToniTornado your original fix still works though. A secondary issue I hit, just FYI for others - As Toni stated above I did have to debug with that url they provided - and that helped a lot. Going to this page 'https://developers.facebook.com/tools/explorer/' (the instagram graph API explorer) seemed to fix my permissions issue even though I had no idea why.
Just for reference, this is the error I saw when I tried the fancier/briefer method:
With this syntax in a .md file for the shortcode: [I share because I think maybe something about the instagram Hugo default shortcode and this custom one may have conflicted?]
{{< instagram CJg-BDPhef9 >}}
Using version:
hugo version Hugo Static Site Generator v0.74.2-48565DE6/extended linux/amd64 BuildDate: 2020-07-17T17:32:27Z
Happy new year
Here is my "quick fix"
- Go to your Facebook Developer Account (or create one). Go to your app (or create one).
- Find your App-ID in the top left corner.
- Go to
Dashboard
and activate oEmbed.- Go to
Settings -> Extended -> Security
and copy your client token.- Create a file
layouts/shortcodes/instagram.html
in your project.- Paste the following content and replace
<APPID>
and<CLIENTTOKEN>
with your credentials:{{- $pc := .Page.Site.Config.Privacy.Instagram -}} {{- if not $pc.Disable -}} {{- if $pc.Simple -}} {{ template "_internal/shortcodes/instagram_simple.html" . }} {{- else -}} {{ $id := .Get 0 }} {{ $hideCaption := cond (eq (.Get 1) "hidecaption") "1" "0" }} {{ with getJSON "https://graph.facebook.com/v8.0/instagram_oembed/?url=https://instagram.com/p/" $id "/&hidecaption=" $hideCaption "&access_token=<APPID>|<CLIENTTOKEN>" }}{{ .html | safeHTML }}{{ end }} {{- end -}} {{- end -}}
Hi Tony, thanks heaps for the fix, but is there a way to embed the feed so it updates automatically? or can you only embed each post/photo individually? TIA
Here is my "quick fix"
- Go to your Facebook Developer Account (or create one). Go to your app (or create one).
- Find your App-ID in the top left corner.
- Go to
Dashboard
and activate oEmbed.- Go to
Settings -> Extended -> Security
and copy your client token.- Create a file
layouts/shortcodes/instagram.html
in your project.- Paste the following content and replace
<APPID>
and<CLIENTTOKEN>
with your credentials:{{- $pc := .Page.Site.Config.Privacy.Instagram -}} {{- if not $pc.Disable -}} {{- if $pc.Simple -}} {{ template "_internal/shortcodes/instagram_simple.html" . }} {{- else -}} {{ $id := .Get 0 }} {{ $hideCaption := cond (eq (.Get 1) "hidecaption") "1" "0" }} {{ with getJSON "https://graph.facebook.com/v8.0/instagram_oembed/?url=https://instagram.com/p/" $id "/&hidecaption=" $hideCaption "&access_token=<APPID>|<CLIENTTOKEN>" }}{{ .html | safeHTML }}{{ end }} {{- end -}} {{- end -}}
Not sure if it's just me, but getting an error
(#10) To use 'Oembed API', your use of this endpoint must be reviewed and approved by Facebook. To submit this 'Oembed API' feature for review please read our documentation on reviewable features: https://developers.facebook.com/docs/apps/review.
The issue you have is tying to embed asset not belongs to you in Facebook or Instagram. Base on explanation https://developers.facebook.com/blog/post/2020/08/04/app-review-improvements-business-developers/
Standard access will be given to your app by default which only allow access assets belong to you. you can request advance access for your app but depends on approval from facebook, or you can create app under assets owner 's account .
I will try to fix this in the next Hugo. The recipe above works almost out of the box for me. Some notes: Reusing an old Facebook App doesn't seem to work that well, as they have totally reworked the access setup. So create a new App.
Products
, add the oEmbed
product: Seems like Facebook has done some changes to this ... again, so the APP I created and mentioned in my last comment does not work anymore ... idiots (Facebook, not you).
@bep Same here. I have tried to pass the app review several times now but without success. The forms just don't fit my simple use case.
I finally passed the app review process after some conversation with the Facebook support team. The oEmbed URL field expects a Facebook or Instagram post or profile URL. I was wrongly giving my own website's URL where you could actually see the embedded post. The docs say here https://developers.facebook.com/docs/plugins/oembed/?locale=en_US: "When asked to provide a URL where we can test Oembed Read, include the URL of a page, post, or video from our official Facebook or Instagram pages, or the pages themselves."
By "our" they seem to mean "your" in this case. So yes, you really give some Instagram or Facebook link there! And there is one KNOWN bug: The URL will be converted to lowercase when you save the form so that when it contains a case-sensitive Instagram-ID it will no longer work!
As a workaround I just posted my Intagram profile URL that did not contain any capital letters.
Hi all, as from 25 Jun none of the Apps category (business, none, customer etc.) seems to allow Oembed plugin.
"None" category that looks the one with more plugins available doesn't offer such a possibility...
Anyone has find out how to solve?
In case anyone else comes looking for a workaround until this issue is resolved:
My solution was to create a custom shortcode with the native embed code found through the Embed Button. It doesn't use an API, and doesn't need an app. It's not the most elegant or future-proof solution, but it works like a charm for now and I can keep using the default:
{{< instagram BWNjjyYFxVx >}}
(If you embed photos from multiple users, you have to customize the shortcode with a few additional parameters to pass in their name and username.)
@cathrinew I was use endpoint of the embed button, and it works.
Here my custom shortcode:
{{ $id := .Get 0 }}
{{ $hideCaption := cond (eq (.Get 1) "hidecaption") "1" "0" }}
{{ if not .Site.IsServer }}
{{ with getJSON "https://api.instagram.com/oembed/?url=https://www.instagram.com/p/" $id "/&hidecaption=" $hideCaption }}
{{ .html | safeHTML }}
{{ end }}
{{ else }}
<style>
.instagram-embed-placeholder {
display: flex;
align-items: center;
justify-content: center;
gap: .5em;
border: 2px dashed silver;
height: 360px;
margin: 2em 0;
border-radius: 8px;
}
</style>
<div class='instagram-embed-placeholder'>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-instagram" viewBox="0 0 16 16">
<path d="M8 0C5.829 0 5.556.01 4.703.048 3.85.088 3.269.222 2.76.42a3.917 3.917 0 0 0-1.417.923A3.927 3.927 0 0 0 .42 2.76C.222 3.268.087 3.85.048 4.7.01 5.555 0 5.827 0 8.001c0 2.172.01 2.444.048 3.297.04.852.174 1.433.372 1.942.205.526.478.972.923 1.417.444.445.89.719 1.416.923.51.198 1.09.333 1.942.372C5.555 15.99 5.827 16 8 16s2.444-.01 3.298-.048c.851-.04 1.434-.174 1.943-.372a3.916 3.916 0 0 0 1.416-.923c.445-.445.718-.891.923-1.417.197-.509.332-1.09.372-1.942C15.99 10.445 16 10.173 16 8s-.01-2.445-.048-3.299c-.04-.851-.175-1.433-.372-1.941a3.926 3.926 0 0 0-.923-1.417A3.911 3.911 0 0 0 13.24.42c-.51-.198-1.092-.333-1.943-.372C10.443.01 10.172 0 7.998 0h.003zm-.717 1.442h.718c2.136 0 2.389.007 3.232.046.78.035 1.204.166 1.486.275.373.145.64.319.92.599.28.28.453.546.598.92.11.281.24.705.275 1.485.039.843.047 1.096.047 3.231s-.008 2.389-.047 3.232c-.035.78-.166 1.203-.275 1.485a2.47 2.47 0 0 1-.599.919c-.28.28-.546.453-.92.598-.28.11-.704.24-1.485.276-.843.038-1.096.047-3.232.047s-2.39-.009-3.233-.047c-.78-.036-1.203-.166-1.485-.276a2.478 2.478 0 0 1-.92-.598 2.48 2.48 0 0 1-.6-.92c-.109-.281-.24-.705-.275-1.485-.038-.843-.046-1.096-.046-3.233 0-2.136.008-2.388.046-3.231.036-.78.166-1.204.276-1.486.145-.373.319-.64.599-.92.28-.28.546-.453.92-.598.282-.11.705-.24 1.485-.276.738-.034 1.024-.044 2.515-.045v.002zm4.988 1.328a.96.96 0 1 0 0 1.92.96.96 0 0 0 0-1.92zm-4.27 1.122a4.109 4.109 0 1 0 0 8.217 4.109 4.109 0 0 0 0-8.217zm0 1.441a2.667 2.667 0 1 1 0 5.334 2.667 2.667 0 0 1 0-5.334z"/>
</svg>
<a href='https://www.instagram.com/p/{{ $id }}/' target="_blank" rel="noopener">
Instagram Embed: {{ $id }}
</a>
</div>
{{ end }}
The API endpoint was back to normal. lol :rofl: But I don't know, how long it will be available for public.
One workaround I'm exploring is to export all of my images from IG, close my IG account, and host the images directly in my Hugo site.
One workaround I'm exploring is to export all of my images from IG, close my IG account, and host the images directly in my Hugo site.
doable via a data download request! https://www.cnet.com/tech/mobile/how-to-download-all-your-instagram-data/
For the record, I did an Instagram account export and replaced my Instagram embeds with self hosted images. I only had a single post with embeds to replace so effort was manageable.
https://github.com/tphummel/blog/commit/d999c9dbc7dfd1d64159b2ab4ae4f706e2860f39
Alternatively, what if there was support for importing external shortcodes into Hugo, so this both can be moved out of core & is still very accessible to where people don't have to write their own shortcode to support it! I haven't taken a look at theming in Hugo in a while... would go modules work for that?
You can! https://gohugo.io/hugo-modules/use-modules/ :D perhaps gohugio/social-shortcodes
or a community version?
Cant you just use something like this?
This is a good alternative for iframe lazyloading, thank you.
Note that there is a solution here by @jhvanderschee.
I have tried all the other solutions above without avail. The solution I linked works well for me at https://www.nijho.lt/
Closing this as "out of scope" or: Too hard.
Note that there is a solution here by @jhvanderschee.
I have tried all the other solutions above without avail. The solution I linked works well for me at https://www.nijho.lt/
The PPI service is no longer active due to the ongoing 'sabotage' from Facebook. Here is a good alternative that is easy to implement in your Hugo website: https://www.usecue.com/blog/free-instagram-widget/.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
What version of Hugo are you using (
hugo version
)?Does this issue reproduce with the latest release?
Yes
How to reproduce?
When using the
instagram
shortcode with id BWNjjyYFxVx the shortcodes uses this template to construct the url https://api.instagram.com/oembed/?url=https://instagram.com/p/BWNjjyYFxVx. When opening it a notice informs you about the deprecation of the linked API endpoint.See also #7866.