display.save & Facebook Connect - Can we post screen captures to FB?

Hi Everybody - this is my first time posting a question, but I’ve been trolling the forums for the last few weeks as I teach myself Corona & Lua - and so far it’s been pretty successful, so thanks for your help! Anyways…

I am working on an app where the user can interactively compose an image, and I’d like the user to be able to post that image to their Facebook Wall. Facebook Connect is working great for me, and I’m able to post custom messages and photos that have a URL from within the app - but I cannot seem to post the JPG that is generated by the “display.save” function.

Does anybody know of a way to do this? Perhaps there is a way to format the “picture” parameter of facebook.request so that it finds the saved JPG? If push comes to shove, I’ll simply upload the image via FTP to a remote server and send that URL to Facebook, but that seems needlessly complex, and requires me to host images on my own server (yuck). Any help would be much appreciated.

Thanks! [import]uid: 27636 topic_id: 7240 reply_id: 307240[/import]

theoretically yes. I’ve managed to attach a MIME formatted image to an email and send via SMTP. http://developer.anscamobile.com/forum/2011/01/31/uploading-binary-file-http#comment-19806

I’m assuming that therefore it is also possible to encode an image and post to the Facebook Graph API. I don’t have a device at the moment so i can’t test this but here are some useful links

http://stackoverflow.com/questions/2964410/how-can-i-upload-photos-to-album-using-facebook-graph-api

http://daipratt.co.uk/facebook-api-upload-photo/

http://www.facebook.com/topic.php?uid=314110374728&topic=15289

http://stackoverflow.com/questions/4999024/facebook-graph-api-upload-photo-using-javascript

there seems to be some discrepancy as to whether the correct post field is “image” or “source” though. I’ve also seen the actual filename used as the field name:
http://forum.developers.facebook.net/viewtopic.php?pid=232498

Note the @ before the filename I believe is used by PHP to tell it to encode the data. You shouldn’t need this…

sorry I can’t be of more help. Trial and error is the way to go for now then :slight_smile:

j

[import]uid: 6645 topic_id: 7240 reply_id: 25603[/import]

Hi J,

Thanks for the assist. I still haven’t worked out the right syntax to upload directly to a user’s Facebook photos, but I’ll keep at it and share if I work it out. Posting photos using the Graph API and PHP seems especially simple so I’m sure it can be done in Corona. It doesn’t help that I can’t test code changes in the simulator - that’s really slowed things down.

For the time being, I’m going to use my FTP workaround, with the silver lining that I’ll have a centralized gallery of user-submitted images. Perhaps I’ll even build in a gallery viewer so users can view and rate each other’s submissions. However, even that has hit a stumbling block, and I’m hoping you might see what I’m missing.

I’m creating a unique file name for each uploaded JPG file, a combination of the user’s device ID and the system.getTimer value when the user taps the upload button. I set a local variable for this named “imagename.” The upload goes fine, but when it comes time to post the image URL to Facebook as a JSON string, I can’t seem to insert the variable into my code properly. The facebook.request “picture =” parameter for the image URL only seems to work when I type in a complete URL inside of quotes. My attempts at plugging in the imagename as a variable keep failing. I’ve tried a few variations variations on this with no luck:

facebook.request( “me/feed”, “POST”, {picture = (“http://www.jasonschroeder.com/pins/” … imagename … “.jpg”), message = “Check this out!”} )

When I substitute a complete URL in quotes after “picture =” it works fine, but that doesn’t help me dynamically create links to freshly uploaded images. Any ideas?

Thanks,
Jason

(*typos brought to you by my iPad’s on-screen keyboard.) [import]uid: 27636 topic_id: 7240 reply_id: 25830[/import]

that suggests a couple of problems to me… although I can’t tell without seeing your code

  1. are you checking your ftp file has finished uploading before trying to access it?

  2. have you tried checking what you get for [lua]print(“http://www.jasonschroeder.com/pins/” … imagename … “.jpg”)[/lua] and then checking if that file is actually on the server?

also i wouldn’t put the () after [lua]picture=[/lua] around the image name

as for the actual facebook photo graph api…

here’s the current documentation:


Requires the publish_stream permission.

To publish a photo, issue a POST request with the photo file attachment as multipart/form-data.

You can publish an individual photo to a user profile with a POST to http://graph.facebook.com/PROFILE_ID/photos We automatically create an album for your application if it does not already exist. All photos from your application will be published to the same automatically created album.

You can publish a photo to a specific, existing photo album with a POST to http://graph.facebook.com/ALBUM_ID/photos.

curl -F ‘access_token=…’ <br> -F ‘source=@file.png’ <br> -F ‘message=Caption for the photo’ <br> https://graph.facebook.com/me/photos

so i would suggest that you use “source” as the field name, and then multipart encode the image with the code from here
http://w3.impa.br/~diego/software/luasocket/smtp.html

[import]uid: 6645 topic_id: 7240 reply_id: 25835[/import]

Still can’t seem to get photo posting to work, even when I use a concrete URL as the “source” - I am beginning to wonder if this is a bug in Corona’s Facebook API.

Regardless, I am more interested at the moment in figuring out how to transplant a variable into the “picture” parameter in the code below. Everything I’ve tried does not work. The problem seems to be that the facebook.request won’t work unless the entire picture parameter falls within quotation marks, but if I place the variable within the quotation marks, it doesn’t register as a variable, but rather as part of the string. Also, I tried removing the ( ) as you suggested, with no luck.

If I skip the variable issue and define a specific URL for my FTP upload, and then point the “picture” parameter to that URL, things are working just fine - so the file definitely finishes uploading before the URL posts to FB. And my variable naming scheme is also working: I can upload using the variable with expected results (but I can’t direct FB to the variable-named URL).

Below is the piece of my code related to this issue. Please take a look if you can and let me know if you have any thoughts. Apologies for any messy or inefficient code (I’m still pretty new at this). Thanks again for your help on this issue.

(FYI, I substituted a string of X’s for my actual Facebook App ID - it seemed strange to post that on a public forum. And my “button” is just a plain rectangle for the moment - I want to get it’s functionality working before I “nice it up.”)

Thanks,
Jason

[code]
– listener for “fbconnect” events
local function listener( event )
if ( “session” == event.type ) then
if ( “login” == event.phase ) then

facebook.request( “me/feed”, “POST”, {
picture = (“http://www.jasonschroeder.com/pins/” … imagename),
message = “Check out this composition I made using ‘Pins!’”
} )
end
elseif ( “request” == event.type ) then
– event.response is a JSON object from the FB server
local response = event.response
print( response )
end

imagename:removeSelf()
imagename=nil
end

local function fbupload()
– first argument is the app id that you get from Facebook
facebook.login( “XXXXXX”, listener, {“publish_stream”} )
end
local function ftpupload()
local imagename = (system.getInfo( “deviceID” ) … system.getTimer()) … “.jpg”
connection:upload{
localFile = system.pathForFile(“screencapture.jpg”, system.TemporaryDirectory),
remoteFile = imagename
}
fbupload()
end
local function screengrab ()
display.save( localGroup, “screencapture.jpg”, system.TemporaryDirectory)
ftpupload()
end

local fbbutton = display.newRect(display.contentWidth*.2,display.contentHeight*.9,60,60)

fbbutton:addEventListener(“tap”, screengrab)
[/code] [import]uid: 27636 topic_id: 7240 reply_id: 25865[/import]

did you try using print on your image url like i suggested?

you’re going to find that it’s

http://www.jasonschroeder.com/pins/nil

using your code above because your imagename variable is local to the ftpupload function

also you’re not testing to see if the ftp upload has finished before trying to post it. [import]uid: 6645 topic_id: 7240 reply_id: 25906[/import]

jmp909, you are a genius! (Or I’m an idiot…maybe a little bit of both.)

Changing imagename from a local variable to a global variable was the missing ingredient. The app now generates the JPG, uploads it to my server, and subsequently posts it to the user’s Facebook feed as a linked image (I haven’t coded a step for it to check for the availability of the image online before posting to FB, but testing on my device worked fine). I also created a second global variable (imageurl) that adds the prefix “http://www.jasonschroeder.com/pins/” to imagename. I’ve pasted my updated code below.

This solves my problem quite nicely. Thanks again!

Semi-related question, and showcases what a novice I am, but: I’m handling multi-part functions like this one by creating a sequence of separate functions (“screengrab”, then “ftpupload”, then “fbupload”, then “listener”, in the code below) - is this sloppy coding? Is there a way to create a multi-step process that is contained within a single function? And even if there is, is it inherently better to do so? Sorry to make you my newbie sounding-board, but I’m learning as I go here, and I don’t want to develop bad habits if I can help it.

Again - THANKS for your kind assistance.

[code]
– listener for “fbconnect” events
local function listener( event )
if ( “session” == event.type ) then
if ( “login” == event.phase ) then

facebook.request( “me/feed”, “POST”, {
picture = imageurl,
message = “Check out this composition I made using ‘Pins!’”
} )
end
elseif ( “request” == event.type ) then
– event.response is a JSON object from the FB server
local response = event.response
print( response )
end
end

local function fbupload()
– first argument is the app id that you get from Facebook
facebook.login( “XXXXXXXX”, listener, {“publish_stream”} )
end
local function ftpupload()
imagename = (system.getInfo( “deviceID” ) … system.getTimer()) … “.jpg”
imageurl = (“http://www.jasonschroeder.com/pins/” … imagename)
connection:upload{
localFile = system.pathForFile(“screencapture.jpg”, system.TemporaryDirectory),
remoteFile = imagename
}
fbupload()
end
local function screengrab ()
display.save( localGroup, “screencapture.jpg”, system.TemporaryDirectory)
ftpupload()
end

local fbbutton = display.newRect(display.contentWidth*.2,display.contentHeight*.9,60,60)

fbbutton:addEventListener(“tap”, screengrab)
[/code] [import]uid: 27636 topic_id: 7240 reply_id: 25940[/import]

i don’t see a problem with calling one function from another, but I imagine it is just luck that your image is on the server by the time you have logged into facebook, and at some point this is going to fail. asynchronous events should use some kind of “operation complete” listener to make sure it’s ok to proceed. [import]uid: 6645 topic_id: 7240 reply_id: 26041[/import]

add your +1 here please:
http://developer.anscamobile.com/forum/2011/03/23/binary-mime-attachment-facebookrequest [import]uid: 6645 topic_id: 7240 reply_id: 29649[/import]

Facebook Photo uploading functionality has been added as of Daily Build 2011.707.

Here’s a tutorial on how to do it:
http://blog.anscamobile.com/2011/12/uploading-photos-to-facebook-in-corona/

NOTE: The tutorial includes important information regarding build.settings for any iOS app using the Facebook API in build 2011.707 and later, regardless if you intend to upload photos or not. [import]uid: 52430 topic_id: 7240 reply_id: 74247[/import]

This still doesn’t work according to my tests. Uploading from the system.ResourceDirectory is fine, but trying to use screen capture or display.save and then writing to DocumentsDirectory or Temporary Directory. When you then access and upload these to facebook, I just see a black image 640x960.

My example code is here: http://developer.anscamobile.com/forum/2012/03/26/facebook-photo-upload-blank-image#comment-109489 [import]uid: 140429 topic_id: 7240 reply_id: 109501[/import]