Using “share_open_graph” Facebook UI to create dyn

2019-01-21 01:23发布

Summary: My problem is getting FB.ui, via the share_open_graph method, to create a customised share dialog that contains different title, description, and picture, based on the user's actions on the page.

The question was my first and I had no reputation, so numerous links were removed, but (thanks to everyone who gave me upvotes) I have been able to rescue the screenshots that were originally missing.


EDIT: I ended up having to just use a regular popup window with a share dialog in it, it's not ideal but at least it works reliably. The more I looked around the web the more I found that many high profile respectable sites were still using popup sharing like this, so I figured in this case the advantages of using a legacy solution outweighed the extensive work in finding a proper solution, I used https://developers.facebook.com/docs/sharing/reference/feed-dialog/v2.2 with dynamic details supplied via URL query which is at least slightly more up-to-date than the sharer.php usage I was originally looking at on Buzzfeed.


My page:

I have a quiz. Ten questions, five answers to each, a result is produced assigning one of five options as the "result". Everything as far as the quiz works great. The result is pulled in when quiz is completed via Ajax/jQuery - this is so that in the future I will be able to build a PHP-based front-end for other people to manage the creation of quizzes. Whilst I happily provide the page URL in the code below, but sorry - until I fix this issue I can't publish it publicly, so you can't access it!

My aim:

When the result of the quiz is shown, it should also have Facebook and Twitter share buttons which have been customised to include a picture, title, and description that is appropriate to the user's quiz result.

Twitter button was easy to do dynamically

I just use jQuery to create a Twitter button using the same HTML as one would anywhere, with my dynamic description supplied as the data-text property, and then call twttr.widgets.load(); to activate the button.

The Facebook Share button is the problem

  • I can't add a "normal" share button - it only takes one property, the URL (doesn't change per quiz result).
  • I can't change the generic Open Graph tags that exist on the page either - although jQuery can do this, Facebook's caching means it is pointless. Plus the generic sharing buttons (FB/Twitter/G+) on every page should remain unaffected and always share the default OG tags.

So what I am doing is creating a link and appending it to the page with jQuery, and then setting the click trigger action with jQuery too. App ID is already successfully set with the FB.init() block of code. These are the methods I have tried for the click trigger:

Attempt 1: FB.ui({ method: "feed" })

FB.ui({
  method: 'feed',
  name: "I got "+response.country+"! Which European are you destined to date?",
  link: "http://advice.uk.match.com/quizzes/which-european-are-you-destined-date",
  picture: response.image,
  description: response.body
});

screenshot showing the correct details appearing but in an old-style half-working and deprecated Feed dialog

The basics work - picture, title and description are all in line with the quiz result (in this case "French") - BUT the Feed dialog is not only deprecated but also hugely inferior to the Share dialog (see below). I'd like to do this properly.

Attempt 2: FB.ui({ method: "share" })

FB.ui({
  method: 'share',
  href: "http://advice.uk.match.com/quizzes/which-european-are-you-destined-date",
  name: "I got "+response.country+"! Which European are you destined to date?",
  picture: response.image,
  description: response.body
});

screenshot showing correct modern share dialog but with generic OG tags and not my custom details

The Share dialog is current, and you can see the improvements in design and functionality compared to the deprecated Feed dialog. But in this basic usage it is just like a regular share button, and despite my attempts to provide extra information only the URL is used and the generic Open Graph tags from the page provide the content.

Attempt 3: FB.ui({ method: "share_open_graph" })

This seems to be the one I must use. I just need to work out how! * I've added: "quiz" as an object type to my app (name: matchadviceuk). * I've added: "Share a quiz" as a story type to my app based on the "quiz" option and the existing "Share" action type. * I've added: the appropriate Open Graph prefix="" content to my <head> declaration

The click function on the button now looks like:

FB.ui({
  method: 'share_open_graph',
  action_type: 'matchadviceuk:share',
  action_properties: JSON.stringify({
    type: 'matchadviceuk:quiz',
    url: "http://advice.uk.match.com/quizzes/which-european-are-you-destined-date",
    title: "I got "+response.country+"! Which European are you destined to date?",
    description: response.body,
    image: response.image
  })
});

Upon click this produces:

screenshot showing error box saying "The action you're trying to publish is invalid because it does not specify any reference objects. At least one of the following properties must be specified: quiz."

So I changed url in the above code to quiz and I get:

screenshot showing error box saying "Object at URL <url> has og:type of 'article'. The property 'quiz' requires an object of og:type 'matchadviceuk:quiz'"

This is starting to make sense - the page itself IS an article, and no that can't change. So maybe I don't want to use this new "quiz" object type at all. But if I go back to the block above and just change type to matchadviceuk:article, we get the same error about "quiz" not being defined - at this point this makes zero sense whatsoever as the "quiz" object type is now not mentioned anywhere in the code! (Possible victim of Facebook caching, which is an added complication.)

And here is where I am stuck beyond any further idea. I've even tried removing type and url attributes entirely, hoping Facebook could do its own thing, but no.

I'm not still convinced that my efforts to add object type and story type to my app were even necessary, but either way, I just cannot get this working. Please help!

Compare to:

It's Buzzfeed who do these type of quizzes a lot, and they actually do a bodge job of using a Facebook sharer.php link with the dynamic content supplied as part of the URL query string, and forcing it to open in a new window manually. It's ugly, not "official", not as user friendly, and I dare say possibly presents problems on mobile and tablet browsing. For all these reasons, I'd much prefer to do it properly with FB.ui - not only that but sharer.php is in a constant flux of "is it or isn't it deprecated?" and even the official FB developer line (can't add link due to no reputation) - is that it won't work like this for long.

Research:

I've done tons of Googling and Stack Overflow searching. Nothing quite matches my issue (which surprises me but I do have extra limitations like needing to do all this processing dynamically without separate PHP-infused results pages). This question is the only result on SO for "share_open_graph" and creates an object with FB.api and then publishes with FB.ui - sounds good apart from the fact this produces multiple posts to the user's feed, which would result in a ban from Facebook. This user was able to rely on PHP where I need pure client-side interactivity.

6条回答
孤傲高冷的网名
2楼-- · 2019-01-21 02:08

I have the exact same problem. Ended up having to use FB.api instead of FB.ui

There's an example here, where it's being used to post an og:likes action: https://developers.facebook.com/docs/opengraph/getting-started

You just have to customize the action and object to post your own custom story.

For me, the problem with this is that it posts without prompting them first with a popup window like how conventional share buttons work.

查看更多
Fickle 薄情
3楼-- · 2019-01-21 02:08

Using the Below mentioned code to Share the Dynamic content on Facebook. It Shares the Post but on the TimeLine it Shows "Anas has shared an Object" instead of Link. Below is the Link mentioned for the Post it Shares on my FB wall. Please guide

FB.ui({ method: 'share_open_graph', action_type: 'og.shares', mobile_iframe: true, action_properties: JSON.stringify({ object: { 'og:url': shareData.link, 'og:title': shareData.title, 'og:description': shareData.description, 'og:image': shareData.image } }) }, function (response) { // Action after response });

查看更多
Explosion°爆炸
4楼-- · 2019-01-21 02:18

The property 'quiz' requires an object of og:type 'matchadviceuk:quiz'." This is starting to make sense - the page itself IS an article

You were right here. After that I went to page template which referenced in 'url' parameter of 'action_properties' and added

<meta property="og:type" content="myapp:mytype" />

In your case it would be

<meta property="og:type" content="matchadviceuk:quiz" /> 

That's all, sharing through FB.ui works

Of course your developing server should have external http address (I use http://ngrok.com for such things)

Edit: anyway you should add extra parameter to the url according to which populate specific data in og:title, og:description, og:image meta tags on the page because it doesn't seem that title, description and image parameters in action_properties actually work, e.g.

...
action_properties: JSON.stringify({
    ...
    url: "http://advice.uk.match.com/quizzes/which-european-are-you-destined-date?" + response.country_id,
    ...
查看更多
神经病院院长
5楼-- · 2019-01-21 02:19

I have done with share_open_graph method with object like this,,

FB.ui({
    method: 'share_open_graph',
    action_type: 'og.shares',
    action_properties: JSON.stringify({
        object : {
           'og:url': 'http://astahdziq.in/', // your url to share
           'og:title': 'Here my custom title',
           'og:description': 'here custom description',
           'og:image': 'http://example.com/link/to/your/image.jpg'
        }
    })
    },
    // callback
    function(response) {
    if (response && !response.error_message) {
        // then get post content
        alert('successfully posted. Status id : '+response.post_id);
    } else {
        alert('Something went error.');
    }
});
查看更多
forever°为你锁心
6楼-- · 2019-01-21 02:23

I was having a similar issue and your detailed question helped me a lot to come up with a solution, thanks for putting out there.

As you suggest you create the custom action and the custom object related to the action in app settings in FB. In your case action is "share" and object is "quiz". And you should have a story such as "John Doe shared a quiz via Some-awesome-app".

In your JS code you are basically telling Facebook this story.

FB.ui({
  method: 'share_open_graph', 
  action_type: 'matchadviceuk:share',    // appNameSpace:myCustomAction
  action_properties: JSON.stringify({
    // The action properties
  })
});

You already told FB that your story has the 'quiz' object, with the 'share' action. So first you tell it where this 'quiz' object is.

FB.ui({
  method: 'share_open_graph', 
  action_type: 'matchadviceuk:share',    // appNameSpace:myCustomAction
  action_properties: JSON.stringify({
    quiz: 'http://example.com/quizItem' // customObjectProperties (found when editing your object in the fb dev portal, looks like `og:quiz`). Note: from what I can tell, every object with name `myObject` will have a `og:myObject` property.
  })
});

Now FB knows where this 'quiz' object is. Next step is to have a 'quiz' object at that location. You can create an HTML or PHP page at that URL. It is a normal HTML page with some additional meta tags. Those meta tags makes your page to be recognised as a 'quiz' object. Below is a sample HTML code and comments:

<html>
    <head>
        <meta property="og:type" content="quiz">
        <!-- this tells that the page is a quiz -->

        <meta property="og:title" content="Some page title" >
        <!-- your page must have a title for sharing -->

        <!-- you can also use og:description and og:image if you want to change more but they are optional. Again you can find these when you edit your custom object -->
        ...

Now the HTML (or PHP) page at that URL is recognised as a 'quiz' object by FB.

In my case I needed to pass some variables to share dialog as well. Therefore I used a PHP page as the object. From JS I make a call with an inline query and read that GET parameters in my PHP. so the JS becomes like:

FB.ui({
  method: 'share_open_graph', 
  action_type: 'matchadviceuk:share',    // appNameSpace:myCustomAction
  action_properties: JSON.stringify({
    quiz: 'http://example.com/quizItem?country=<populated country name>'
  })
});

And PHP file is something like

<?php
    $country = $_GET['country'];
?>
<html>
    <head>
        <meta property="og:type" content="quiz">
        <meta property="og:title" content="Quiz from <?php echo $country; ?>" >
        ...

I hope this helps. Cheers!

查看更多
何必那么认真
7楼-- · 2019-01-21 02:27

the object must be, well, an object

FB.ui({
  method: 'share_open_graph',
  action_type: 'matchadviceuk:share',
  action_properties: JSON.stringify({
    'quiz': {
       'og:type': 'matchadviceuk:quiz',
       'og:url': "http://advice.uk.match.com/quizzes/which-european-are-you-destined-date",
       'og:title': "I got "+response.country+"! Which European are you destined to date?",
       'og:description': response.body,
       'og:image': response.image
    }
  })
}, function(){});
查看更多
登录 后发表回答