This page was originally written for the 2.x branch of Drupal for Facebook. You're probably using the 3.x branch (or later). The 3.x branch includes a file, modules/fb/contrib/fb_example.module, with code showing the updated API for fb_stream_publish_dialog(). Some of the information that follows is out of date.

Facebook provides a Stream API for publishing content to "streams". These streams include user and page Walls, and also allows you update a user's status. Read Facebook's documentation to get a sense of everything that's possible using these APIs.

Drupal for Facebook includes a module, fb_stream.module, to simplify publishing to Facebook Streams.

fb_stream_publish_dialog()

The fb_stream_publish_dialog() function presents the user with a dialog box. This form allows them to make edits to the content before it is published to their wall, or to skip publishing entirely.

The parameters expected by fb_stream_publish_dialog() closely mirror the parameters expected by FB.Connect.streamPublish (Connect pages) and Facebook.streamPublish (Canvas pages). Consult that documentation for complete details. Note that fb_stream_publish_dialog() function for both Connect and Canvas page apps.

You may call fb_stream_publish_dialog() from any of Drupal's hooks. Use PHP code to compose the messages and control when they are published. Below is an example, from a module called dff_custom. This code is used on the drupalforfacebook.org forums.


/**
 * Implementation of hook_form_alter.
 *
 * Adds a checkbox to node edit and comment forms.  This checkbox lets
 * facebook users know that content may be published to their Wall,
 * and gives them a chance to prevent that.
 */
function dff_custom_form_alter(&$form, $form_state, $form_id) {

  if (isset($GLOBALS['_fb']) && fb_facebook_user()) {
    if ($form['#id'] == 'node-form') {
      // Add checkbox to control feed publish.
      $form['dff_custom']['stream_publish'] = array(
        '#type' => 'checkbox',
        '#title' => 'Share on Facebook',
        '#default_value' => TRUE,
      );
    }
    else if ($form['form_id']['#value'] == 'comment_form') {
      // Add checkbox to control feed publish.
      $form['dff_custom']['stream_publish'] = array(
        '#type' => 'checkbox',
        '#title' => 'Share on Facebook',
        '#default_value' => TRUE,
      );
    }
  }

}

/**
 * Implementation of hook_nodeapi().
 *
 * Publish to facebook Walls when users submit nodes.
 */
function dff_custom_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  if ($op == 'insert' || $op == 'update') {
    if (isset($node->stream_publish) && $node->stream_publish) {
      //dpm($node, "dff_custom_nodeapi, publishing to stream");
      // http://wiki.developers.facebook.com/index.php/Attachment_(Streams)
      $attachment = array(
        'name' => $node->title,
        'href' => url('node/' . $node->nid, array('absolute' => TRUE)),
        'description' => $node->teaser,
      );

      $user_message = t('Check out my latest post on !site...',
                        array('!site' => variable_get('site_name', t('my Drupal for Facebook powered site'))));
      $actions = array();
      $actions[] = array('text' => t('Read More'),
                         'href' => url('node/'.$node->nid, array('absolute' => TRUE)),
      );
      fb_stream_publish_dialog(array('user_message' => $user_message,
                                     'attachment' => $attachment,
                                     'action_links' => $actions,
                               ));
    }
  }


}

/**
 * Implementation of hook_comment().
 *
 * Publish to facebook Walls when users submit comments.
 */
function dff_custom_comment(&$a1, $op) {
  if ($op == 'insert' || $op == 'update') {
    if ($a1['stream_publish']) {
      //dpm($a1, "dff_custom_comment, publishing to stream");
      $node = node_load($a1['nid']);
      
      // http://wiki.developers.facebook.com/index.php/Attachment_(Streams)
      $attachment = array(
        'name' => $a1['subject'],
        'href' => url('node/' . $a1['nid'], array('absolute' => TRUE, 'fragment' => 'comment-' . $a1['cid'])),
        'description' => $a1['comment'],
        'properties' => array(t('In reply to') => array('text' => $node->title, 'href' => url("node/" . $node->nid, array('absolute' => TRUE)))),
      );

      $user_message = t('Check out my latest comment on !site...',
                        array('!site' => variable_get('site_name', t('my Drupal for Facebook powered site'))));
      $actions = array();
      $actions[] = array('text' => t('Read More'),
                         'href' => url('node/'.$a1['nid'], array('absolute' => TRUE)),
      );
      fb_stream_publish_dialog(array('user_message' => $user_message,
                                     'attachment' => $attachment,
                                     'action_links' => $actions,
                               ));
    }
  }
 
}



