Skip to content

Commit

Permalink
chore: general updates (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
ReenigneArcher authored Dec 7, 2024
1 parent 3709b19 commit 6516913
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 192 deletions.
44 changes: 0 additions & 44 deletions .github/workflows/CI.yml

This file was deleted.

60 changes: 60 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
name: CI

on:
pull_request:
branches: [master]
types: [opened, synchronize, reopened]
push:
branches: [master]
workflow_dispatch:

concurrency:
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true

jobs:
action:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: facebook-post-action
uses: ./
with:
access_token: ${{ secrets.FACEBOOK_ACCESS_TOKEN }}
fail_on_error: true
message: |
${{ github.event.repository.name }} - ${{ github.ref_name }} test
page_id: ${{ secrets.FACEBOOK_PAGE_ID }}
url: ${{ github.event.repository.html_url }}/actions/runs/${{ github.run_id }}

release:
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
needs:
# - pytest
- action
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Release
id: setup-release
uses: LizardByte/setup-release-action@v2024.919.143601
with:
github_token: ${{ secrets.GH_BOT_TOKEN }}

- name: Create Release
id: action
uses: LizardByte/create-release-action@v2024.919.143026
with:
allowUpdates: false
artifacts: ''
body: ${{ steps.setup-release.outputs.release_body }}
generateReleaseNotes: ${{ steps.setup-release.outputs.release_generate_release_notes }}
name: ${{ steps.setup-release.outputs.release_tag }}
prerelease: true
tag: ${{ steps.setup-release.outputs.release_tag }}
token: ${{ secrets.GH_BOT_TOKEN }}
13 changes: 13 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM python:3.12-alpine3.18 AS base

RUN python -m pip install --no-cache-dir --upgrade pip setuptools wheel

COPY . /app

WORKDIR /app
RUN python -m pip install --no-cache-dir --upgrade -r requirements.txt

# github will mount the `GITHUB_WORKSPACE` directory to /github/workspace
# https://docs.github.com/en/actions/creating-actions/dockerfile-support-for-github-actions#workdir

ENTRYPOINT ["python", "/app/action/main.py"]
5 changes: 0 additions & 5 deletions HISTORY.md

This file was deleted.

73 changes: 43 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
#facebook-post-action
# facebook-post-action
GitHub Action for posting to a facebook page or group.

## 🎒 Prep Work
1. Get a facebook permanent access token (explained below) using a facebook account that owns the page where you want to post messages.
2. Find the ID of the page that you want to post messages in (explained below).
3. Find the atom feed URL that contains the posts that you wish to share.
2. Find the ID of the page or group that you want to post messages in (explained below).

## 🖥 Workflow example
```yaml
Expand All @@ -19,88 +18,102 @@ jobs:

steps:
- name: facebook-post-action
uses: ReenigneArcher/facebook-post-action@v1
uses: LizardByte/facebook-post-action@master
with:
page_id: ${{ secrets.FACEBOOK_PAGE_ID }}
access_token: ${{ secrets.FACEBOOK_ACCESS_TOKEN }}
fail_on_eror: True
message: |
${{ github.event.repository.name }} ${{ github.ref }} Released
${{ github.event.release.body }}
page_id: ${{ secrets.FACEBOOK_PAGE_ID }}
url: ${{ github.event.release.html_url }}
fail_on_eror: True
```
## 🤫 Environment Secrets
## 🤫 Inputs
- **PAGE_ID**: The page ID where you want to post
- **ACCESS_TOKEN**: The permanent facebook access token
- **FAIL_ON_ERROR**: Fail the workflow on error.
Group posts will fail if the facebook app is not installed to the group; however, the message will be posted,
setting this to False will allow the workflow to be successful.
- **MESSAGE**: The content to post
- **PAGE_ID**: The page ID where you want to post
- **URL**: The url to embed with the post (optional)
- **FAIL_ON_ERROR**: Fail the workflow on error.
Group posts will fail if the facebook app is not installed to the group; however the message will be posted,
setting this to False will allow the workflow run to be successful.
## 👥 How to get a Facebook permanent access token
Following the instructions laid out in Facebook's [extending page tokens documentation][2] I was able to get a page access token that does not expire.
Following the instructions laid out in Facebook's [extending page tokens documentation][2] I was able to get a page
access token that does not expire.
I suggest using the [Graph API Explorer][3] for all of these steps except where otherwise stated.
### 0. Create Facebook App ###
### 1. Create Facebook App
**If you already have an app**, skip to step 1.
**If you already have an app**, skip to the next step.
1. Go to [My Apps][4].
2. Click "+ Add a New App".
3. Set up a website app.
You don't need to change its permissions or anything. You just need an app that won't go away before you're done with your access token.
You don't need to change its permissions or anything. You just need an app that won't go away before you're done with
your access token.
### 1. Get User Short-Lived Access Token ###
### 2. Get User Short-Lived Access Token
1. Go to the [Graph API Explorer][3].
2. Select the application you want to get the access token for (in the "Facebook App" drop-down menu, not the "My Apps" menu).
3. Click "Get Token" > "Get User Access Token".
4. In the "Add a Permission" drop-down, search and check "pages_manage_posts", "pages_show_list", and "publish_to_groups".
5. Click "Generate Access Token".
6. Grant access from a Facebook account that has access to manage the target page. Note that if this user loses access the final, never-expiring access token will likely stop working.
2. Select the application you want to get the access token for (in the "Meta App" drop-down menu).
3. In the "Add a Permission" drop-down, search and check "pages_manage_posts", "pages_show_list",
and "publish_to_groups". Publishing to groups requires an approved app.
4. Click "Generate Access Token".
5. Grant access from a Facebook account that has access to manage the target page. Note that if this user loses access,
the final, never-expiring, access token will likely stop working.
The token that appears in the "Access Token" field is your short-lived access token.
### 2. Generate Long-Lived Access Token ###
### 3. Generate Long-Lived Access Token
Following [these instructions][5] from the Facebook docs, make a GET request to
> https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&client_id=**{app_id}**&client_secret=**{app_secret}**&fb_exchange_token=**{short_lived_token}**
```
https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&client_id=**{app_id}**&client_secret=**{app_secret}**&fb_exchange_token=**{short_lived_token}**
```

entering in your app's ID and secret and the short-lived token generated in the previous step.

You **cannot use the Graph API Explorer**. For some reason it gets stuck on this request. I think it's because the response isn't JSON, but a query string. Since it's a GET request, you can just go to the URL in your browser.
You **cannot use the Graph API Explorer**. For some reason it gets stuck on this request.
I think it's because the response isn't JSON, but a query string. Since it's a GET request,
you can just go to the URL in your browser.

The response should look like this:

```json
{"access_token":"**ABC123**","token_type":"bearer","expires_in":5183791}
```

"ABC123" will be your long-lived access token. You can put it into the [Access Token Debugger][7] to verify. Under "Expires" it should have something like "2 months".
"ABC123" will be your long-lived access token. You can put it into the [Access Token Debugger][7] to verify.
Under "Expires" it should have something like "2 months". If it says "Never", you can skip the rest of the steps.

### 3. Get User ID ###
### 4. Get User ID

Using the long-lived access token, make a GET request to

> https://graph.facebook.com/me?access_token=**{long_lived_access_token}**
```
https://graph.facebook.com/me?access_token=**{long_lived_access_token}**
```

The `id` field is your account ID. You'll need it for the next step.

### 4. Get Permanent Page Access Token ###
### 5. Get Permanent Page Access Token

Make a GET request to

> https://graph.facebook.com/**{account_id}**/accounts?access_token=**{long_lived_access_token}**
```
https://graph.facebook.com/**{account_id}**/accounts?access_token=**{long_lived_access_token}**
```

The JSON response should have a `data` field under which is an array of items the user has access to. Find the item for the page you want the permanent access token from. The `access_token` field should have your permanent access token. Copy it and test it in the [Access Token Debugger][7]. Under "Expires" it should say "Never".
The JSON response should have a `data` field under which is an array of items the user has access to.
Find the item for the page you want the permanent access token from. The `access_token` field should have your
permanent access token. Copy it and test it in the [Access Token Debugger][7]. Under "Expires" it should say "Never".

[2]:https://developers.facebook.com/docs/facebook-login/access-tokens#extendingpagetokens
[3]:https://developers.facebook.com/tools/explorer
Expand Down
28 changes: 9 additions & 19 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
---
name: facebook-post-action
author: LizardByte
description: GitHub Action for posting to a facebook page or group.
name: "Facebook Post Action"
description: "Post to a facebook page or group."
author: "LizardByte"

branding:
icon: at-sign
color: blue

inputs:
page_id:
Expand All @@ -21,19 +25,5 @@ inputs:
required: false

runs:
using: "composite"
steps:
- run: python -m pip install -r ${{ github.action_path }}/requirements.txt # Installing dependencies
shell: bash
- run: python ${{ github.action_path }}/facebook_post_action.py
shell: bash
env:
INPUT_PAGE_ID: ${{inputs.page_id}}
INPUT_ACCESS_TOKEN: ${{inputs.access_token}}
INPUT_MESSAGE: ${{inputs.message}}
INPUT_URL: ${{inputs.url}}
INPUT_FAIL_ON_ERROR: ${{inputs.fail_on_error}}

branding:
icon: at-sign
color: blue
using: "docker"
image: "Dockerfile"
Empty file added action/__init__.py
Empty file.
45 changes: 45 additions & 0 deletions action/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# standard imports
import os
import sys

# lib imports
from dotenv import load_dotenv
import requests

load_dotenv()

# inputs
ACCESS_TOKEN = os.environ['INPUT_ACCESS_TOKEN']
MESSAGE = os.environ['INPUT_MESSAGE']
PAGE_ID = os.environ['INPUT_PAGE_ID']
URL = os.getenv('INPUT_URL', None)
FAIL_ON_ERROR = os.getenv('INPUT_FAIL_ON_ERROR', 'true')

# constants
FACEBOOK_API_END = f'https://graph.facebook.com/{PAGE_ID}/feed'


def main():
facebook_api_data = {
'message': MESSAGE,
'access_token': ACCESS_TOKEN,
}
if URL:
facebook_api_data['link'] = URL

r = requests.post(url=FACEBOOK_API_END, json=facebook_api_data)

result = r.json()

if 'error' not in result:
print('Post successful')
else:
print('Post error:')
print(result)
if FAIL_ON_ERROR.lower() == 'true':
print('Failing the workflow')
sys.exit(1)


if __name__ == '__main__':
main() # pragma: no cover
38 changes: 0 additions & 38 deletions facebook_post_action.py

This file was deleted.

Loading

0 comments on commit 6516913

Please sign in to comment.