Publiez de python à vous-même ou à la chronologie sur votre page Facebook.
Malheureusement, Facebook n'a pas de mécanisme de webhook entrant, vous devez donc créer une application Facebook pour publier.
De plus, des jetons d'accès sont nécessaires pour faire fonctionner Facebook, mais il est difficile d'obtenir des jetons d'accès de CLI car Facebook nécessite une authentification OAuth (bien que ce ne soit pas impossible si vous analysez la réponse à l'aide d'un navigateur sans tête).
Donc, cette fois, je vais démarrer le serveur CGI avec python sur localhost et traiter le rappel OAuth avec CGI pour obtenir le jeton d'accès.
Je voulais pouvoir poster sur le groupe facebook, mais malheureusement j'ai abandonné cette fois car il semble que l'opérateur facebook doive approuver l'application facebook.
version | |
---|---|
OS | Ubuntu 15.04 (3.19.0-26-generic) |
Python | 2.7.10 |
pip | 7.1.2 |
requests | 2.8.1 |
jinja2 | 2.8 |
facebook-sdk | 0.4.0 |
facebook graph API | 2.5 |
https://github.com/nmatsui/post_facebook_using_python
Tout d'abord, créez une application Facebook.
1 Affichez «Ajouter une nouvelle application» depuis le portail des développeurs Facebook https://developers.facebook.com/ et sélectionnez «Site Web».
2 Entrez le nom de l'application Facebook que vous souhaitez créer (cette fois ** python_publisher **) et appuyez sur "Créer un nouvel ID d'application Facebook"
3 Sélectionnez une catégorie (cette fois ** Utility **) et appuyez sur "Create App ID"
4 Entrez l'URL pour le rappel d'authentification avec OAuth (cette fois ** http: // localhost: 8000 / cgi-bin / get_token **) et appuyez sur "Suivant".
5 Fin de la création de l'application facebook
6 Affichez à nouveau la Première page du portail des développeurs et sélectionnez l'application créée dans "Mes applications".
Si vous ne voyez pas l'application que vous avez créée, rechargez le portail des développeurs
7 Vérifier l'ID de l'application et le secret de l'application
Vous pouvez être invité à entrer un mot de passe lors de la vérification du secret de l'application
Créez un fichier de paramètres qui décrit les informations de l'application Facebook créée et les informations de la page Facebook à publier. Pour la commodité du programme CGI, le nom du fichier de paramètres est défini comme ** conf.json **.
conf.json
{
"app": {
"app_id": "ID d'application de l'application facebook",
"app_secret": "l'application facebook App Secret",
"redirect_uri": "URL de rappel définie dans l'application Facebook"
},
"page": {
"name": "Le nom de la page facebook à publier"
}
}
Maintenant que nous avons une application facebook, nous devons préparer un environnement python.
Créez requirements.txt au même emplacement que conf.json et installez les trois bibliothèques suivantes à l'aide de pip.
requirements.txt
requests
jinja2
facebook-sdk
Installer avec pip
$ pip install -r requirements.txt
Placez le programme CGI dans le répertoire où se trouve conf.json ** Créez le répertoire cgi-bin ** et le répertoire jinja2 template ** templates **
Créer un répertoire
$ mkdir cgi-bin
$ mkdir templates
Cette fois, nous allons créer les deux CGI suivants
Cette fois, spécifiez les trois plages d'autorités suivantes. Voir Référence des autorisations - Connexion à Facebook pour plus de détails sur les autorisations qui peuvent être spécifiées.
Par défaut, le jeton d'accès reçoit les privilèges ** public_profile ** (autorisation d'acquérir un profil public), de sorte que le jeton d'accès acquis cette fois est autorisé à fonctionner dans ces quatre plages de privilèges.
index Générez une URL d'authentification OAuth pour l'application Facebook et affichez le lien dans votre navigateur.
** cgi-bin / index ** lit conf.json et génère une URL d'authentification OAuth au format suivant.
https://www.facebook.com/dialog/oauth?redirect_uri= <URL de rappel définie pour l'application Facebook & client_id = <ID d'application de l'application Facebook> & scope = <Autorité d'accorder l'approbation>
cgi-bin/index
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
import urllib
from jinja2 import Environment, FileSystemLoader
CONF_FILE = 'conf.json'
BASE_URL = 'https://www.facebook.com/dialog/oauth'
SCOPE = 'manage_pages,publish_actions,publish_pages'
TPL_DIR = './templates'
TEMPLATE = 'index.tpl.html'
def create_url():
with open(CONF_FILE, 'r') as f:
conf = json.load(f)
redirect_uri = urllib.quote_plus(conf['app']['redirect_uri'])
url = BASE_URL + '?'
url += 'redirect_uri=' + redirect_uri + '&'
url += 'client_id=' + conf['app']['app_id'] + '&'
url += 'scope=' + SCOPE
return url
def main():
params = {}
try:
url = create_url()
params['isOK'] = True
params['url'] = url
except Exception as e:
params['isOK'] = False
params['error_type'] = type(e).__name__
params['error_title'] = str(e)
env = Environment(loader=FileSystemLoader(TPL_DIR, encoding='utf-8'))
tpl = env.get_template(TEMPLATE)
html = tpl.render(params)
print('Content-type: text/html')
print('\n')
print(html.encode('utf-8'))
main()
Puisque l'URL de rappel ne peut pas être passée en tant que paramètre d'URL telle quelle, elle est échappée avec ʻurllib.quote_plus () `.
** templates / index.tpl.html ** affiche l'URL générée sous forme de lien.
html+jinja:templates/index.tpl.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>index</title>
</head>
<body>
{% if isOK %}
<a href="{{ url }}">get token</a>
{% else %}
<b>J'ai eu l'erreur suivante</b><br/>
[{{ error_type }}] {{ error_title }}
{% endif %}
</body>
</html>
get_token Rappelé depuis la fonction d'authentification OAuth de Facebook et obtenir le code d'authentification. Obtenez le jeton d'accès suivant de l'API facebook à l'aide du code d'authentification et enregistrez-le en tant que fichier json.
** cgi-bin / get_token ** obtient le jeton d'accès à la page de la page Facebook spécifiée comme jeton d'accès utilisateur en utilisant le code d'autorisation rappelé. Le jeton d'accès acquis est enregistré dans token.json.
cgi-bin/get_token
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import cgi
import json
import re
import requests
from jinja2 import Environment, FileSystemLoader
CONF_FILE = 'conf.json'
TOKEN_FILE = 'token.json'
TOKEN_URL = 'https://graph.facebook.com/oauth/access_token'
ACCOUNT_URL = 'https://graph.facebook.com/me/accounts'
USER_ACCESS_TOKEN_PATTERN = r'access_token=([^&=]+)(&expires=\d+)?'
TPL_DIR = './templates'
TEMPLATE = 'get_token.tpl.html'
class TokenRetriever(object):
def __init__(self, code):
self.code = code
with open(CONF_FILE, 'r') as f:
self.conf = json.load(f)
def get_token(self):
user_access_token = self.__get_user_access_token()
page_access_token = self.__get_page_access_token(user_access_token)
token = {}
token['user_access'] = user_access_token
token['page_access'] = page_access_token
token_json = json.dumps({'token': token}, indent=2, sort_keys=True)
return token_json
def __get_user_access_token(self):
payload = {}
payload['client_id'] = self.conf['app']['app_id']
payload['client_secret'] = self.conf['app']['app_secret']
payload['redirect_uri'] = self.conf['app']['redirect_uri']
payload['code'] = self.code
response = requests.get(TOKEN_URL, params=payload)
m = re.match(USER_ACCESS_TOKEN_PATTERN, response.text)
if m:
return self.__exchange_token(m.group(1))
else:
raise LookupError('access_token does not exist')
def __get_page_access_token(self, user_access_token):
payload = {}
payload['access_token'] = user_access_token
response = requests.get(ACCOUNT_URL, params=payload)
pages = filter(lambda p: p['name'] == self.conf['page']['name'],
json.loads(response.text)['data'])
page_access_token = pages[0]['access_token']
return self.__exchange_token(page_access_token)
def __exchange_token(self, token):
payload = {}
payload['client_id'] = self.conf['app']['app_id']
payload['client_secret'] = self.conf['app']['app_secret']
payload['grant_type'] = 'fb_exchange_token'
payload['fb_exchange_token'] = token
response = requests.get(TOKEN_URL, params=payload)
m = re.match(USER_ACCESS_TOKEN_PATTERN, response.text)
if m:
return m.group(1)
else:
raise LookupError('access_token does not exist')
def main():
params = {}
try:
form = cgi.FieldStorage()
if not form.has_key('code'):
raise LookupError('QueryString "code" does not exist')
token_retriever = TokenRetriever(form['code'].value)
token_json = token_retriever.get_token()
with open(TOKEN_FILE, 'w') as f:
f.write(token_json)
params['isOK'] = True
params['token_file'] = TOKEN_FILE
params['token_json'] = token_json
except Exception as e:
params['isOK'] = False
params['error_type'] = type(e).__name__
params['error_title'] = str(e)
env = Environment(loader=FileSystemLoader(TPL_DIR, encoding='utf-8'))
tpl = env.get_template(TEMPLATE)
html = tpl.render(params)
print('Content-type: text/html; charset=utf-8')
print('\n')
print(html.encode('utf-8'))
main()
La bibliothèque requests
est utilisée pour utiliser l'API REST de facebook. Le jeton d'accès utilisateur facebook expire généralement 1 à 2 heures après son acquisition. Ce fut un problème à tester, j'ai donc utilisé l'API REST Access Token Extension pour échanger des jetons valides pendant 60 jours.
** templates / get_token.tpl.html ** affiche le jeton d'accès acquis.
html+jinja:templates/get_token.tpl.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>get_token</title>
</head>
<body>
{% if isOK %}
<b>User Access Token</b>Quand<b>Page Access Token</b>J'ai eu.</br>
Les jetons sont au format JSON suivant{{ token_file }}Je l'ai écrit.
<pre>{{ token_json }}</pre>
{% else %}
<b>L'erreur suivante s'est produite:</b><br/>
[{{ error_type }}] {{ error_title }}
{% endif %}
</body>
</html>
Maintenant, exécutons CGI et obtenons un jeton d'accès. Puisqu'il s'agit d'une vérification, httpd tel que nginx et apache ne sera pas utilisé, et python2.7 CGIHTTPServer
sera utilisé à la place.
Démarrez le serveur HTTP CGI avec la commande suivante à partir du répertoire contenant le répertoire conf.json, le répertoire cgi-bin et le répertoire templates.
Démarrer le serveur HTTP CGI
$ python -m CGIHTTPServer
Accédez à l'URL suivante à partir du navigateur du PC sur lequel CGIHTTPServer est démarré.
http://localhost:8000/cgi-bin/index
Cliquez sur get_token
pour authentifier l'application Facebook et vous demander d'approuver les autorisations.
1 Vérification de l'autorité donnée à l'utilisateur Vérifiez l'autorité d'approuver. Étant donné que cette application Facebook n'est pas approuvée, un avertissement s'affiche indiquant que certaines des autorisations telles que l'écriture dans le groupe ont été invalidées.
2 Vérifiez la plage d'affichage Spécifiez la plage de publications que l'application Facebook publie en votre nom.
3 Vérification des autorisations pour la page Facebook Vérifiez l'autorité de gestion et l'autorité de publication de la page Facebook. Il n'y a aucun avertissement concernant la publication sur la page Facebook, même pour les applications non approuvées.
CGI obtient le jeton d'accès, l'enregistre dans token.json
et l'affiche à l'écran.
token.json
{
"token": {
"page_access": "Jeton d'accès à la page obtenu",
"user_access": "Jeton d'accès utilisateur obtenu"
}
}
Maintenant que j'ai le jeton d'accès, je le posterai de python sur facebook. Vous pouvez utiliser directement l'API REST de Facebook, mais cette fois, nous utiliserons le SDK Facebook pour Python.
Obtenez-vous et le point de terminaison de la page Facebook en utilisant le SDK et le jeton d'accès et rédigez un message. Notez que la méthode d'écriture est différente entre votre chronologie et la chronologie de la page Facebook.
post.py
#!/usr/bin/env python
# -*- encode: utf-8 -*-
import sys
import json
import facebook
class Timeline:
def __init__(self, token_file):
with open(token_file, 'r') as f:
token = json.load(f)['token']
self.user_endpoint = facebook.GraphAPI(token['user_access'])
self.page_endpoint = facebook.GraphAPI(token['page_access'])
def post_me(self, msg):
self.user_endpoint.put_object('me', 'feed', message=msg)
print('posted to my timeline: %s' % msg)
def post_page(self, msg):
self.page_endpoint.put_wall_post(message=msg)
print('posted to page timeline: %s' % msg)
if __name__ == '__main__':
if len(sys.argv) != 4:
print('usage: %s token_file [me|page] message' % sys.argv[0])
exit(1)
try:
timeline = Timeline(sys.argv[1])
if sys.argv[2] == 'me':
timeline.post_me(sys.argv[3])
elif sys.argv[2] == 'page':
timeline.post_page(sys.argv[3])
else:
print '%s is invalid' % sys.argv[2]
except (IOError, facebook.GraphAPIError) as e:
print e
exit(9)
Essayez de publier sur votre chronologie.
Publiez sur votre chronologie
$ ./post.py token.json me "Poste de test. Ceci est un test d'un article à partir d'un script python."
posted to my timeline:Poste de test. Ceci est un test d'un article à partir d'un script python.
Je le posterai sur la chronologie de la page facebook créée pour cette expérience.
$ ./post.py token.json page "Poste de test. Ceci est un test d'un article à partir d'un script python."
posted to page timeline:Poste de test. Ceci est un test d'un article à partir d'un script python.
Je voulais juste publier de python sur facebook, mais c'était un très long chemin, mais j'ai pu publier en toute sécurité sur ma chronologie et la chronologie de la page facebook. Facebook préparera-t-il également un webhook entrant?
Recommended Posts