Comments

Miquel Carol’s picture

I changed some lines of this code to looks more fun on facebook's wall.

I created a Image Field with CCK module, named field_imagefb to put an image on the streams, in the post and on comments. The modification call the image when use the fb_stream_publish_dialog().

I use the strip_tags PHP function, to correct a little bug that not show the teaser on streams. Drupal use html text and Facebook today only accept plain text. Strip_tags correct this easyly. ;)

/**
* Implementation of hook_form_alter.
*
* Adds a checkbox to node edit and comment forms.  This checkbox lets
* facebook users know that content may be published to their Wall,
* and gives them a chance to prevent that.
*/
function dff_custom_form_alter(&$form, $form_state, $form_id) {

  if (isset($GLOBALS['fb']) && fb_facebook_user()) {
    if ($form['#id'] == 'node-form') {
      // Add checkbox to control feed publish.
      $form['dff_custom']['stream_publish'] = array(
        '#type' => 'checkbox',
        '#title' => 'Share on Facebook',
        '#default_value' => TRUE,
      );
    }
    else if ($form['form_id']['#value'] == 'comment_form') {
      // Add checkbox to control feed publish.
      $form['dff_custom']['stream_publish'] = array(
        '#type' => 'checkbox',
        '#title' => 'Share on Facebook',
        '#default_value' => TRUE,
      );
    }
  }

}

/**
* Implementation of hook_nodeapi().
*
* Publish to facebook Walls when users submit nodes.
*/
function dff_custom_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  if ($op == 'insert' || $op == 'update') {
    if (isset($node->stream_publish) && $node->stream_publish) {
      //dpm($node, "dff_custom_nodeapi, publishing to stream");
      // http://wiki.developers.facebook.com/index.php/Attachment_(Streams)
      $attachment = array(
        'name' => $node->title,
        'href' => url('node/' . $node->nid, array('absolute' => TRUE)),
        'description' => strip_tags($node->teaser),
				'media' => array(array('type' => 'image', 'src' => url(($node->field_imagefb[0]['filepath']), array('absolute' => TRUE)), 'href' => url('node/' . $node->nid, array('absolute' => TRUE)))),
      );

      $user_message = t('Check out my latest post on !site...',
                        array('!site' => variable_get('site_name', t('my Drupal for Facebook powered site'))));
      $actions = array();
      $actions[] = array('text' => t('Read More'),
                         'href' => url('node/'.$node->nid, array('absolute' => TRUE)),
      );
      fb_stream_publish_dialog(array('user_message' => $user_message,
                                     'attachment' => $attachment,
                                     'action_links' => $actions,
                               ));
    }
  }


}

/**
* Implementation of hook_comment().
*
* Publish to facebook Walls when users submit comments.
*/
function dff_custom_comment(&$a1, $op) {
  if ($op == 'insert' || $op == 'update') {
    if ($a1['stream_publish']) {
      //dpm($a1, "dff_custom_comment, publishing to stream");
      $node = node_load($a1['nid']);
     
      // http://wiki.developers.facebook.com/index.php/Attachment_(Streams)
      $attachment = array(
        'name' => $a1['subject'],
        'href' => url('node/' . $a1['nid'], array('absolute' => TRUE, 'fragment' => 'comment-' . $a1['cid'])),
        'description' => strip_tags($a1['comment']),
        'media' => array(array('type' => 'image', 'src' => url(($node->field_imagefb[0]['filepath']), array('absolute' => TRUE)), 'href' => url('node/' . $node->nid, array('absolute' => TRUE)))),
        'properties' => array(t('In reply to') => array('text' => $node->title, 'href' => url("node/" . $node->nid, array('absolute' => TRUE)))),
      );

      $user_message = t('Check out my latest comment on !site...',
                        array('!site' => variable_get('site_name', t('my Drupal for Facebook powered site'))));
      $actions = array();
      $actions[] = array('text' => t('Read More'),
                         'href' => url('node/'.$a1['nid'], array('absolute' => TRUE)),
      );
      fb_stream_publish_dialog(array('user_message' => $user_message,
                                     'attachment' => $attachment,
                                     'action_links' => $actions,
                               ));
    }
  }

}
splash112’s picture

