Images/Videos CDN URL - Detect file type/extension - url

I'm trying to implement Story Mention rendering according to IG messenger graph API.
IG webhooks sends the payload URL of the media as CDN URLs that are extensionless,
which means I can't detect the file type(could be any kind of image or a video file).
The purpose is to render the URL to an HTML element and to prevent saving some file extensions.
Did anybody find out how to get this information?
An example for IG CDN URL
https://lookaside.fbsbx.com/ig_messaging_cdn/?asset_id=17952754300482708&signature=AbxVoHUcW3qKGZvE0FwrbpSEKBqkYGH9wFDUY9xnywlxxek8lWtrTwE173Sxhta9jbp0bgDiL17IpyiI82vqHGNPUD1wdMUZphwQOggW-_877cCI1BxaY_aDUZ8hj5OwmHK9E8OnSybqtMVmGXCX_hBF399t1Hb44zspeL3d9NWb9rib

Python:
import requests
res = requests.head(url)
print res.headers

I was able to retrieve the content type by making a request with node-fetch.
const fetch = require('node-fetch');
const response = await fetch(mediaUrl, { method: 'HEAD' });
const contentType = response.headers.get('Content-Type');

Related

How to get link to third party site in 'about channel' section via python

I want to display information about links in the YouTube profile in a text document, I tried to do it through the requests library, but Google gave links to privacy and security, I did not find information about this in the YouTube API documentation. Who knows, you can help with this
This isn't possible to get using the YouTube API, I actually found myself needing to do the same thing as yourself and was not able to because the YouTube API lacked the necessary functionality (Hopefully, It will be added soon!)
I see you mentioned Python, My only solution is in Node but I will do a large explanation and you can base your code off of it. In order to get the banner links without the YouTube API, we need to scrape the data, since YouTube uses client-side rendering we need to scrape the JSON configuration from the source.
There's a variable defined inside a script called ytInitialData which is a big JSON string with a massive amount of information about the channel, viewer, and YouTube configurations. We can find the banner links by parsing through this JSON link.
const request = require("request-promise").defaults({
simple: false,
resolveWithFullResponse: true
})
const getBannerLinks = async () => {
return request("https://www.youtube.com/user/pewdiepie").then(res => {
if (res.statusCode === 200) {
const parsed = res.body.split("var ytInitialData = ")[1].split(";</script>")[0]
const data = JSON.parse(parsed)
const links = data.header.c4TabbedHeaderRenderer.headerLinks.channelHeaderLinksRenderer
const allLinks = links.primaryLinks.concat(links.secondaryLinks || [])
const parsedLinks = allLinks.map(l => {
const url = new URLSearchParams(l.navigationEndpoint.commandMetadata.webCommandMetadata.url)
return {
link: url.get("q"),
name: l.title.simpleText,
icon: l.icon.thumbnails[0].url
}
})
return parsedLinks
} else {
// Error/ratelimit - Handle here
}
})
}
The way the links are scraped is as follows:
We make a HTTP request to the channel's URL
We parse the body to extract the JSON string that the banner links are inside using split
We parse the JSON string into a JSON object
We extract the links from their JSON section (It's a big JSON object data.header.c4TabbedHeaderRenderer.headerLinks.channelHeaderLinksRenderer
Because there are two types of links (Primary, the one that shows the text and secondary, links that don't show the text) we have to concatenate them together so we can map through them
We then map through the links and use URLSearchParams to extract the q query parameter since YouTube encrypts their outgoing links (Most likely for security reasons) and then extract the name and icon too using their appropriate objects.
This isn't a perfect solution, should YouTube update/change anything on their front end this could break your program easily. YouTube also has rate limits for their software if you're trying to mass scrape you'll run into 429/403 errors.

Programmable Chat Media Filename (JS)

The Media Support docs it mentions that when sending media you can: "Optionally specify a default download filename to help your application display the media to other users.". This is done using messagingOptions in Swift however in JS I cannot find any supporting documentation on how this is done. Currently, I am sending media as follows:
channel.sendMessage({
contentType: 'image/png',
media: fs.readFileSync(media)
});
I have tried adding a filename with file, filename and name properties without any luck. As you can see the filename is empty in the Twilio console:
Any help on adding a filename is much appreciated, thanks.
The answer:
const data = new FormData();
data.append('file', blob, filename);
According to the FormData docs, you can add a filename as an option like so:
After converting the image to a Base64 string I created a blob from the binary and appended the blob to the form data as shown above. Here is my code:

How to retrieve Medium stories for a user from the API?

I'm trying to integrate Medium blogging into an app by showing some cards with posts images and links to the original Medium publication.
From Medium API docs I can see how to retrieve publications and create posts, but it doesn't mention retrieving posts. Is retrieving posts/stories for a user currently possible using the Medium's API?
The API is write-only and is not intended to retrieve posts (Medium staff told me)
You can simply use the RSS feed as such:
https://medium.com/feed/#your_profile
You can simply get the RSS feed via GET, then if you need it in JSON format just use a NPM module like rss-to-json and you're good to go.
Edit:
It is possible to make a request to the following URL and you will get the response. Unfortunately, the response is in RSS format which would require some parsing to JSON if needed.
https://medium.com/feed/#yourhandle
⚠️ The following approach is not applicable anymore as it is behind Cloudflare's DDoS protection.
If you planning to get it from the Client-side using JavaScript or jQuery or Angular, etc. then you need to build an API gateway or web service that serves your feed. In the case of PHP, RoR, or any server-side that should not be the case.
You can get it directly in JSON format as given beneath:
https://medium.com/#yourhandle/latest?format=json
In my case, I made a simple web service in the express app and host it over Heroku. React App hits the API exposed over Heroku and gets the data.
const MEDIUM_URL = "https://medium.com/#yourhandle/latest?format=json";
router.get("/posts", (req, res, next) => {
request.get(MEDIUM_URL, (err, apiRes, body) => {
if (!err && apiRes.statusCode === 200) {
let i = body.indexOf("{");
const data = body.substr(i);
res.send(data);
} else {
res.sendStatus(500).json(err);
}
});
});
Nowadays this URL:
https://medium.com/#username/latest?format=json
sits behind Cloudflare's DDoS protection service so instead of consistently being served your feed in JSON format, you will usually receive instead an HTML which is suppose to render a website to complete a reCAPTCHA and leaving you with no data from an API request.
And the following:
https://medium.com/feed/#username
has a limit of the latest 10 posts.
I'd suggest this free Cloudflare Worker that I made for this purpose. It works as a facade so you don't have to worry about neither how the posts are obtained from source, reCAPTCHAs or pagination.
Full article about it.
Live example. To fetch the following items add the query param ?next= with the value of the JSON field next which the API provides.
const MdFetch = async (name) => {
const res = await fetch(
`https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/${name}`
);
return await res.json();
};
const data = await MdFetch('#chawki726');
To get your posts as JSON objects
you can replace your user name instead of #USERNAME.
https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/#USERNAME
With that REST method you would do this: GET https://api.medium.com/v1/users/{{userId}}/publications and this would return the title, image, and the item's URL.
Further details: https://github.com/Medium/medium-api-docs#32-publications .
You can also add "?format=json" to the end of any URL on Medium and get useful data back.
Use this url, this url will give json format of posts
Replace studytact with your feed name
https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/studytact
I have built a basic function using AWS Lambda and AWS API Gateway if anyone is interested. A detailed explanation is found on this blog post here and the repository for the the Lambda function built with Node.js is found here on Github. Hopefully someone here finds it useful.
(Updating the JS Fiddle and the Clay function that explains it as we updated the function syntax to be cleaner)
I wrapped the Github package #mark-fasel was mentioning below into a Clay microservice that enables you to do exactly this:
Simplified Return Format: https://www.clay.run/services/nicoslepicos/medium-get-user-posts-new/code
I put together a little fiddle, since a user was asking how to use the endpoint in HTML to get the titles for their last 3 posts:
https://jsfiddle.net/h405m3ma/3/
You can call the API as:
curl -i -H "Content-Type: application/json" -X POST -d '{"username":"nicolaerusan"}' https://clay.run/services/nicoslepicos/medium-get-users-posts-simple
You can also use it easily in your node code using the clay-client npm package and just write:
Clay.run('nicoslepicos/medium-get-user-posts-new', {"profile":"profileValue"})
.then((result) => {
// Do what you want with returned result
console.log(result);
})
.catch((error) => {
console.log(error);
});
Hope that's helpful!
Check this One you will get all info about your own post........
mediumController.getBlogs = (req, res) => {
parser('https://medium.com/feed/#profileName', function (err, rss) {
if (err) {
console.log(err);
}
var stories = [];
for (var i = rss.length - 1; i >= 0; i--) {
var new_story = {};
new_story.title = rss[i].title;
new_story.description = rss[i].description;
new_story.date = rss[i].date;
new_story.link = rss[i].link;
new_story.author = rss[i].author;
new_story.comments = rss[i].comments;
stories.push(new_story);
}
console.log('stories:');
console.dir(stories);
res.json(200, {
Data: stories
})
});
}
I have created a custom REST API to retrieve the stats of a given post on Medium, all you need is to send a GET request to my custom API and you will retrieve the stats as a Json abject as follows:
Request :
curl https://endpoint/api/stats?story_url=THE_URL_OF_THE_MEDIUM_STORY
Response:
{
"claps": 78,
"comments": 1
}
The API responds within a reasonable response time (< 2 sec), you can find more about it in the following Medium article.

YouTube v3 API (.NET) - Get URI of newly posted video resource?

After scouring the v3 API documentation (and using the API explorer), I am not able to determine how to obtain the URI of a newly uploaded video resource (or any video resource).
I am aware that the video's ID is readily available and it is trivial to construct a URI from the ID. For example, I have this extension method:
public static Uri GetUri(this Video video)
{
var uriBuilder = new UriBuilder
{
Scheme = Uri.UriSchemeHttp,
Host = "youtu.be",
Path = video.Id,
};
return uriBuilder.Uri;
}
However, it seems strange that the video resource would not include a few different URLs (regular, shortened and embed-able come to mind).
I also recognize I am probably over thinking this because the only volatile part of the URL is the video ID. I guess I could always put the host name in a config file :)
Thoughts and comments are appreciated.
Regards,
You can get the video ID from the upload response once your request is executed.
YouTube API samples have a great upload example for this.
Once you have the video id, you can construct the full URL as
youtube.com/watch?v={video_id}
youtu.be/{video_id}

How do I mask Facebook graph api URLs for pictures?

I'm trying to display Facebook profile pictures on my site, but don't want to leak the facebook id's of the people in the source.
For example, this URL: http://graph.facebook.com/4/picture will redirect to: http://profile.ak.fbcdn.net/hprofile-ak-snc4/157340_4_3955636_q.jpg when you load it in a browser. I'd like to get the 2nd url (CDN url) and use it as my img src since it doesn't show the facebook id in the url.
I'm doing this in Ruby on Rails at the moment and am curious if there's a better way that what I have done below:
def picture_square(facebook_id, secure=false)
raw_url = "http://graph.facebook.com/" facebook_id + "/picture?type=square"
if secure
binary_img = ''
open(raw_url) do |f|
binary_img = f.read
end
encoded_img = Base64.encode64(binary_img)
return 'data:image/jpg;base64,' + encoded_img.to_s
else
return raw_url
end
end
You could call this with the following HTML (using the above example):
<img src="<%= picture_square(4, true) %>"
This definitely works and uses the inline image properties to actually render the image, but it's a bit slow if you have a bunch of images that you're trying to load.
Is there a way in Ruby that I can get the redirected URL and just return that instead of trying to get the actual raw binary data and encode it to base64?
Make a call to the graph API with this url:
http://graph.facebook.com/4/?fields=picture&type=large
This will return the image you are looking for inside the json response. The other option would be to make an http request to the first url you posted and then inspect the HTTP headers to read the location header..

Resources