comsa/facebook-bundle

Make connection to facebook API and get user feed.

3.1.1 2022-07-20 14:58 UTC

This package is auto-updated.

Last update: 2024-04-20 18:50:38 UTC


README

composer require comsa/facebook-bundle

Setup

  1. Create the following parameters inside .env.local:
COMSA_FACEBOOK_BUNDLE_API_URL=https://graph.facebook.com
COMSA_FACEBOOK_BUNDLE_PAGE_ID=YOUR-PAGE-ID
COMSA_FACEBOOK_BUNDLE_INSTAGRAM_ID=YOUR-INSTAGRAM-USER-ID
COMSA_FACEBOOK_BUNDLE_APP_ID=YOUR-APP-ID
COMSA_FACEBOOK_BUNDLE_APP_SECRET=YOUR-APP-SECRET
COMSA_FACEBOOK_BUNDLE_ACCESS_TOKEN=YOUR-ACCESS-TOKEN
  1. Log in on: https://developers.facebook.com/
  2. Create an App and add Instagram Graph API as product.
    (Make sure your facebook page and instagram pages are linked)
  3. Go to basic settings and assign your app_id and app_secret to the corresponding variable inside your .env.local
  4. In the basic settings, scroll down and add a platform
  5. Add domains that wil use this app
  6. Generate an access token on: https://developers.facebook.com/tools/explorer/
    Make sure to add the following permissions: pages_show_list, pages_read_engagement, pages_read_user_content + all instagram permissions
  7. Use the generated token to generate a long lived user access token: https://developers.facebook.com/tools/debug/accesstoken Make sure "This new long-lived access token will never expire" message is displayed! If the message is displayed, skip step 9!
  8. Use the Generated Access Token to make the following request in Postman:

    https://graph.facebook.com/{user-id}/accounts?access_token={long-lived-user-access-token}
    

    Get user ID: From debug info --> App-Scoped User ID

  9. Assign the access_token inside the response to the corresponding variable in .env.local

  10. Assign your page id to the corresponding variable in .env.local. This can be found on facebook. Go to the page and click on about. Assign you instagram user id to the corresponding variable in .env.local. This can be found by making the following request in the Graph API: https://graph.facebook.com/{pageId}?fields=instagram_business_account&access_token={access_token}
  11. Make sure permissions are set correctly, this can be checked through business integrations on facebook: https://www.facebook.com/help/405094243235242
  12. Update database:
    php bin/console doctrine:schema:update -f
    

Configure Sulu

In config/routes_admin.yaml:

comsa_facebook_bundle_api:
  type: rest
  resource: "@FacebookBundle/Resources/config/routes/admin.yaml"
  prefix: /admin/api

Facebook-post block template:

<?xml version="1.0" ?>
<type name="facebook_post" xmlns="http://schemas.sulu.io/template/template"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:xi="http://www.w3.org/2001/XInclude"
      xsi:schemaLocation="http://schemas.sulu.io/template/template http://schemas.sulu.io/template/template-1.0.xsd">
    <meta>
        <title lang="en">Facebook Posts</title>
        <title lang="nl">Facebook Posts</title>
    </meta>
    <properties>

        <property name="loadType" type="single_select">
            <meta>
                <title lang="en">How do you want to load the posts?</title>
                <title lang="nl">Hoe wil je de posts ophalen?</title>
            </meta>

            <params>
                <param name="default_value" value="dynamically"/>

                <param name="values" type="collection">
                    <param name="dynamic">
                        <meta>
                            <title lang="en">Dynamically</title>
                            <title lang="nl">Dynamisch</title>
                        </meta>
                    </param>

                    <param name="static">
                        <meta>
                            <title lang="en">Static posts</title>
                            <title lang="nl">Vaste posts</title>
                        </meta>
                    </param>
                </param>
            </params>
        </property>

        <property name="facebook_post_selection" type="facebook_post_selection" visibleCondition="__parent.loadType == 'static'">
            <meta>
                <title lang="en">Facebook Post</title>
                <title lang="nl">Facebook Post</title>
            </meta>
        </property>

        <property name="amount" type="number" visibleCondition="__parent.loadType == 'dynamic'">
            <meta>
                <title lang="en">Amount of posts</title>
                <title lang="nl">Aantal posts</title>
            </meta>
            <params>
                <param name="min" value="0" />
            </params>
        </property>

        <xi:include href="includes/width.xml"/>
    </properties>
