Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Comfubar/d7b36b6dcfca00fb602c74441a5c00a1 to your computer and use it in GitHub Desktop.
Save Comfubar/d7b36b6dcfca00fb602c74441a5c00a1 to your computer and use it in GitHub Desktop.
Tautulli notification script for Facebook Group
#!/usr/bin/env python
###############################################################################
## Facebook Group Posting Script ##
###############################################################################
## This script will post a status to a Facebook group based on args ##
## All credit goes to u/djzang for giving me the idea, Pablo on ##
## stackoverflow for writing the original code and KennyX for tying together ##
## for me. And of course, thanks to SwifthPanda16 & Arcanemagus for all the ##
## tremendous support. ##
###############################################################################
## Change Log: ##
## 08/04/2018 KU - Created Job ##
## 08/04/2018 PO - Modified Args ##
## 08/09/2018 PO - Removed pyquery dependency ##
## 08/10/2018 PO - Added persistent login session ##
## 08/12/2018 PO - Bulletproof script output for ppl that don't read ##
###############################################################################
## Example fbsettings.ini file ##
"""
[Script]
debug: False
[Facebook]
username: facebook@login.use
password: fb_passwd
group-id: 123456789101112
session-time: 86400
"""
###############################################################################
import re
import requests
import json
from configparser import ConfigParser, NoOptionError, NoSectionError
import pickle
import datetime
import os
from urlparse import urlparse
from argparse import ArgumentParser
###############################################################################
## Parameters ##
###############################################################################
## input location
credential_path = r'/home/plex/scripts'
credential_file = 'fbsettings.ini'
cookie_file = 'fbcookies.dat'
###############################################################################
## Import Credentials ##
###############################################################################
## read configuration settings
config = ConfigParser()
try:
with open('%s/%s' % (credential_path,credential_file)) as f:
config.readfp(f)
## parse settings
try:
fb_username = config.get('Facebook', 'username')
except (NoSectionError, NoOptionError):
print('ERROR: Config file not setup - missing username')
sys.exit(1)
try:
fb_password = config.get('Facebook', 'password')
except (NoSectionError, NoOptionError):
print('ERROR: Config file not setup - missing password')
sys.exit(1)
try:
fb_group_id = config.get('Facebook', 'group-id')
try:
i = int(fb_group_id)
except ValueError:
print('ERROR: Please use the numeric Facebook Group ID')
sys.exit(1)
except (NoSectionError, NoOptionError):
print('ERROR: Config file not setup - missing group-id')
sys.exit(1)
try:
maxSessionTime = int(config.get('Facebook', 'session-time'))
except (NoSectionError, NoOptionError):
maxSessionTime = 86400
try:
debug = config.getboolean('Script', 'debug')
except (NoSectionError, NoOptionError):
debug = False
except IOError:
print('ERROR: No configuration file found')
sys.exit(1)
###############################################################################
## Parse Arguments ##
###############################################################################
## create a parser
parser = ArgumentParser()
## add arguments
parser.add_argument("-s"
,"--subject"
,dest = "post_subject"
,help = "Post Subject (first Line of text)"
,type = str
,required=True
)
parser.add_argument("-c"
,"--content"
,dest = "post_content"
,help = "Post Content (second line of text)"
,type = str
,default = ''
)
parser.add_argument("-u"
,"--url"
,dest = "post_url"
,help = "Link to Include in Post"
,type = str
,default = ''
)
## parge arguments into dictionary
args = vars(parser.parse_args())
###############################################################################
## Define Functions ##
###############################################################################
## Master function to log in and post
def main(username,password,group_id):
## create a web session
session = requests.session()
## execute login function
sess,uid,dtsg = login(session, username, password)
## execute posting function
postToFacebook(session = sess
,dtsg = dtsg
,pageID = group_id
,uID = uid
,message = args['post_subject'] + '\n' + args['post_content']
,link = args['post_url']
)
## Facebook Login
def login(session,username,password):
# If the last cache access was too old perform a proper login.
wasReadFromCache = False
fbcookies = '%s/%s' % (credential_path,cookie_file)
if os.path.exists(fbcookies):
t = os.path.getmtime(fbcookies)
time = datetime.datetime.fromtimestamp(t)
lastModification = (datetime.datetime.now() - time).seconds
if lastModification < maxSessionTime:
with open(fbcookies, "rb") as f:
session = pickle.load(f)
response = session.get('https://www.facebook.com')
wasReadFromCache = True
if debug:
print('DEBUG: loaded session from cache (last access %ds ago)' % lastModification)
## Login if no recetn session data
if not wasReadFromCache:
# Navigate to the Facebook homepage
response = session.get('https://www.facebook.com')
# Find LSD
m = re.search('name=\"lsd\"\ value=\"([A-Z,a-z,0-9]+)\"', response.text)
lsd = m.group(1)
if debug:
print('DEBUG: Unique Form Input = %s' % lsd)
# Perform the login request
response = session.post('https://www.facebook.com/login.php?login_attempt=1'
,data={'lsd' : lsd
,'email' : fb_username
,'pass' : fb_password
,'default_persistent' : '0'
,'timezone' : '-60'
,'lgndim' : ''
,'lgnrnd' : ''
,'lgnjs' : ''
,'locale' : 'en_US'
,'qsstamp' : ''
}
)
## verify login by looking for faccebook's login cookie
try:
## get user id from the facebook login cookie
uid = session.cookies['c_user']
if debug:
print('DEBUG: UID = %s' % uid)
dtsg = re.search(r'(type="hidden" name="fb_dtsg" value="([0-9a-zA-Z-_:]+)")', response.text).group(1)
## obtain the "dtsg" needed to interact with the facebook session
dtsg = dtsg[dtsg.find("value")+6:]
dtsg = dtsg[1:-1]
if debug:
print('DEBUG: DTSG = %s' % dtsg)
except KeyError:
raise Exception('ERROR: Login Failed!')
if debug:
print('DEBUG: Facebook ' + str(response))
## Store Facebook Login Cookies
with open(fbcookies, "wb") as f:
pickle.dump(session, f, protocol=2)
if debug:
print('DEBUG: updated session cache-file %s' % fbcookies)
return session, uid, dtsg
## post to facebook
def postToFacebook(session = ''
,dtsg = ''
,pageID = ''
,uID = ''
,message = ''
,link = ''
):
## create a library of posting information
data = {"__user" : uID
,"fb_dtsg" : dtsg
,"message" : message
,"target" : pageID
}
if link != '':
data['linkUrl'] = link
## post to facebook
response = session.post('https://m.facebook.com/a/group/post/add/?gid='+pageID+'&refid=18'
,data = data
,headers = {'Content-Type':'application/x-www-form-urlencoded'}
)
## return facebook post response
if debug:
print('DEBUG: Facebook ' + str(response))
try:
main(username = fb_username
,password = fb_password
,group_id = fb_group_id
)
except Exception as exception:
print('ERROR: ' + str(exception))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment