0

现在,当您想使用 READ 等内置操作时,facebook 需要具有这些选项。

“一种让用户控制将其操作发布回 Open Graph 的清晰方法。在下面的示例新闻应用程序中,提供了一个清晰的“开/关”开关,适用于应用程序内所有未来的阅读操作。当用户切换将开关切换到“关闭”,这会阻止应用从那时起发布读取操作。将开关切换回“开启”会重新启用发布。“

“一种用户删除刚刚通过您的应用共享的文章的清晰方法。在下面的示例中,用户可以轻松删除由于应用发布的读取操作而共享的最近文章。”

示例图片在这里:https ://developers.facebook.com/docs/opengraph/actions/builtin/#read在标题“发布意识”下

如何创建简单的按钮来停止分享和删除分享的文章?最好的会

我一直在寻找解决方案一周没有结果...

4

3 回答 3

1

对于文章,facebook 建议您将触发器放在“阅读更多”或其他类型的“下一页”按钮/链接上,这样用户实际上正在阅读文章的可能性非常高。

为此,您可以;

  1. 在每篇文章中/上放置一个小表格,并带有一个单选按钮/复选框询问您是否要发布此文章(是/否) - 或
  2. 使用与 1 中相同类型的表单在您的网站上为您的用户首选项添加一个部分。然后您可以更进一步,让他们可以选择为您网站的每个部分、类别或页面设置首选项。

无论哪种方式,但是您决定调用需要提交表单的操作(阅读更多或下一页等),检查答案是否是/否(发布与否),然后相应地发布操作。

使用会话变量也可能是一种选择!为用户提供为当前会话发布/不发布操作的能力会非常简洁。这可以以在每个会话开始时呈现给用户的相同形式进行处理,甚至可以给他们第三个选项,“每次都问我”。

就删除现有动作而言,这可以通过获取动作实例并以与创建类似的方式运行删除命令来完成。正如我所说,这取决于您如何触发 - CURL、js api 等...检查 FB 开发文档以了解您正在使用的方法。

希望这可以帮助!

盖兹

于 2012-04-24T13:53:15.253 回答
1

您的问题有两个部分,一个是存储用户偏好,另一个是在文章页面上提供的共享/取消共享选项。问题的第一部分很简单,只需拥有一个包含最少两列(为简单起见)、用户 ID(varchar 或 long int)和 share(bool 或位)的小型数据库表即可实现。通过提供一个开/关按钮,为用户提供一个选项来切换此共享位,该按钮将共享值从 1 更改为 0(真到假),反之亦然,对于指定的用户 ID。现在,在进行社交操作(如阅读)之前,请在数据库中为登录的 facebook 用户检查此共享位,并相应地执行操作。

现在回答您问题的第二部分,您可以使用 Facebook JavaScript SDK 对 news.read 操作进行 api 调用,并提供一个回调来存储共享文章的返回 id。然后使用相同的 id 为用户提供取消共享的选项。假设您的页面中包含 jQuery,下面的内容应该可以工作(我很快就编写并测试了它,在大多数情况下应该可以工作)

在您的页面中包含以下脚本

//set this at page load or from authResponse object
var fbDataObj = {
    user_id : <some user id>,
    access_token: <some access token>
};

//set currentPostFBUrl to your article url
var currentPostFBUrl = "http://www.yourpageurl.com";

var publishPost = function (articleLink, callback) {
    FB.api(
        '/' + fbDataObj.user_id + '/news.reads',
        'post',
        { article: articleLink,
          access_token: fbDataObj.access_token },
        function(response) {
           if (!response || response.error) {
              //alert('Error occured');
              if (typeof callback === 'function') {
                callback({text: "error", id: ""});
              }
           } else {
              //alert('Share was successful! Action ID: ' + response.id);
              if (typeof callback === 'function') {
                callback({text: "success", id: response.id});
              }
           }
        });
};

var deletePost = function (postId, callback) {
    FB.api(
        postId,
        'delete',
        { access_token: fbDataObj.access_token },
        function(response) {
           if (!response || response.error) {
              //alert('Error occured');
              if (typeof callback === 'function') {
                callback({text: "error", id: ""});
              }
           } else {
              //alert('Unshare was successful!');
              if (typeof callback === 'function') {
                callback({text: "success", id: ""});
              }
           }
        });
};

var publishOrDeleteArticle = function (btn_obj) {
    var btn_name = btn_obj.attr("name");
    if (isNaN(parseInt(btn_name, 10))) {
        publishPost(currentPostFBUrl, function(status){
            if (status.text === "success") {
                btn_obj.attr("name", status.id);
                btn_obj.text("Unshare");
            }
        });
    }
    else {                  
        deletePost(btn_name, function(status){
            if (status.text === "success") {
                btn_obj.attr("name", "share");
                btn_obj.text("Share")
            }
        });
    }
};

现在在你的页面做这样的事情

编辑:(
还将 currentPostFBUrl 设置为您的文章网址,如下所示)
var currentPostFBUrl = " http://www.yourpageurl.com ";

//within script tag
$(document).ready(function(){
    $("#btn_share").click(function(e){
        e.preventDefault();
        publishOrDeleteArticle($(this));
    });
});
//your actual share/unshare button
<a id="btn_share" name="share" href="#">Share</a>

最后一点,我为我正在开发的一个最近的 facebook 应用程序编写了一个包装 js 类。有了它,您只需一行代码就可以阅读/未阅读一篇文章。里面还有其他 WordPress 包装器,但在这种情况下可以单独使用,最简单的情况是,您可以在提供初始配置和初始化后使用下面的对象(检查下面的附加代码)。代码中可能存在一些错误,并且方法可能不完整和广泛,因为我仍在研究它,但目前它应该可以解决目的。为了清楚起见,也可以在上述代码中使用以下包装器方法。随意使用/修改代码,提供反馈和评论,并在发现任何问题时回复。

/*!
 * --------------------------------------------------------------------------------------
 * Utility Library for Facebook Application
 * Contains wrapper methods for WordPress JSON API (named WPJsonApi)
 * and for Facebook Javascript SDK (named FBJsWrapper)
 * Dependency : jQuery, Facebook JavaScript SDK
 * Author : Emad Alam
 * Date: Thu Jun 07 21:11:03 2012 +0530
 * --------------------------------------------------------------------------------------
 * Notes:
 * Including this script adds a global object called FBAppUtil to the window object.
 * You may initialize the object with init method, providing init time configurations.
 * Once FBAppUtil object is initted, you get two sub-ojects, WPJsonApi & FBJsWrapper.
 * These two objects can be initted individually or while initing the main FBAppUtil.
 * Both the objects have a buffer that stores the last fetched data and responses.
 * Methods are provided to access these buffers individually.
 * Once the sub-objects are configured, their methods can be called from their references.
 *
 * Example Usage:
 *          //main object init. config can be given at this time
 *          FBAppUtil.init();
 *
 *          var wpJsonApiConfig = {
 *                  apiUrl : "http://www.example.com/wordpress/api",
 *                  permalinkEnabled : true,
 *                  crossDomain : true
 *          };
 *          FBAppUtil.WPJsonApi.init(wpJsonApiConfig);
 *          
 *          // now you may use all the methods of FBAppUtil.WPJsonApi 
 *          FBAppUtil.WPJsonApi.getRecentPosts(someParams, someCallback);
 *          FBAppUtil.WPJsonApi.getPost(someIdOrSlug, someCallback);
 *          var data = FBAppUtil.WPJsonApi.lastFetched();
 *          var response = FBAppUtil.WPJsonApi.lastResponse();
 *
 *          // other facebook related scripts and sdks initializations
 *          // at this point you should be having the FB object initialized
 *          // you may pass the authResponse object to init the FBJsWrapper or
 *          // populate one of your own to pass it to the FBJsWrapper.init(authResponse)
 *
 *          var fbJsWrapperConfig = {
 *                  userID : <logged in userId>,
 *                  accessToken : <user's accessToken>,
 *                  signedRequest : <from authResponse object>,
 *                  expiresIn : <from authResponse object>
 *              };
 *          FBAppUtil.FBJsWrapper.init(fbJsWrapperConfig);
 *          
 *          // now you may use all the methods of FBAppUtil.FBJsWrapper
 *          FBAppUtil.FBJsWrapper.sendAppRequest("some message", someCallback);
 *          FBAppUtil.FBJsWrapper.share(someArticleUrl, someCallback);
 *          FBAppUtil.FBJsWrapper.unshare(someId, someCallback);
 *          var fbdata = FBAppUtil.FBJsWrapper.dataFromLastCall();
 *          var fbresponse = FBAppUtil.FBJsWrapper.responseFromLastCall();
 */