Instead of media I used "picture" tag and an imagacache preset.
'picture'=> imagecache_create_url('product', $node->field_image_cache[0]['filepath'], TRUE, TRUE),

Works pretty well so far

masipila’s picture

I had problems to get the checkboxes to show up in the node edit / comment form.

The problem was that in the hook_form_alter function the first if statement was

if (isset($GLOBALS['fb']) && fb_facebook_user()) {

For some reason the $GLOBALS['fb'] was not set in all cases. I'm using the 3.x-dev version from May 18, 2010.

I changed the hook_form_alter function as a follows to get it work.

function dff_custom_form_alter(&$form, $form_state, $form_id) {
  if (module_exists('fb')) {
    if (fb_facebook_user()) {
      if ($form['#id'] == 'node-form') {
        // Add checkbox to control feed publish.
        $form['dff_custom']['stream_publish'] = array(
          '#type' => 'checkbox',
          '#title' => 'Share on Facebook',
          '#default_value' => TRUE,
        );
      }
      else if ($form['form_id']['#value'] == 'comment_form') {
        // Add checkbox to control feed publish.
        $form['dff_custom']['stream_publish'] = array(
          '#type' => 'checkbox',
          '#title' => 'Share on Facebook',
          '#default_value' => TRUE,
        );
      }
    }
  }
}
Dave Cohen’s picture

It should be $GLOBALS['_fb']. I've changed the example above to show that.

rgs’s picture

websites-development.com’s picture

If you want to publish to the application's wall, you need to add the parameter target_id = ID_of_application

fb_stream_publish_dialog(array(
                                    'target_id' => 'XXXXXXXXXX'
                                     'user_message' => $user_message,
                                     'attachment' => $attachment,
                                     'action_links' => $actions,
                               ));
Jean Rodas’s picture

It's posible to publish in both Facebook Walls, User and Aplication? How?

Thanks.

millions’s picture

I used target_id to post my page's ID#. It worked, and posted directly to my page's wall. There should be a way to post to both, I'm guessing put down two target_ids? Is there a way to have the option on the pop-up like other apps use? Checkboxes for posting to the page and users wall?

Dave Cohen’s picture

Edit the code to call the method once with a target_id, then again without. Without the target_id it should bring up a popup and post to the logged-in user's wall.

millions’s picture

Ok thanks Dave. Is there anyone to have a popup with checkboxes to choose which wall to post on, or both? (page, user, both)

atxajon’s picture

I can´t post to my page´s wall, it only allows me to post to my user´s wall. Using my user´s 'target_id' works, but it doesn´t for my page´s id, says "An invalid target was specified: 'xxxxxxxxxx'. The target must be a page, event, or user that the actor can post on the wall of."

Has anyone come across this one before? has this anything to do with the way the app on facebook is set, or do I have to tweak something on the drupal end?

rafinskipg’s picture

USE actor_id , instead of target_id

OR !! User "XXXXXXX" instead of 'XXXXXX' (working)

Marko B’s picture

http://developers.facebook.com/docs/reference/rest/stream.publish

Here is stated "You cannot publish to an application profile page's Wall."

wilbersmith’s picture

I am getting this same notice when posting to a group target id, simply by applying the following single line.

      fb_stream_publish_dialog(array(
                                     'target_id' => 'XXXXXXXXX',
                                     'message' => $user_message,
                                     'attachment' => $attachment,
                                     'action_links' => $actions,
                               ));

I have tried many different things, including using the actor_id and just posting to pages but I always get the same response. Please help.

ebeyrent’s picture

This doesn't work for me either.

gabash’s picture

With this code a member publish content to his own stream.

When we have facebook connect app with registered members allowing the site with all the "Facebook Extended Permissions" then we can publish new content to their stream just like a "Fan page" publish content to the page members.

Am i right? how can this be done?

Marko B’s picture

"Drupal for Facebook includes a module, fb_stream.module, to simplify publishing to Facebook Streams..."

I wouldnt call any part of facebook for drupal module simple. Simple woule be, I install module, login trough facebook connect and when i post something there is checkbox if i want this on my wall.

Ok i have to make module with code abowe, right?
If users can post to their wall, can they do it without me making an app, is app BASE for all other things?

p.s.
also i had to make curl and openssl extension in PHP enabled to even make an app.

Dave Cohen’s picture

If you prefer, use Facebook's APIs directly, instead of fb_stream.module.

The 3.x branch of modules/fb includes modules/fb/contrib/fb_example.module. fb_example includes code for this as well as other ideas for customizing Drupal for Facebook.

I'm actually not sure whether you need to create an app. I haven't tried without one.

I'm so sorry there is no checkbox labeled, "do what deepM wants". No one submitted a patch for that.

Marko B’s picture

Are you creator or maintener of module? How can you not know inner-workings of module and not now if its needed to create app or not?

I realized that you do have to make app as nothing will work without this, not sure if FB asks for this also or is it possible without it.

I am pissed as i spent hours testing, reading issues, catching versions etc and then i find word "simple". Ok i know it cannot be like you said "do what deepM wants", but i hate when i find so much confusion in module and cannot get definite answers.

Probably it would be easier if i made it like you proposed, overide node submit form and when submiting node connect to FB and upload new data. Hate it when "Drupal way" is in 50% cases long, harder and nerv wrecinking way, thats all.

Ok to calm things down, dont get mad as i am now, just saying what i think is not good and it is confusing workflow of module(s).

p.s.
With all this i appritiate all the work and effort of community and sorry for my tone :-)

