beaulebens / keyring-social-importers Goto Github PK
View Code? Open in Web Editor NEWA collection of importers which pull your content back from social networks, and into your own WordPress install.
A collection of importers which pull your content back from social networks, and into your own WordPress install.
If you're using the Instagram importer and the People & Places plugin, then you'd expect that if you tagged a person in a photo, they'd be tagged as a "Person" on the imported post. Instead, this will only work if you mention them via username in the caption. It might also work if they already exist, but new People are not created properly.
In this photo; https://www.instagram.com/p/BsFVOCmgBbk/ there are multiple people mentioned, and they show up in the API response as follows:
[users_in_photo] => Array
(
[0] => stdClass Object
(
[user] => stdClass Object
(
[username] => akires
)
[position] => stdClass Object
(
[x] => 0.5342222222
[y] => 0.3244444444
)
)
[1] => stdClass Object
(
[user] => stdClass Object
(
[username] => dewizzzle
)
[position] => stdClass Object
(
[x] => 0.4542222222
[y] => 0.4684444444
)
)
[2] => stdClass Object
(
[user] => stdClass Object
(
[username] => makethingsdaily
)
[position] => stdClass Object
(
[x] => 0.8045542895
[y] => 0.3795555556
)
)
[3] => stdClass Object
(
[user] => stdClass Object
(
[username] => taurean_chic
)
[position] => stdClass Object
(
[x] => 0.6902057778
[y] => 0.3804444444
)
)
)
but on the imported post, only akires
registers (previously created).
This block of code might not be catching them properly, or this block might not be creating new entries properly (perhaps because we only get a username for them?).
Ideally, you'd be able to control the posts which are automatically created during imports using some sort of simple templating language.
The Twitter importer seems to be importing retweets, even if the option is unchecked.
I updated my Twitter account recently and yesterday went to clean up connections. I deleted the Twitter connection, which was still pulling tweets in, but listed with the old account. When I tried the test feature on the service connections page, it returned the error "This connection is NOT working correctly."
I tried to reconnect with the current app, and with a new app that I created. Each time that I've tried I've received the error "There was a problem connecting to Twitter to create an authorized connection. Please try again in a moment."
I understand that Twitter is making yet more API changes. I'm not sure if this is related. My other connections still work, and I was able to reauthenticate where needed. Some custom connections that I wrote are also still working; Twitter is the only connection that I had active that is no longer working.
With the default scope being requested in beaulebens/keyring@4a0f839 now, private activities are also imported. When they are created as posts, those posts should default to private to match other importers.
I'm trying to modify the Facebook Importer found elsewhere on Github to work a bit nicer (but this isn't about the Facebook importer specifically...)
Facebook's API is quite complex in that you can say "give me all my posts" and it'll give just the text and the ID of that post in nicely formatted JSON. To get any more information about each post (attached images, links, people you've mentioned, thumbnails of linked sites, etc), you make further HTTP requests to Facebook, giving it the post ID you're interested in and the data you want.
So the routine would go something like this
Is there a way to do step 4 from within the importer, or will I need to do something else? I can't see any mechanism from within the importer to do any actual HTTP requests... I'm guessing that's done elsewhere?
Apparently Instagram (Facebook) is deprecating their current API as of July 2018, and switching to a new Graph API.
https://developers.facebook.com/blog/post/2018/01/30/instagram-graph-api-updates/
Need to investigate and probably re-work everything to use the new API.
Running the first import on a new site seems to only get the 20 most recent Instagram pics, and then never loops back in time.
Reported by @michaeltieso
My Fitbit data is pulled in minutes, not seconds. I had to rewrite the following function in my replacement importer from
function format_duration( $num ) {
if ( $num < 3600 ) {
return sprintf( __( '%s minutes', 'keyring' ), round( $num / 60 ) );
} else {
$hours = floor( $num / 60 / 60 );
$num = $num - ( $hours * 60 * 60 );
return sprintf( __( '%1$s hours, %2$s minutes', 'keyring' ), $hours, round( $num / 60 ) );
}
}
to
function format_duration( $num ) {
if ( $num < 60 ) {
return sprintf( __( '%s minutes', 'keyring' ), $num );
} else {
$hours = floor( $num / 60 );
$min = $num - ( $hours * 60 );
return sprintf( __( '%1$s hours, %2$s minutes', 'keyring' ), $hours, $min );
}
}
Something seems to have changed recently, and Instagram videos are no longer being downloaded to the local Media Library (or updated/replaced into the post itself).
Reported here: https://wordpress.org/support/topic/instagram-videos-5/#post-9421904
I haven't dug into this, but I assume it is related to the singleton change in master
for PHP 8.2. Whenever using the plugin, the Delicious importer is always used.
Delete the Delicious file and repeat... same but now says FitBit.
Delete all except TripIt, it works fine.
Hiya. Not sure if it's possible/planned but I was hoping that for each new Instagram post that it would automatically post to Twitter & Facebook. I prefer this method only because it shares my blogs link vs sharing it directly on Instagram. Alternatively I can use IFTTT to create the trigger but wanted to see if this was possible.
My activities have stopped syncing. When I run the importer manually, it shows an error:
Strava Importer
We got an unknown error back from Strava. This is what they said.
{"message":"Authorization Error","errors":[
{"resource":"AccessToken","field":"activity:read_permission","code":"missing"}
]}
It is be possible Strava has changed scopes required to read content from profiles. I might look into this in a few weeks if nobody else beats me to it
At the core level, the importers should ideally support multiple users. Everything would work very similarly, but you should have the ability to create multiple instances of each importer, and connect them to different Keyring tokens (users), then configure them differently.
This will require changing how options are stored/handled, and will also require some UI thought around how to allow for the creation of new instances, and how to go between existing instances (list them out, link to each, etc)
Will you add the option to automatically set the post status to PRIVATE, as does the Facebook Importer? I'm unable to hack it myself and figure it'll be simple for you or someome interested. Thanks!
I deleted and re-uploaded keyring and the social importers form githug
when I try to connect to instagram, I get this dump on the page
{"error_type": "OAuthException", "code": 400, "error_message": "Invalid scope field(s): basic"}
Any ideas ?
Twitter converts links to t.co shortlinks when you create a Tweet. The importer should reverse that back to the original link when creating a local post (available via entities
property in the import data, so can also add a reprocessor to got back and fix old posts).
Originally reported here.
Would you consider adding Trakt.tv to the list of importers?
https://trakt.tv/
http://docs.trakt.apiary.io/
They apparently use oAuth2, although some of the data doesn't require any authentication.
It would be nice if all movies and TV shows watched were imported as new posts, maybe using history
:
http://docs.trakt.apiary.io/#reference/users/friends/get-watched-history?console=1
There are all sorts of modifications that people might want to make to posts before they're imported/created, and it's a losing battle to try to provide actual options for all of them. The easiest approach is probably to just add the ability to filter posts right before they're imported. We've already got an action that fires after each post is imported, allowing developers to do more customized things.
It looks like filtering $this->posts right before this line would give pretty good control over things.
Instagram videos are not downloading/embedding properly (again?).
I've confirmed that it's because of the way that URLs are coming through (with query string params), which seems to confuse mime handling in WordPress, so it rejects the files.
Working on a fix.
In running a test import against my Flickr account, I noticed that many of the imported images are upside down. It's not currently practical to re-take all of those photos with a differently oriented camera.
In the meta information for one of these images on the Flickr page for it, it shows Orientation - Rotate 180
but that information is not available in the raw_import_data
field in WordPress.
The Flickr API docs at https://www.flickr.com/services/api/flickr.photos.getInfo.htm don't mention orientation as a return value, but in using the API explorer at https://www.flickr.com/services/api/explore/flickr.photos.getInfo and a test image ID of 34000467050
I do see that information in the result: <photo ... rotation="180" ...>
So I guess unless there's a querystring param that can be appended to the fetching of an original image on the Flickr side, the importer would need to rotate an incoming image by the given amount somewhere along the way to the media library. An alternative might be to fetch the largest size on Flickr that is already auto-rotated, and use that as the main source image instead.
Hi Beau
I'm interested in using the Instapaper importer, but I'm unable to import the full content of a saved Instapaper article. I noticed the following description for the Instapaper importer:
- NEW: Downloads the full content of the article using Instapaper's API, and stores that in the post content, so that you can search it later. Disable it by creating a stub plugin, or dropping this in your theme's functions.php; add_filter( 'keyring_instapaper_download_article_texts', '__return_false' );
Is this feature already available or does it need some more development?
Thanks a lot!
Kind regards
Cliff
Add the ability to control whether detected images are set as Featured or not via filters.
Haven't had a chance to debug yet, but running the Instapaper importer only brought in my 60 oldest saved web pages. Perhaps it's a matter of not having an Instapaper Premium account.
If a post is set to Private in the source application, it should be set to Private in WP also.
Sometimes I check-in at places but set them as private check-ins. The importer imports them but sets them as public posts, instead of private posts.
With the Strava service definition in beaulebens/keyring#25 I'm now working on an importer for Strava. I've been basing it on and borrowing from the existing Moves importer.
One architectural decision I'm pondering...when the Strava keyring connection is created, I'm storing a first_date
which is the profile created_at
aka "The time at which the athlete was created." from the SummaryAthlete response to https://www.strava.com/oauth/token (ref: https://developers.strava.com/docs/reference/#api-models-SummaryAthlete)
So, assuming that the activities we want to import are from dates greater than first_date
...how best to gather them for importing?
The Strava athlete/activities endpoint supports date filtering via before
and after
params in (unix epoch format), but they can't be combined =(
eg: https://www.strava.com/api/v3/athlete/activities?after=1515801600 where after == Saturday 13th January 2018 12:00:00 AM
So, I guess we'll ask the Strava athlete/activities endpoint for ALL activities after first_date
and then page through them (endpoint defaults to 30 activities per page) until we're done.
I guess that's the approach I'll take, unless anyone has better ideas =)
Instagram have updated their API responses to include data about "carousel" posts (where you post multiple images/media items in a single post). Update the importer to handle these changes and download/embed everything from the original.
There's some example response data in https://www.instagram.com/developer/endpoints/media/
Here's what one of my own posts looks like (series of photos, no videos):
stdClass Object
(
[id] => 1737952825260742638_285663
[user] => stdClass Object
(
[id] => 285663
[full_name] => Beau Lebens
[profile_picture] => https://scontent.cdninstagram.com/vp/a156149c00825dfb66e05d6151024bb0/5B4567CC/t51.2885-19/s150x150/13414371_486301391575531_820857067_a.jpg
[username] => beaulebens
)
[images] => stdClass Object
(
[thumbnail] => stdClass Object
(
[width] => 150
[height] => 150
[url] => https://scontent.cdninstagram.com/vp/c36e9cfdb98d9d3677e8208c9e6d0fcd/5B3AA489/t51.2885-15/s150x150/e35/28763915_1742157569161436_4735371782242959360_n.jpg
)
[low_resolution] => stdClass Object
(
[width] => 320
[height] => 320
[url] => https://scontent.cdninstagram.com/vp/475b9293b5191ce6de98a78c3b057425/5B390DB9/t51.2885-15/s320x320/e35/28763915_1742157569161436_4735371782242959360_n.jpg
)
[standard_resolution] => stdClass Object
(
[width] => 640
[height] => 640
[url] => https://scontent.cdninstagram.com/vp/c1054a93ba95b3cb74353349fff02fe7/5B2CF6F4/t51.2885-15/s640x640/sh0.08/e35/28763915_1742157569161436_4735371782242959360_n.jpg
)
)
[created_time] => 1521400143
[caption] => stdClass Object
(
[id] => 17931286021042565
[text] => Arc’teryx Brize 25 vs Patagonia Nine Trails 28
[created_time] => 1521400143
[from] => stdClass Object
(
[id] => 285663
[full_name] => Beau Lebens
[profile_picture] => https://scontent.cdninstagram.com/vp/a156149c00825dfb66e05d6151024bb0/5B4567CC/t51.2885-19/s150x150/13414371_486301391575531_820857067_a.jpg
[username] => beaulebens
)
)
[user_has_liked] =>
[likes] => stdClass Object
(
[count] => 0
)
[tags] => Array
(
)
[filter] => Normal
[comments] => stdClass Object
(
[count] => 0
)
[type] => carousel
[link] => https://www.instagram.com/p/BgecuLyDZfu/
[location] =>
[attribution] =>
[users_in_photo] => Array
(
[0] => stdClass Object
(
[user] => stdClass Object
(
[id] => 22592480
[full_name] => Arc'teryx
[profile_picture] => https://scontent.cdninstagram.com/vp/3ac4f80e8ca1ccfdd4b6190c95bce991/5B38FAFA/t51.2885-19/11356945_521047711377460_3545960_a.jpg
[username] => arcteryx
)
[position] => stdClass Object
(
[x] => 0.7857777507
[y] => 0.5855394747
)
)
[1] => stdClass Object
(
[user] => stdClass Object
(
[id] => 143939018
[full_name] => Patagonia
[profile_picture] => https://scontent.cdninstagram.com/vp/d076cf1acec3604cb045281232ef9389/5B2BC258/t51.2885-19/11820461_878388088917822_530389951_a.jpg
[username] => patagonia
)
[position] => stdClass Object
(
[x] => 0.235555542
[y] => 0.5766407119
)
)
)
[carousel_media] => Array
(
[0] => stdClass Object
(
[images] => stdClass Object
(
[thumbnail] => stdClass Object
(
[width] => 150
[height] => 150
[url] => https://scontent.cdninstagram.com/vp/c36e9cfdb98d9d3677e8208c9e6d0fcd/5B3AA489/t51.2885-15/s150x150/e35/28763915_1742157569161436_4735371782242959360_n.jpg
)
[low_resolution] => stdClass Object
(
[width] => 320
[height] => 320
[url] => https://scontent.cdninstagram.com/vp/475b9293b5191ce6de98a78c3b057425/5B390DB9/t51.2885-15/s320x320/e35/28763915_1742157569161436_4735371782242959360_n.jpg
)
[standard_resolution] => stdClass Object
(
[width] => 640
[height] => 640
[url] => https://scontent.cdninstagram.com/vp/c1054a93ba95b3cb74353349fff02fe7/5B2CF6F4/t51.2885-15/s640x640/sh0.08/e35/28763915_1742157569161436_4735371782242959360_n.jpg
)
)
[users_in_photo] => Array
(
[0] => stdClass Object
(
[user] => stdClass Object
(
[id] => 22592480
[full_name] => Arc'teryx
[profile_picture] => https://scontent.cdninstagram.com/vp/3ac4f80e8ca1ccfdd4b6190c95bce991/5B38FAFA/t51.2885-19/11356945_521047711377460_3545960_a.jpg
[username] => arcteryx
)
[position] => stdClass Object
(
[x] => 0.7857777507
[y] => 0.5855394747
)
)
[1] => stdClass Object
(
[user] => stdClass Object
(
[id] => 143939018
[full_name] => Patagonia
[profile_picture] => https://scontent.cdninstagram.com/vp/d076cf1acec3604cb045281232ef9389/5B2BC258/t51.2885-19/11820461_878388088917822_530389951_a.jpg
[username] => patagonia
)
[position] => stdClass Object
(
[x] => 0.235555542
[y] => 0.5766407119
)
)
)
[type] => image
)
[1] => stdClass Object
(
[images] => stdClass Object
(
[thumbnail] => stdClass Object
(
[width] => 150
[height] => 150
[url] => https://scontent.cdninstagram.com/vp/38515d0259753b236400ebff4550512d/5B280B23/t51.2885-15/s150x150/e35/c0.0.1079.1079/29096457_171997266786965_8970175403993858048_n.jpg
)
[low_resolution] => stdClass Object
(
[width] => 320
[height] => 319
[url] => https://scontent.cdninstagram.com/vp/c0d09c37c0158937af87ed7ae08830f0/5B4B0A8A/t51.2885-15/s320x320/e35/29096457_171997266786965_8970175403993858048_n.jpg
)
[standard_resolution] => stdClass Object
(
[width] => 640
[height] => 639
[url] => https://scontent.cdninstagram.com/vp/c4a389ee044b0b349e5f97e79206b7f1/5B3C23C9/t51.2885-15/s640x640/sh0.08/e35/29096457_171997266786965_8970175403993858048_n.jpg
)
)
[users_in_photo] => Array
(
)
[type] => image
)
[2] => stdClass Object
(
[images] => stdClass Object
(
[thumbnail] => stdClass Object
(
[width] => 150
[height] => 150
[url] => https://scontent.cdninstagram.com/vp/717567afa9950f38fedc90ed0733ceb5/5B41C216/t51.2885-15/s150x150/e35/28754394_151921658809455_6055238588335915008_n.jpg
)
[low_resolution] => stdClass Object
(
[width] => 320
[height] => 320
[url] => https://scontent.cdninstagram.com/vp/c1d313cd49dd9a323ee3d899621c217a/5B42A951/t51.2885-15/s320x320/e35/28754394_151921658809455_6055238588335915008_n.jpg
)
[standard_resolution] => stdClass Object
(
[width] => 640
[height] => 640
[url] => https://scontent.cdninstagram.com/vp/4153a6494ca79ed0b38319ece5648783/5B2BEA12/t51.2885-15/s640x640/sh0.08/e35/28754394_151921658809455_6055238588335915008_n.jpg
)
)
[users_in_photo] => Array
(
)
[type] => image
)
[3] => stdClass Object
(
[images] => stdClass Object
(
[thumbnail] => stdClass Object
(
[width] => 150
[height] => 150
[url] => https://scontent.cdninstagram.com/vp/676ddce54edf168b28b235d163b4fc90/5B395CEE/t51.2885-15/s150x150/e35/28764555_1602521753179681_4382156145721081856_n.jpg
)
[low_resolution] => stdClass Object
(
[width] => 320
[height] => 320
[url] => https://scontent.cdninstagram.com/vp/ba1227ba3b07e75b699fd0325b92d2a5/5B4E6ADE/t51.2885-15/s320x320/e35/28764555_1602521753179681_4382156145721081856_n.jpg
)
[standard_resolution] => stdClass Object
(
[width] => 640
[height] => 640
[url] => https://scontent.cdninstagram.com/vp/35eda795a2292518dcecb4e9348cbc53/5B322993/t51.2885-15/s640x640/sh0.08/e35/28764555_1602521753179681_4382156145721081856_n.jpg
)
)
[users_in_photo] => Array
(
)
[type] => image
)
)
)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.