(function (window) {

    /** Local helper Buffer Class - Start **/
    var LocalBuffer = function (size) {

        //enforce 'new' - object creation pattern
        if (!(this instanceof LocalBuffer)) {
            return new LocalBuffer(size);
        }

        //private variables
        var _buffer = {
            data        : [], //data fetched from the last successfull call
            response    : [] //response from the last call
        },
            _size = (function (size){
                        var n = parseInt(size || 10, 10);
                        return isNaN(n) ? 10 : n;
                    }(size)); //default buffer size

        var _pushToBuffer = function (name, data) {
            if (typeof _buffer[name][_size-1] !== 'undefined') {
                _buffer[name].shift(); //remove the first element in case the buffer is full
            }
            _buffer[name].push(data);
        };

        var _readFromBuffer = function (name) {
            var len = _buffer[name].length;
            return len === 0 ? {} : _buffer[name][len-1]; //read the last inserted without popping
        };

        var _getDataFromBuffer = function () {
            return _readFromBuffer("data");
        };

        var _getResponseFromBuffer = function () {
            return _readFromBuffer("response");
        };

        //expose methods
        this.pushToBuffer           =   _pushToBuffer,
        this.readFromBuffer         =   _readFromBuffer,
        this.getDataFromBuffer      =   _getDataFromBuffer,
        this.getResponseFromBuffer  =   _getResponseFromBuffer
    };  
    /** Local helper Buffer Class - End **/

    /** WordPress JSON API Plugin wrapper - Start **/
    var WPJsonApi;
    (function () {
        var instance;
        WPJsonApi = function (config) {
            if (!(this instanceof WPJsonApi)) {
                return new WPJsonApi(config);
            }
            if (instance) {
                return instance;
            }
            instance = this;

            //config variables
            var apiUrl, //complete url for the api
                cross_domain, //jsonp cross domain calls
                permalink_enabled, //whether permalink enabled
                templates, //TODO: templating system
                buffer_size; //size of the buffer

            //private variables
            var _buffer; //the LocalBuffer object

            //form the final api url string for the json call
            var _getControllerUrl = function (controller_name) {
                var url = apiUrl; //base url
                if (!permalink_enabled) {
                    url += "/?json=" + controller_name;
                    if (cross_domain) {
                        url += "&callback=?";
                    }
                } else {
                    url += "/" + controller_name;
                    if (cross_domain) {
                        url += "/?callback=?";
                    }
                }
                return url;
            };

            //fetch posts using the jQuery getJSON
            //push data and response to buffer
            //on successfull fetch, return array of post objects to the callback
            var _getRecentPosts = function (paramObj, callback) {
                var url = _getControllerUrl("get_recent_posts"); //base url for the specified controller
                if (typeof paramObj === 'function') {
                    callback = paramObj; //no parameters provided only callback
                    paramObj = {};
                }
                paramObj = paramObj || {};
                $.getJSON(url, paramObj, function(data) {
                        if (data.status === "ok") {
                            _buffer.pushToBuffer("response",
                                {
                                    status  : "ok",
                                    success : "Successfully fetched the post for the specified id/slug."
                                }
                            );
                            _buffer.pushToBuffer("data", data);
                            if (typeof callback === 'function') {
                                callback(data.posts);
                            }
                        } else if (data.status === "error") {
                            _buffer.pushToBuffer("response",
                                {
                                    status: "error",
                                    error : data.error
                                }
                            );
                        } else {
                            _buffer.pushToBuffer("response",
                                {
                                    status: "error",
                                    error : "Unknown error!"
                                }
                            );
                        }
                    }
                );
            };

            //fetch post by it's id or slug using the jQuery getJSON
            //push data and response to buffer
            //on successfull fetch, return the post object to the callback
            var _getPost = function (paramObj, callback) {
                var url = _getControllerUrl("get_post"), //base url for the specified controller
                    id  = parseInt(paramObj, 10); //assume the parameter to be id

                paramObj = paramObj || {};

                if (typeof paramObj !== 'object') {
                    if (typeof paramObj === 'number' || !isNaN(id)) {
                        paramObj = {id : id};
                    } else if (typeof paramObj === 'string') {
                        paramObj = {slug : paramObj};
                    }
                } 

                if (isNaN(parseInt(paramObj.id, 10)) && !paramObj.slug) {
                    throw {
                                status: "error",
                                error : "Provide a valid id or slug to get a post."
                            };
                }

                //TODO: Avoid server hit by searching and returning the post
                //      from the local buffer for the specified id/slug
                $.getJSON(url, paramObj, function(data) {
                        if (data.status === "ok") {
                            _buffer.pushToBuffer("response",
                                {
                                    status  : "ok",
                                    success : "Successfully fetched the post for the specified id/slug."
                                }
                            );
                            _buffer.pushToBuffer("data", data);
                            if (typeof callback === 'function') {
                                callback(data.post);
                            }
                        } else if (data.status === "error") {
                            _buffer.pushToBuffer("response",
                                {
                                    status: "error",
                                    error : data.error
                                }
                            );
                        } else {
                            _buffer.pushToBuffer("response",
                                {
                                    status: "error",
                                    error : "Unknown error!"
                                }
                            );
                        }
                    }
                );
            };

            //initialize the object and add methods to it
            var _init  = function (config) {
                if (typeof config === 'undefined') {
                    throw {
                        status: "error",
                        error : "Provide a valid configuration object to initialize WPJsonApi."
                    };
                }
                apiUrl = config.apiUrl || "/api", //assume base url relative to current page
                cross_domain = config.crossDomain || false, //jsonp cross domain calls
                permalink_enabled = config.permalinkEnabled || true, //assume permalink enabled
                templates = config.templates || {}, //TODO: templating mechanisms
                buffer_size = config.bufferSize || 10, //assume buffer size to be 10
                _buffer = new LocalBuffer(buffer_size); //new buffer object

                //expose the methods and variables
                this.getRecentPosts = _getRecentPosts; //method for fetching recent posts
                this.getPost        = _getPost; //method to fetch the post by id or slug
                this.lastFetched    = _buffer.getDataFromBuffer; //last fetched data from the buffer
                this.lastResponse   = _buffer.getResponseFromBuffer; //response from the last roundtrip to server
            };

            //init the object if config is provided while creating
            if (typeof config !== 'undefined') {
                _init(config);
            }

            //expose init
            this.init = _init;
        };
    }());
    /** WordPress JSON API Plugin wrapper - End **/

    /** FB JavaScript SDK wrapper - Start **/
    var FBJsWrapper;
    (function () {
        var instance;
        FBJsWrapper = function (config) {
            if (!(this instanceof FBJsWrapper)) {
                return new FBJsWrapper(config);
            }
            if (instance) {
                return instance;
            }
            instance = this;

            //config variables
            var access_token, //user access token
            expires_in, //time to expire
            signed_request, //the signed request object
            user_id; //user id of the current connected user

            //private variables
            var _buffer, //the LocalBuffer object
                _token_valid = true; //assume the access token to be valid

            var _isTokenValid = function () {
                //TODO: Implement the method to check for invalid access tokens or
                //      invalid calls to FB APIs
                return _token_valid;
            };

            var _read = function (article, callback) {
                //TODO: Avoid repeated code, make a generic function

                var paramObj = {}; //start with an empty parameter

                paramObj.article = article; //add article to the parameter object

                //if token is invalid, no further calls are possible, so return
                if (!_isTokenValid()) {
                    //TODO: Provide a better way of handling this
                    throw {
                        status: "error",
                        error : "Provide a valid configuration object to initialize FBJsWrapper."
                    };
                }

                if (!(!access_token || 0 === access_token.length)) {
                    paramObj.access_token = access_token; //access token not empty, add it to the parameter object
                }

                //TODO: Make a generic function to handle this call
                FB.api(
                    '/' + user_id + '/news.reads',
                    'post',
                    paramObj,
                    function(response) {
                        var i,
                            message, // response error message
                            exists = false, //assume the words don't exist in the message           
                            probable_words = [  "session has expired",
                                                "session has been invalidated",
                                                "session is invalid",
                                                "has not authorized" ]; //list of words that may denote an invalid token

                        //no response, return
                        if (!response) {
                            _buffer.pushToBuffer("response",
                                {
                                    status  : "error",
                                    error   : "No response returned by the server!"
                                }
                            );
                            return;
                        }

                        //some error
                        if (response.error) {
                            message = response.error.message.toLowerCase(); //case insensetive match
                            for (i in probable_words) {
                                if (message.indexOf(probable_words[i]) > -1) {
                                    exists = true;
                                    break;
                                }
                            }
                            if (exists) {
                                _token_valid = false; //denotes invalid token
                            }
                            _buffer.pushToBuffer("response",
                                {
                                    status  : "error",
                                    error   : exists ? "Invalid access token!" : response.error.message
                                }
                            );
                        } else {
                            _buffer.pushToBuffer("response",
                                {
                                    status  : "ok",
                                    success : "Successfully read the specified article."
                                }
                            );
                            _buffer.pushToBuffer("data", response);
                            if (typeof callback === 'function') {
                                callback(response.id);
                            }
                        }
                    });
            };

            var _unread = function (articleId, callback) {
                //TODO: Avoid repeated code, make a generic function

                var paramObj = {}; //start with an empty parameter

                //if token is invalid, no further calls are possible, so return
                if (!_isTokenValid()) {
                    //TODO: Provide a better way of handling this
                    throw {
                        status: "error",
                        error : "Provide a valid configuration object to initialize FBJsWrapper."
                    };
                }

                if (!(!access_token || 0 === access_token.length)) {
                    paramObj.access_token = access_token; //access token not empty, add it to the parameter object
                }

                //TODO: Make a generic function to handle this call
                FB.api(
                    articleId,
                    'delete',
                    paramObj,
                    function(response) {
                        var i,
                            message, // response error message
                            exists = false, //assume the words don't exist in the message           
                            probable_words = [  "session has expired",
                                                "session has been invalidated",
                                                "session is invalid",
                                                "has not authorized" ]; //list of words that may denote an invalid token

                        //no response, return
                        if (!response) {
                            _buffer.pushToBuffer("response",
                                {
                                    status  : "error",
                                    error   : "No response returned by the server!"
                                }
                            );
                            return;
                        }

                        //some error
                        if (response.error) {
                            message = response.error.message.toLowerCase();//case insensetive match
                            for (i in probable_words) {
                                if (message.indexOf(probable_words[i]) > -1) {
                                    exists = true;
                                    break;
                                }
                            }
                            if (exists) {
                                _token_valid = false; //denotes invalid token
                            }
                            _buffer.pushToBuffer("response",
                                {
                                    status  : "error",
                                    error   : exists ? "Invalid access token!" : response.error.message
                                }
                            );
                        } else {
                            _buffer.pushToBuffer("response",
                                {
                                    status  : "ok",
                                    success : "Successfully unread the specified article."
                                }
                            );
                            _buffer.pushToBuffer("data", response);
                            if (typeof callback === 'function') {
                                callback();
                            }
                        }
                    });
            };

            var _sendAppRequest = function (message, callback) {
                var paramObj = {}; //start with an empty parameter

                if (typeof message === 'function') { //no message only callback provided
                    callback = message;
                    message = 'Invite friends to this app.';
                }

                paramObj.method = 'apprequests';
                paramObj.message = message.toString();
                if (!(!access_token || 0 === access_token.length)) {
                    paramObj.access_token = access_token; //access token not empty, add it to the parameter object
                    paramObj.display = 'iframe'; //access token provided, iframe can be used
                } else {
                    paramObj.display = 'popup'; //no access token present, use popup dialog
                }

                FB.ui(paramObj, function (request, to) {
                    //TODO: Handle the error conditions
                    _buffer.pushToBuffer("response",
                        {
                            status  : "ok",
                            success : "Successfully sent the app request."
                        }
                    );
                    _buffer.pushToBuffer("data", { request: request, to: to });
                    if (typeof callback === 'function') {
                        callback(request, to);
                    }               
                });
            };

            var _init  = function (config) {
                if (typeof config === 'undefined') {
                    throw {
                        status: "error",
                        error : "Provide a valid configuration object to initialize FBJsWrapper."
                    };
                }
                access_token = config.accessToken || "", //assume a blank access token, will try to call FB.api without it
                expires_in = config.expiresIn || 0, //jsonp cross domain calls
                signed_request = config.signedRequest || {}, //signed request parameter
                user_id = config.userID || 'me', //assume 'me' (for a user it's user_id but for pages and apps it might be something else)
                buffer_size = config.bufferSize || 10, //default buffer size
                _buffer = new LocalBuffer(buffer_size); //local buffer object

                //expose the methods and variables
                this.sendAppRequest         = _sendAppRequest; //method for sending the app request from a dialog
                this.share                  = _read; //method to read an article, news.read
                this.unshare                = _unread //method to unread a previously read article
                this.dataFromLastCall       = _buffer.getDataFromBuffer; //last fetched data from the buffer
                this.responseFromLastCall   = _buffer.getResponseFromBuffer; //response from the last roundtrip to server
            };

            //init the object if config is provided while creating
            if (typeof config !== 'undefined') {
                _init(config);
            }

            //expose init
            this.init = _init;
        };
    }());
    /** FB JavaScript SDK wrapper - End **/

    /** The main Utility Class - Start **/
    var FBAppUtil;
    (function () {
        var instance;
        FBAppUtil = function () {
            if (!(this instanceof FBAppUtil)) {
                return new FBAppUtil();
            }
            if (instance) {
                return instance;
            }
            instance = this;

            var _init  = function (config) {
                if (typeof config !== 'undefined'){ 
                    if (typeof config.WPJsonApi !== 'undefined') {                  
                        this.WPJsonApi = new WPJsonApi(config.WPJsonApi); //WPJsonApi configuration provided while init
                    } else {
                        this.WPJsonApi = new WPJsonApi();
                    }
                    if (typeof config.FBJsWrapper !== 'undefined') {                    
                        this.FBJsWrapper = new FBJsWrapper(config.FBJsWrapper); //FBJsWrapper configuration provided while init
                    } else {
                        this.FBJsWrapper = new FBJsWrapper();
                    }
                } else {
                    this.WPJsonApi = new WPJsonApi();
                    this.FBJsWrapper = new FBJsWrapper();
                }
            };

            //expose the methods and variables
            this.init = _init;
        };
    })();
    /** The main Utility Class - End **/

    // Expose the Utility to the global object
    window.FBAppUtil = new FBAppUtil();
})(window);

FBAppUtil.FBJsWrapper.share(someArticleUrl, someCallback); FBAppUtil.FBJsWrapper.unshare(someId, someCallback);

于 2012-06-14T10:04:14.703 回答
0

开/关发布与Facebook Graph API无关,您必须自己实现这一点。应该有一个与用户表相关的标志即 is_publish 。如果用户通过单击用户开/关按钮授予权限,则您可以发布该操作,并且只有当用户在文章页面上停留至少 10 秒时,才能发布更多操作,为此您可以这样做

setTimeout('readArticle()', 10000);

希望这可以帮助!

于 2014-01-27T19:40:51.320 回答