Post photo on Facebook page doesn't work - python

I can't post a photo on a facebook page with my facebook app (V 2.11). My app has the manage_pages e publish_pages permissions. I have a page token too. Post text works well. If I use a image url from my domain the post doesn't work if I use a image url from another domain (eg: tripadvisor) the post works. My domain has a SSL DigiCert SHA2 Secure Server CA.
This is my code:
def PostPhotoFB(photo, title, link, text , fb_access_token, fb_page_id, desc):
facebook_data = {'url': photo,
'access_token': fb_access_token,
'caption': text,
}
facebook_request = "https://graph.facebook.com/" + fb_page_id + "/photos"
response_facebook = requests.post(facebook_request, data=facebook_data)
if response_facebook.status_code == 200:
return json.loads(response_facebook.text)['id']
else:
return ""
with an image in my server I get 400 and
"(#324) Missing or invalid image
file","type":"OAuthException","code":324
I use Jpg or PNG image.
this is a exemple url "https://www.stbrun.com/static/img_locale/24/biciclette.jpg"
I don't understand. Can you help me please? Thanks a lot

Using the graph api, you can post like this:
import facebook
def main():
graph = facebook.GraphAPI(access_token='your_user_access_token',
version='2.8')
#if version 2.8 shows error use 2.6
attachment = {
'name': 'Link name'
'link': 'https://www.example.com/',
'caption': 'Check out this example',
'description': 'This is a longer description of the attachment',
'picture': 'https://www.example.com/thumbnail.jpg'
}
graph.put_wall_post(message='Check this out...',
attachment=attachment, profile_id='your_page_id')
if __name__ == "__main__":
main()
If you leave the profile_id blank, it will default to your profile. In the attachment dictionary, you can leave the extra fields that you don't need. First you need to install fackbook-sdk:
pip install facebook-sdk

Related

Python and mailchimp integration

So i have been stuck on this for a week or so and could really do this some advice.
I have a basic website which allows people to sign up to an automated newsletter that i want to send out. After adding their email on the site their address is automatically added to an audience.
I have a small python script running that then web scrapes a site and then if that returns a certain criteria it will send an automated email out via mailchimp to all the contacts in the mailchimp audience.
What i am having issue with is actually creating and sending out the email via mail chimp.
I have been through https://mailchimp.com/developer/api/marketing/campaigns/add-campaign/ a few times and can't seem to get it working. I am able to create a new campaign succesfully as well as the audience and subject line. I am unable to workout how to actually send the email with the content i want inside it however. It just saves itself as a draft and thats it.
When i try to preview the email there is nothing in it and when i click edit next to the campaign everything is ticked except for the 'content.
I have excluded th web scraping part of my program but below is the test i am running to create and sent out via the mailchimp api
import mailchimp_marketing as MailchimpMarketing
from mailchimp_marketing.api_client import ApiClientError
from mailchimp3 import MailChimp
data = {
"recipients" :
{
"list_id": 'XXXXXXXX'
},
"settings":
{
"subject_line": 'Subject of email',
"from_name": 'from_name',
"reply_to": 'reply_email',
},
"type": "regular"
}
try:
client = MailchimpMarketing.Client()
#print(client)
client.set_config({
"api_key": "XXXXXXXXXXXXXXXX",
"server": "XXXXXXX"
})
#client = MailChimp(mc_api='XXXXXXXXXXXX', mc_user="XXXXXXXXX")
client.campaigns.create(data)
response = client.campaigns.get('campaign_id')
#client.campaigns.send()
print(response)
except ApiClientError as error:
print("Error: {}".format(error.text))
This succesfully creates the campaign except without the content that i want to add and simply saves the email as a draft without send. So i guess my question is how to i edit the email content and then how do i actually initiate the send.
Thanks for any help
I also didn't find a minimal example on the web. Plus the examples in the mailchimp api documentation are severely lacking for python (only curl seems correct). Here's a minimal example:
from mailchimp_marketing import Client, api_client
# find this out at https://mailchimp.com/en/help/about-api-keys/
API_KEY = '…'
# log into your Mailchimp account and look at the URL in your browser.
# You’ll see something like https://us19.admin.mailchimp.com/
# the us19 part is the server prefix.
SERVER_PREFIX = 'us19'
try:
client = Client()
client.set_config({
"api_key": API_KEY,
"server": SERVER_PREFIX
})
# find out list id: https://mailchimp.com/en/help/find-audience-id/
campaign_data = dict(
type='regular',
recipients=dict(list_id='…'),
settings=dict(
subject_line='lorem ipsum',
from_name='John Doe',
reply_to='john#doe.com',
)
)
campaign = client.campaigns.create(campaign_data)
print(campaign)
campaign_id = campaign['id']
content_data = dict(
plain_text='lorem ipsum',
html='<p><strong>lorem</strong><br />ipsum</p>'
)
response = client.campaigns.set_content(campaign_id, content_data)
print(response)
response = client.campaigns.send(campaign_id)
print(response)
except api_client.ApiClientError as e:
print("Error: {}".format(error.text))

Google slides API replaceAllShapesWithImage returns error for Google Drive file (2020)

I'm trying to replace a Google slides shape filled with a placeholder text with an image via API. The image in question is allocated in a team Drive unit. I've read several solutions like this and this, and I have tried to set the permissions in the image as "reader" and "anyone with link", both via API and manually, and nothing works. I get a "Access to the provided image was forbidden" error everytime. However, I can download the image wihout problems via API and without giving extra permissions.
I'm using v3 of the Drive API and v1 for Slides API.
Below is the code I'm using:
def replace_shape_with_image(slides_service, url, presentation_id, contains_text):
requests = [
{
"replaceAllShapesWithImage": {
"imageUrl": url,
"replaceMethod": "CENTER_INSIDE",
"containsText": {
"text": "{{" + contains_text + "}}",
}
}
}]
body = {
'requests': requests
}
response = slides_service.presentations().batchUpdate(presentationId=presentation_id,body=body).execute()
return response
def create_public_permissions(drive_service, file_id):
request = drive_service.permissions().create(
fileId=file_id,
supportsAllDrives=True,
fields='id, type, role',
body={
'role':'reader',
'type':'anyone'
}
)
response = request.execute()
return response
file_id = '123'
presentation_id = '789'
# drive_service = etc
# slides_service = etc
create_public_permissions(drive_service, file_id) # Here I put the actual service object and file ID. Manually verified and it works
url = f'https://drive.google.com/uc?export=download&id={file_id}'
# also tried url = https://drive.google.com/uc?id={file_id}&export=download
replace_shape_with_image(slides_service, url, presentation_id, 'test') # shape in slide has "test" as text
The following error is returned:
googleapiclient.errors.HttpError: <HttpError 400 when requesting
https://slides.googleapis.com/v1/presentations/1cDSov4IKFHSyzaXjFYNYPB7EYlMMtInamYv0AwXiazw:batchUpdate?alt=json
returned "Invalid requests[0].replaceAllShapesWithImage: Access to the
provided image was forbidden.">
For downloading the file I use this code, which works without problem:
import io
from googleapiclient.http import MediaIoBaseDownload
tmp_file_path = r'C:\Users\me\tmp\testimage.png'
fh = io.FileIO(tmp_file_path, 'wb')
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
I know there have been changes in the Drive API recently (over the last year), and most questions about this are old and the solutions are deprecated, and more recent ones doesn't seem to work for me. Any ideas in how to solve this issue, if possible?
Thanks in advance!
It's known issue: https://issuetracker.google.com/issues/150933939
As it was happening with one of our projects, we figured out that error is thrown not for all Google Drive images, but for random ones when using replaceAllShapesWithImage Slides API request.
Only possible workaround is to wrap your requests code in try / catch and use some placeholder image in case replaceAllShapesWithImage requests are keep failing.
Example code (in Google Apps Script):
var slideImageNotFoundPlaceholder = 'https://example.com/../placeholder.png';
try {
Slides.Presentations.batchUpdate({'requests': slidesReqs}, presentationFileId);
}
catch(err)
{
// loop all requests
for (var i = 0; i < slidesReqs.length; i++)
{
// update replaceAllShapesWithImage requests
if (slidesReqs[i].replaceAllShapesWithImage)
{
// replace with image not found placeholder
slidesReqs[i].replaceAllShapesWithImage.imageUrl = slideImageNotFoundPlaceholder;
}
}
Slides.Presentations.batchUpdate({'requests': slidesReqs}, presentationFileId);
}
It is not perfect solution, but all other requests are getting executed, so you won't have your presentations being totally failed.
P.S. hopefully Google will fix Google Drive images being used in Slides API, so "star" the issue linked in the beginning of the answer to make it happen faster.

Python facebook-sdk post to page

