How to receive frequent Facebook posts without limit error for over 200+ FB pages in Drupal 7

  0 comments

Suppose your app fetch feeds from many Facebook pages and you are constantly sending requests for getting these Facebook pages feeds, then this condition it gives the error response "Application Limits has been reached" and you can not send a request again within a certain time period.

Then in this condition, you can switch the apps on every cron OR when you got limit reached in one app then switch it to another one.

For this, I have created a setting form where I can insert many Facebook Apps credentials.

FB Settings

 

<?php /** * Form builder; Configure social feeds settings for this site. * * @ingroup forms * * @see system_settings_form() */ function nowads_facebook_settings($form, &$form_state) { $form['#tree'] = TRUE; $max = 5; $required = TRUE; $collapsed = FALSE; $nowads_facebook = variable_get('nowads_facebook', []); for ($i = 1; $i <= $max; $i++) { $form['facebook'][$i] = array( '#type' => 'fieldset', '#title' => t('NowAds Facebook APP CREDENTIAL @item_no', ['@item_no' => $i]), '#weight' => 5, '#collapsible' => TRUE, '#collapsed' => $collapsed, ); $form['facebook'][$i]['app_id'] = array( '#type' => 'textfield', '#title' => t('Facebook App ID'), '#default_value' => isset($nowads_facebook[$i]['app_id']) ? $nowads_facebook[$i]['app_id'] : '', '#description' => t('Create your Facebook app and visit this link to get App ID.', array('@this' => 'https://developers.facebook.com/apps', '@blank' => '_blank')), '#size' => 60, '#maxlength' => 100, '#required' => $required, ); $form['facebook'][$i]['secret_key'] = array( '#type' => 'textfield', '#title' => t('Facebook Secret Key'), '#default_value' => isset($nowads_facebook[$i]['app_id']) ? $nowads_facebook[$i]['secret_key'] : '', '#description' => t(' This link will help you to find out your App Secret Key.', array('@this' => 'https://developers.facebook.com/apps', '@blank' => '_blank')), '#size' => 60, '#maxlength' => 100, '#required' => $required, ); $collapsed = TRUE; $required = FALSE; } $form['submit'] = array( '#type' => 'submit', '#value' => 'Submit', '#submit' => ['nowads_facebook_settings_submit'], ); return $form; } /** * Declare nowads_facebook_settings_submit() */ function nowads_facebook_settings_submit($form, &$form_state) { variable_set('nowads_facebook', $form_state['values']['facebook']); } ?>

 

and now i fetch the feeds data via cron and switch the app on every cron or when we get limit reached in one app and then I had switched it to another one.

 