</type>

Instagram post block template:

<?xml version="1.0" ?>
<type name="instagram_post" xmlns="http://schemas.sulu.io/template/template"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:xi="http://www.w3.org/2001/XInclude"
      xsi:schemaLocation="http://schemas.sulu.io/template/template http://schemas.sulu.io/template/template-1.0.xsd">
    <meta>
        <title lang="en">Instagram Posts</title>
        <title lang="nl">Instagram Posts</title>
    </meta>
    <properties>

        <property name="loadType" type="single_select">
            <meta>
                <title lang="en">How do you want to load the posts?</title>
                <title lang="nl">Hoe wil je de posts ophalen?</title>
            </meta>

            <params>
                <param name="default_value" value="dynamically"/>

                <param name="values" type="collection">
                    <param name="dynamic">
                        <meta>
                            <title lang="en">Dynamically</title>
                            <title lang="nl">Dynamisch</title>
                        </meta>
                    </param>

                    <param name="static">
                        <meta>
                            <title lang="en">Static posts</title>
                            <title lang="nl">Vaste posts</title>
                        </meta>
                    </param>
                </param>
            </params>
        </property>

        <property name="instagram_post_selection" type="instagram_post_selection" visibleCondition="__parent.loadType == 'static'">
            <meta>
                <title lang="en">Instagram Post</title>
                <title lang="nl">Instagram Post</title>
            </meta>
        </property>

        <property name="amount" type="number" visibleCondition="__parent.loadType == 'dynamic'">
            <meta>
                <title lang="en">Amount of posts</title>
                <title lang="nl">Aantal posts</title>
            </meta>
            <params>
                <param name="min" value="0" />
            </params>
        </property>

        <xi:include href="includes/width.xml"/>
    </properties>
</type>

FRONTEND

Facebook post example template:

{% if block.loadType == "static" %}
  {% set facebookPosts = block.facebook_post_selection %}
{% else %}
  {% set facebookPosts = parse_facebook_widget("facebook", block.amount) %}
{% endif %}

  <div class="facebook-posts">
    <div class="row">
      {% for facebookPost in facebookPosts %}
        <div class="col-md-3">
          <div class="card post">
            {% if facebookPost.attachments %}
              {% set attachments = unserialize_attachments(facebookPost.attachments) %}
              <img src="{{ attachments[0] }}" class="card-img-top" alt="{{ facebookPost.id }}-image">
            {% endif %}
            <div class="card-body post-content">
              <p class="card-text">
                {{ facebookPost.message }}
              </p>
              {% if facebookPost.url %}
                <a href="{{ facebookPost.url }}" class="btn btn-primary">Go to post</a>
              {% endif %}
            </div>
          </div>
        </div>
      {% endfor %}
    </div>
  </div>

Instagram post example template:

{% if block.loadType == "static" %}
  {% set instagramPosts = block.instagram_post_selection %}
{% else %}
  {% set instagramPosts = parse_facebook_widget("instagram", block.amount) %}
{% endif %}

<div class="instagram-posts">
  <div class="row">
    {% for instagramPost in instagramPosts %}
      <div class="col-md-3">
        <div class="card post">
          {% if instagramPost.media %}
            {% if instagramPost.mediaType == "VIDEO" %}
              <video style="height: 100%; width: 100%;" controls>
                <source src="{{ instagramPost.media }}" type="video/mp4">
              </video>
            {% else %}
              <img src="{{ instagramPost.media }}" class="card-img-top" title="{{ instagramPost.id }}" alt="{{ instagramPost.id }}-image">
            {% endif %}
          {% endif %}
          <div class="card-body post-content">
            <p class="card-text">
              {{ instagramPost.caption }}
            </p>
            {% if instagramPost.url %}
              <a href="{{ instagramPost.url }}" class="btn btn-primary">Go to post</a>
            {% endif %}
          </div>
        </div>
      </div>
    {% endfor %}
  </div>
</div>

Commands

Get feed from page:

php bin/console comsa:facebook:get-facebook-feed {amount}

Get instagram posts:

php bin/console comsa:facebook:get-instagram-posts {amount}

The argument amount determines how many posts are retrieved. Command retrieves 100 posts by default.