I'm trying to post to a Facebook Page I manage with the Python facebook-sdk but I can't figure out how to do it. I can post to my Facebook Wall like so:
graph.put_object("me", "feed", message='My message goes here')
I can get the pages I manage and the access tokens like so:
fbpages = graph.request('me/accounts')
But I can't find any resources to indicate how to actually then use the access token to post to the page. I imagine it would be something like this:
graph.put_object("me", "page id", "access token", message='My message goes here')
How would I actually go about doing this with the Python facebook-sdk?
I'm using 'pythonforfacebook/facebook-sdk'.
Thank's to WizKid for pointing me in the right direction. For anyone else with this problem it is solved like so:
graph = facebook.GraphAPI(page_access_token)
graph.put_object("page id", "feed", message='My message goes here')
With the new API(v2.8), you can use the following code:
import facebook
def main():
graph = facebook.GraphAPI(access_token='your_user_access_token', version='2.8')
#if version 2.8 show error use 2.6
attachment = {
'name': 'Link name'
'link': 'https://www.example.com/',
'caption': 'Check out this example',
'description': 'This is a longer description of the attachment',
'picture': 'https://www.example.com/thumbnail.jpg'
}
graph.put_wall_post(message='Check this out...', attachment=attachment, profile_id='your_page_id')
if __name__ == "__main__":
main()
You can change the attachment as your need. I think this will be helpful if someone needs to use the new API. You need to install facebook sdk first.
pip install facebook-sdk

Sometimes get 500 Error w/ Ajax to Google Books API on production

While working on a small profect(Japanese) using Python, Flask, Heroku, Jquery, and Google Books API, I got 500 Internal Server Error while executing "検索", which means "search".
When you click on "検索" w/ some input on the box next to it, it sends request to the Google Books API and get books data that match to that argument via Ajax w/ Jquery as follows.
#app.route("/_search_books")
def search_books():
title = request.args.get('title')
if title:
title = title.encode('utf-8')
url = 'https://www.googleapis.com/books/v1/volumes?q=' + title
h = urlopen(url)
data = json.load(h)
books = []
for i in range(len(data['items'])):
try:
title = data['items'][i]['volumeInfo']['title']
except:
title = None
try:
author = data['items'][i]['volumeInfo']['authors'][0]
except:
author = None
try:
publisher = data['items'][i]['volumeInfo']['publisher']
except:
publisher = None
try:
year = data['items'][i]['volumeInfo']['publishedDate']
except:
year = None
try:
thumbnail = data['items'][i]['volumeInfo']['imageLinks']['thumbnail']
except:
thumbnail = None
try:
page = data['items'][i]['volumeInfo']['pageCount']
except:
page = None
books.append({'title': title, 'author': author, 'publisher': publisher, 'year': year, 'thumbnail': thumbnail, 'page': page})
return jsonify(result=books)
It works properly on development, so I guess it's Google Books API's permission related stuffs or SSL related stuffs.
The weird thing is that it doesn't always return 500, and it sometimes returns expected results. It seems it's depend on the time I execute, like 200 in the morning and 500 in the afternoon.
Thanks in advance :)
I'm having the same problem. Mine is not different between development and production; they both just occasionally return a 500. The message is "Backend error." I don't believe there's anything you can do to resolve this; it seems like a problem on Google's end. I can usually repeat the same query again a few seconds later and it works fine.
Hey I actually had the same issue, changed request amount lower maxResults=15 to the search string it fixed the issue

How to get page access token

I create app in facebook and page in my profile. In "Select how your app integrates with Facebook" section I don't select any option because I want only post text to facebook page (maybe this is problem?).
I have this code:
FACEBOOK_APP_ID = 'myappid'
FACEBOOK_APP_SECRET = 'myappsecret'
FACEBOOK_PROFILE_ID = 'myprofileid'
oauth_args = dict(client_id = FACEBOOK_APP_ID,
client_secret = FACEBOOK_APP_SECRET,
scope = 'publish_stream',
grant_type = 'client_credentials'
)
oauth_response = urllib.urlopen('https://graph.facebook.com/oauth/access_token?' + urllib.urlencode(oauth_args)).read()
oauth_response looks good
but when I run:
resp = urllib.urlopen('https://graph.facebook.com/me/accounts?'+oauth_response).read()
I get error:
{"error":{"message":"An active access token must be used to query information about the current user.","type":"OAuthException","code":2500}}
What am I doing wrong? I want to post on page wall some text when, for example, I click button on my website (Django).
UPDATE:
Ok, I get the pages data in json. I parsing it and I get page_access_token, but when I call this:
attach = {
"name": 'Hello world',
"link": 'http://linktosite',
"caption": 'test post',
"description": 'some test'
}
facebook_graph = facebook.GraphAPI(page_access_token)
try:
response = facebook_graph.put_wall_post('', attachment=attach)
except facebook.GraphAPIError as e:
print e
I get error: "The target user has not authorized this action"
This question is basically asking about the same problem, and the answer seems to be what you're looking for: (OAuthException - #2500) An active access token must be used to query information about the current user
If the page_access_token is correct, I guess you (the page admin) have not yet granted permission for your facebook application to post message to facebook page.
Check facebook login function in client side, whether you ask enough permission, the scope option should be 'mange_pages publish_stream photo_upload...' depends on your requirement, rather than only 'mange_pages'

Categories

Resources