<?php /** * Implements hook_cron(). */ function nowads_cron() { global $user; // Get the running facebook app id index from here /admin/config/services/nowads. $running_app_index = variable_get('nowads_facebook_running_app_index', 1); // Fetch credential & generate facebook access tokens. $nowads_facebook = variable_get('nowads_facebook', []); if (isset($nowads_facebook[$running_app_index])) { $app_id = $nowads_facebook[$running_app_index]['app_id']; $secret = $nowads_facebook[$running_app_index]['secret_key']; if (!empty($app_id) && !empty($secret)) { $access_token = $app_id . "|" . $secret; // Check for a new post from facebook or twitter for each advertiser. If the post hasn't been made into a node, make a node, and delete the previous node. $local_biz_type = "local_biz"; // Gather all relevant data from advertiser nodes. Note that this query will filter out any advertisers that don't have an ad-group. $advertisers = db_query("SELECT DISTINCT n.nid, n.title, n.uid, n.status, u.status AS publisher_status, fb.field_fb_page_value, bp.field_big_picture_value FROM {node} n LEFT JOIN {field_data_field_ad_group} ag_old ON ag_old.entity_id = n.nid LEFT JOIN {field_data_field_ad_groups} ag ON ag.entity_id = n.nid INNER JOIN {field_data_field_fb_page} fb ON fb.entity_id = n.nid INNER JOIN {users} u ON u.uid = n.uid LEFT JOIN {field_data_field_big_picture} bp ON bp.entity_id = n.nid WHERE n.type = :loc_biz_type AND (ag_old.entity_id > 0 OR ag.entity_id > 0)", array(':loc_biz_type' => $local_biz_type))->fetchAll(); foreach ($advertisers as $advertiser) { // Filter out advertisers that don't have a url, aren't published, or are // owned by publishers that are blocked. Note that the query itself filtered advertisers // that don't have an ad group. try { if (!empty($advertiser->field_fb_page_value) && $advertiser->status === '1' && $advertiser->publisher_status === '1') { $regex_fb = '#^\s*https://www\.facebook\.com/.+$#i'; $regex_tw = '#^\s*https://twitter\.com/.+$#i'; // Check to see if the field_fb_page_value is a facebook url. if (preg_match($regex_fb, $advertiser->field_fb_page_value)) { create_ad_from_facebook_post_if_new($advertiser, $access_token); // If preg_match for facebook didn't work, check preg for twitter and make twitter embed node. } elseif (preg_match($regex_tw, $advertiser->field_fb_page_value)) { create_ad_from_twitter_post_if_new($advertiser); } } } catch (Exception $e) { continue; } } } else { if (in_array('administrator', array_values($user->roles))) { watchdog('NowAds Facebook', t('Please provide your Facebook credentials here.', array('@facebook' => url('admin/config/services/nowads'))), 'error'); drupal_set_message(t('Please provide your Facebook credentials here.', array('@facebook' => url('admin/config/services/nowads'))), 'warning'); } } } else { if (in_array('administrator', array_values($user->roles))) { watchdog('NowAds Facebook', t('Please provide your Facebook credentials here.', array('@facebook' => url('admin/config/services/nowads'))), 'error'); drupal_set_message(t('Please provide your Facebook credentials here.', array('@facebook' => url('admin/config/services/nowads'))), 'error'); } } } /** * This function is used to read in the latest posts from facebook for a given advertiser, * create and publish new ad nodes if they haven't been created already. */ function create_ad_from_facebook_post_if_new($advertiser, $access_token) { $advertiser_name_array = explode('/', $advertiser->field_fb_page_value); if ($advertiser_name_array[3] == 'pages') { $pageName = $advertiser_name_array[5]; } else { $pageName = $advertiser_name_array[3]; } $num_posts = 6; $fields = ['id', 'name', 'message', 'picture', 'full_picture', 'link', 'caption', 'description', 'object_id']; $query = ["access_token" => $access_token, "limit" => $num_posts, "fields" => implode(',', $fields)]; $fb_feeds_url = url("https://graph.facebook.com/$pageName/posts", ['query' => $query]); watchdog('Facebook Feeds URL', $fb_feeds_url); $fb_feeds_response = drupal_http_request($fb_feeds_url); $fb_feeds_data = json_decode($fb_feeds_response->data, TRUE); if (!empty($fb_feeds_data['error']['message'])) { watchdog('Facebook Feeds Error', $fb_feeds_data['error']['message']); // https://developers.facebook.com/docs/graph-api/using-graph-api/error-handling/ // Switch to another apps when an app expires(Application limit reached) error getting. if ($fb_feeds_data['error']['code'] == 341) { // Fetch credential lists /admin/config/services/nowads. $nowads_facebook = variable_get('nowads_facebook', []); if (!empty($nowads_facebook)) { $running_app_index = variable_get('nowads_facebook_running_app_index', 0); if ($running_app_index > 0 && $running_app_index < 5) { // Move forward If app not goes to end. $running_app_index++; } elseif ($running_app_index > 0 && $running_app_index > 4) { // If already running last apps go back to first app. $running_app_index = 1; } // The new app index has set but check for make sure again. for ($i = $running_app_index; $i <= 5; $i++) { if (!empty($nowads_facebook[$i]['app_id']) && !empty($nowads_facebook[$i]['secret_key'])) { variable_set('nowads_facebook_running_app_index', $i); // Just quit from loop. $i = 6; } // If loop goes to end then check from start. elseif ($running_app_index > 1 && $i == 5) { $i = 1; } } } else { watchdog('NowAds Facebook Error', t("No any apps exists here /admin/config/services/nowads")); } } } else { // Now loop through a given number of facebook posts from this advertiser to find one with the required fields (neglecting likes etc. that are also returned with /posts) for ($i = 0; $i < $num_posts; $i++) { // Make sure post has an id and either a message, picture, or link (with either name, caption, or description) if (!empty($fb_feeds_data['data'][$i]['id']) && (!empty($fb_feeds_data['data'][$i]['message']) || !empty($fb_feeds_data['data'][$i]['picture']) || (!empty($fb_feeds_data['data'][$i]['link']) && (!empty($fb_feeds_data['data'][$i]['name']) || !empty($fb_feeds_data['data'][$i]['caption']) || !empty($fb_feeds_data['data'][$i]['description']))) ) && // Make sure message doesn't end in ##, which is the code for excluding the post from inclusion in nowads. !(!empty($fb_feeds_data['data'][$i]['message']) && preg_match('/##$/', $fb_feeds_data['data'][$i]['message']) == 1)) { $facebook_id = $fb_feeds_data['data'][$i]['id']; // Make sure we haven't already made a node with the same facebook id. If the same advertiser goes through multiple publishers, thus having multiple advertiser nodes, we need to make sure that their post is pulled from facebook for each publisher, so either we should filter by publisher here using n.uid equal to $advertiser->uid, or filter by advertiser by joining with the node reference field and making the reference nid equal to $advertiser->nid. $id_match = db_query("SELECT 1 FROM {node} n INNER JOIN {field_data_field_fb_id} fb ON fb.entity_id = n.nid INNER JOIN {field_data_field_local_biz} flb ON flb.entity_id = n.nid WHERE fb.field_fb_id_value = :fb_id AND flb.field_local_biz_target_id = :loc_biz_nid LIMIT 1", array(':fb_id' => $facebook_id, ':loc_biz_nid' => $advertiser->nid))->fetchAssoc(); if (empty($id_match)) { $node = new stdClass(); $node->title = @$advertiser->title . time(); $node->type = "facebook_feed"; node_object_prepare($node); $node->language = LANGUAGE_NONE; $node->uid = 1; $node->status = 1; $node->promote = 0; $node->field_local_biz[$node->language][] = array( 'target_id' => $advertiser->nid, 'target_type' => 'node', ); $node->field_fb_id[$node->language][0]['value'] = substr($facebook_id, 0, 255); $node->field_fb_profile[$node->language][0]['value'] = utf8_encode(substr('', 0, 255)); $node->field_fb_profile[$node->language][0]['format'] = 'full_html'; if (!empty($fb_feeds_data['data'][$i]['message'])) { $node->body[$node->language][0]['value'] = utf8_encode(preg_replace('/[^(\x20-\x7F)]*/', '', $fb_feeds_data['data'][$i]['message'])); } if (!empty($fb_feeds_data['data'][$i]['picture'])) { if (!empty($fb_feeds_data['data'][$i]['link']) && (!empty($fb_feeds_data['data'][$i]['caption']) || !empty($fb_feeds_data['data'][$i]['description']))) { $node->field_fb_lnkd_piclong[$node->language][0]['value'] = utf8_encode(''); $node->field_fb_lnkd_piclong[$node->language][0]['format'] = 'full_html'; } else { // Check if this advertiser has the big picture option selected, and, if so, fill the big picture field. if (!empty($advertiser->field_big_picture_value) && $advertiser->field_big_picture_value == '1' && !empty($fb_feeds_data['data'][$i]['object_id'])) { if (!empty($fb_feeds_data['data'][$i]['full_picture'])) { $node->field_fb_image_big[$node->language][0]['value'] = utf8_encode(''); $node->field_fb_image_big[$node->language][0]['format'] = 'full_html'; } } else { $node->field_fb_image[$node->language][0]['value'] = utf8_encode(substr('', 0, 255)); $node->field_fb_image[$node->language][0]['format'] = 'full_html'; } } } if (!empty($fb_feeds_data['data'][$i]['link']) && (!empty($fb_feeds_data['data'][$i]['caption']) || !empty($fb_feeds_data['data'][$i]['description']))) { $node->field_fb_lnkd_link[$node->language][0]['value'] = utf8_encode(substr($fb_feeds_data['data'][$i]['link'], 0, 255)); $node->field_fb_lnkd_link[$node->language][0]['format'] = 'full_html'; if (!empty($fb_feeds_data['data'][$i]['name'])) { $node->field_fb_lnkd_headline[$node->language][0]['value'] = utf8_encode(substr($fb_feeds_data['data'][$i]['name'], 0, 100)); $node->field_fb_lnkd_headline[$node->language][0]['format'] = 'full_html'; } if (!empty($fb_feeds_data['data'][$i]['caption'])) { $node->field_fb_lnkd_site[$node->language][0]['value'] = utf8_encode(substr($fb_feeds_data['data'][$i]['caption'], 0, 100)); // $node->field_fb_lnkd_site[$node->language][0]['format'] = 'full_html';. } if (!empty($fb_feeds_data['data'][$i]['description'])) { $node->field_fb_lnkd_content[$node->language][0]['value'] = utf8_encode($fb_feeds_data['data'][$i]['description']); $node->field_fb_lnkd_content[$node->language][0]['format'] = 'full_html'; } } // Prepare node for saving. $node = node_submit($node); node_save($node); // Add entry to nowads_map table. db_insert('nowads_map') ->fields(array( 'nid' => $node->nid, 'advid' => $advertiser->nid, 'src' => 'facebook', 'srcid' => $facebook_id, 'uid' => $advertiser->uid, )) ->execute(); // Now delete previous node. Doing this after saving new node (even though it's more complicated) because // any error in saving the new node will prevent the deleting of the old node. delete_previous_ad_node($advertiser->nid); } // After finding the most recent facebook post from that advertiser with the required fields, we stop checking more posts. Note that we may have already saved this post and so skip creating a node in the previous if statement, but we still want to break. break 1; } } } } ?>

 

I have saved the latest posts as a node and delete the old posts.

 

Enjoy!

Add new comment