Maybe its FB problem also, try twitter module, you install it, input API keys of your profile and you are good to go. Ok its been messed up a bit with oAuth but still rather fast integration and clear what you should do.

Marko B’s picture

Here is the deal Dave :-)

This is what module says when on modules pages.

Streams (fb_stream.module) 6.x-3.0-beta2 Post to Facebook Streams (a.k.a. News Feed or Wall)

Ok so you would assume its "normal module", not an API. So you go and search for options in content types and all around to make it work. Then you somehow get here. http://drupal.org/node/685320#comment-2980494
and you relize its an API, ok then why is then this not mentiond on most important place, module page. Also why dont you link to this example page on module page, instead of FB page, Its not much use if you go there, just more confusing things.

Ok then on this example page your code is WRONG. Variable in fb_stream_publish_dialog shouldnt be user_message but only message, without this Stream will not work, why is that not corrected?

Also i read carefully readme file, there is nowhere mentioned that you must enable php_curl and php_openSSL.

Problem is that, with this process of finding out all this things will pass many people and loose time, its bad for community, for progress for everything as we all make the same mistakes that could be avoided. Time could be spent for more useful things, less issues here and time spent to answer the same things. Include all this in readme and help us all.

Also, mention to new drupalers they have to make a module out of this code to make it work or that they can use contrib module "example" in latest version. I would recommend to not call this module "example" as its highly functional module, that offers functions users need very much and example will confuse people and make them not install but search here for solutions.

p.s.
sorry if you hate me now, but i dont think this was done well and think as its rather important part of www (FB) and it should be handled better.

Marko B’s picture

In example module code

function fb_example_form_alter(&$form, $form_state, $form_id) {

you have some old naming for forms "dff_custom" but this nameing wont make problems, i know its Nitpicking :-)

tahiticlic’s picture

I totally agree... There's no easy way to use this module... and I'm a developer.

I've a project using FB auto publishing, seeing this module I told my client it was a 1 day work... 1 day has already been spent, and it's always "an error has occured, please retry later" from FB. And many many warning and notice from module. Please, document it...

Drupal rocks!
www.tahiticlic.com

cibonato’s picture

I'm trying to publish on FB Wall and I can not make the checkbox appear. I've been debugging the code and, for example, to get any positive result I had to change the following line:

if (isset($GLOBALS['_fb']))

This way it was not working at all.

if (module_exists('fb'))

This way it is still not working, but it seems I'm closer to the solution.

Right now, my problem is that fb_facebook_user() is returning FALSE. What is the module I have to enable to get TRUE? I just want to enable publishing on the Wall and the users MUST be the ones I have on the local system. I mean, the authentication is done using our LDAP server.

Of course, the users will need to have a Facebook user and I still don't see where/when I should provide this data. Maybe I'm misunderstanding something.

Greetings.

wonka68’s picture

Well, after many many hours of trying, I eventually got this to work. I have to say, the documentation, or lack of documentation, stinks. I salute and applaud whoever took the time and trouble to develop this API, but crucial prerequisites are simply not mentioned. What's worse, there is a list of instructions that lull you into a false sense of security - you would expect that by following them to the letter that this publishing module would work. Not true though.

This is a failing of lots of software developers - not bothering to write up the "unglamorous" documentation. Please please please don't shoot yourself in the foot by neglecting this.

What I had trouble with was the "share with Facebook" checkbox failing to appear. I traced it to the line:
If (fb_facebook_user()) and further down the stack, found there was no Facebook session.

I even installed a Debugger to go through line by line.

The answer was that I didn't have the Facebook Connect block enabled in the Block configuration.

I'd also neglected to create a Facebook application within my Facebook profile, and you also need to register this in the Facebook settings within Drupal. To be fair, these 2 issues had been mentioned by other Users, so I had picked up on this.

Dave Cohen’s picture

you would expect that by following them to the letter that this publishing module would work. Not true though.

The very first sentence of this documentation page highlights that this is for an older version of the project. Did you read that far?

If you want to actually read the documentation, start with the README.txt that comes with the modules.

If you're still not satisfied, and I offer you this just because your criticism is so constructive, we'll fully refund you the cost of the software. Just send me the receipt where you originally purchased it and I'll get you reimbursed right away.

stieglitz’s picture

Dave after reading through this thread I just want to say Thank you. You have made it quite clear from the beginning of the project the complexity and challenging nature of the module. I think many users expect to pick up the module and use it without really following the development of it. You've done a great job and the more I use it the more I realize the power of it.

Slacky08’s picture

Hi,

Just wanted to share something I recently found out regarding this code. I had created a custom .tpl.php file to theme my content type edit form (the form where I wanted the "Share on Facebook" button to appear.

However, for some reason it was appearing below the Save / Preview buttons. Yet, on forms where I hadn't edited the form theme, it appeared above. I got it work using the code:

print drupal_render($form['fbpublish']['stream_publish']);

Which allows you to position that "Share on Facebook" checkbox and text anywhere you like.

Hope this helps someone.

Cheers,

Richard

Countzero’s picture

With October 2nd dev version, I had to change line 88 of fb_example.module from

    if ($form['#id'] == 'node-form') {

to

    if ($form['#id'] == 'page-node-form') {

... to get the 'Share on Facebook' checkbox. Probably a D6 -> D7 namespace convention change.

I couldn't manage to post to my wall yet but thought it might help some to mention that.

Update : the code in this module isn't D7 ready. Here is a working implementation of a hook which works for a D7 node :

// nodeapi disappeared in D7 so you have to use node_insert, node_update and the like
function  fb_example_node_update($node) {
    if (isset($node->stream_publish) && $node->stream_publish) {
      $attachment = array(
        'name' => $node->title,
        'href' => url('node/' . $node->nid, array('absolute' => TRUE)),
        // No more $node->content nor $node->teaser, but fields
        'description' => filter_xss($node->body['und'][0]['value'], array()),
      );
      if ($logo_path = theme_get_setting('logo_path')) {
        $url = url($logo_path, array('absolute' => TRUE));
        $attachment['media'][] = array(
          'type' => 'image',
          'src' => $url,
          'href' => $url,
        );
      }
      $user_message = t('Check out my latest post on !site...',
                        array('!site' => variable_get('site_name', t('my Drupal for Facebook powered site'))));
      $actions = array();
      $actions[] = array(
        'text' => t('Read More'),
        'href' => url('node/' . $node->nid, array('absolute' => TRUE)),
      );
      fb_stream_publish_dialog(array('message' => $user_message,
                                     'attachment' => $attachment,
                                     'action_links' => $actions,
                               ));
    }
  }

Hope it helps.

maxchock’s picture

Hi, can you share the custom module that you port from D6 to D7?? I've tried to replace your code here to my custom module but it still doesn't show the check box on D7.

Thanks.

Countzero’s picture

I just took the code from the fb_example.module and added the D7 hook. You can find it in the Services module's folder.

As the namespaces also changed in D7, the first lines of the previous post are needed but should be adapted to suit the name of your content type if it's not the standard one.

PS : Sorry for the late answer but for some reason I didn't receive the notification for your post.

navinkmrsingh’s picture

You can also use (at line 88)

 if (substr($form['#id'], -9) == 'node-form') {

in place of

 if ($form['#id'] == 'page-node-form') {

This will ensure 'Share on Facebook' option available on all node forms including the comment-node-form

narendrasonitest’s picture

Hi, i am using this module but still not connecting facebook

i have warning on my home page---- "Not able to connect with Facebook"

suggest me....