Socialite - social networking made easy!

Monkey Programming Forums/User Modules/Socialite - social networking made easy!

sygem(Posted 2014) [#1]
My first post - yay!

I would like to introduce my first MonkeyX module - Socialite.

Supporting Android and iOS (maybe Windows Phone 8 in the future), the goal of this module is to provide easy access to social networks.

Socialite currently supports the following networks:

- Twitter (text only)
- Facebook (posting only for now)
- Email (a social network? yeah, why not)

And it's on GitHub too: https://github.com/sygem/socialite

Please note: this hasn't been used in an app yet - I am just writing a load of modules before starting on my next game. It is still WIP, and could change at any time. Especially the Facebook part, which is nowhere near complete and has some inconsistencies between Android and iOS. I will be uploading some samples soon, and there is some limited documentation in the README files on GitHub.

Next up: ModPlug modules for Android & iOS :)


erebel55(Posted 2014) [#2]
This looks great sygem!

Can't wait for more facebook/twitter functionality to be added. Am very glad that you are choosing to support both ios and android :D

Also, looking forward to future modules from you.


erebel55(Posted 2014) [#3]
Can this module bring the user to a specific facebook/twitter page within the appropriate facebook/twitter app? If not, this would be a great addition to the module in order to support the in game buttons that will bring the user to the appropriate facebook/twitter page so they can like/follow.

I am also looking forward to your samples :)


erebel55(Posted 2014) [#4]
Hoping to see some more commits soon :) And hopefully some samples.


sygem(Posted 2014) [#5]
Sorry for the silence, I've been on holiday for a week :) I'll try to get the samples uploaded this week.

Progress will be slow, and I might even drop Android support - Google decided to terminate my account last week, so I'm going to concentrate on iOS development.


erebel55(Posted 2014) [#6]
Google strikes again :/ I really hope you continue android support.


erebel55(Posted 2014) [#7]
Any chance on those samples soon? :)


sygem(Posted 2014) [#8]
A quick example of how to post to Twitter...
format_codebox('
Import socialite
Import mojo.app

#TWITTER = true
#TWITTER_CONSUMER_KEY="<PUT YOUR KEY HERE>"
#TWITTER_CONSUMER_SECRET="<PUT YOUR SECRET HERE>"

Function Main:Int()
New TwitterTest()
End

Class TwitterTest Extends App

Method OnCreate()
SetUpdateRate(0)
Local t:TwitterSharer = New TwitterSharer()
t.SetPostListener(New TwitterPostListener())
#if TARGET="android"
t.ShareText("This is an android test")
#else if TARGET="ios"
t.ShareText("This is an ios test")
#endif

End

End

Class TwitterPostListener Extends SocialPostListener
Method OnPostComplete:Void()
Print("Message Tweeted Successfully");
End

Method OnPostFailure:Void(errorCode:Int, message:String)
Print("Message Not Tweeted: " + errorCode + " " + message)
End
End
')


erebel55(Posted 2014) [#9]
Thanks sygem :)


erebel55(Posted 2014) [#10]
I'm getting the following when I try and compile your example for android
format_code('
Type 'SocialListener' not found
')

on line 40 of twitterSharer.monkey

And I don't see this class defined anywhere within sociallistener.monkey or the social natives.


sygem(Posted 2014) [#11]
Sorry about that - I have pushed an update to GitHub, so it should compile now.


erebel55(Posted 2014) [#12]
Cheers for the quick reply :)

Now, I am getting
format_code('
Unable to find overload for SetPostListener(TwitterPostListener)
')

on line 17 of your example.

Edit:
Ahh I fixed it in your example
format_codebox('
Import socialite
Import mojo.app

#TWITTER = true
#TWITTER_CONSUMER_KEY=""
#TWITTER_CONSUMER_SECRET=""

Function Main:Int()
New TwitterTest()
End

Class TwitterTest Extends App

Method OnCreate()
SetUpdateRate(0)
Local t:TwitterSharer = New TwitterSharer()
t.SetPostListener(New TwitterPostListener())
#if TARGET="android"
t.ShareText("This is an android test")
#else if TARGET="ios"
t.ShareText("This is an ios test")
#endif

End

End

Class TwitterPostListener Extends PostListener
Method OnPostComplete:Void()
Print("Message Tweeted Successfully");
End

Method OnPostFailure:Void(errorCode:Int, message:String)
Print("Message Not Tweeted: " + errorCode + " " + message)
End
End
')


erebel55(Posted 2014) [#13]
Does this not open the twitter app when sharing text?


sygem(Posted 2014) [#14]
No, the only user-interaction required is during the login process.


erebel55(Posted 2014) [#15]
Okay and facebook is the same way? Do you need to have the facebook/twitter apps installed on the device?

I am planning on adding a open facebook profile / twitter page function as well. So the user can like / follow my page on facebook / twitter.
This function would open the page in the appropriate social app and if they aren't present would open them in the browser instead.


erebel55(Posted 2014) [#16]
I am getting the following with your twitter example


I set the TWITTER_CONSUMER_KEY and TWITTER_CONSUMER_SECRET.

Also, on apps.twitter.com I set "Sign in with Twitter" to yes and changed the access permission to "Read and Write".

Is there anything else I need to do there? Do I need to set the callback url?


CopperCircle(Posted 2014) [#17]
Great work, I look forward to testing it. How about adding linkedin?


sygem(Posted 2014) [#18]
Is there anything else I need to do there? Do I need to set the callback url?


Yes, I think you do need to set the callback URL. Doesn't look like it matters what it is set to, as long as there is something set. There is something about your exact error here: https://dev.twitter.com/discussions/14503


sygem(Posted 2014) [#19]
How about adding linkedin?


LinkedIn looks possible - there seems to be unofficial Android & iOS libraries around. Maybe in the future...


erebel55(Posted 2014) [#20]
It worked after I set the callback URL to a placeholder. Thank you :)


erebel55(Posted 2014) [#21]
Hmm so even if I have the twitter / facebook apps installed and am logged in, this still prompts for the user to login?


sygem(Posted 2014) [#22]
Hmm so even if I have the twitter / facebook apps installed and am logged in, this still prompts for the user to login?


I believe so - each app needs to be authenticated, so just being logged into your twitter account in the twitter app is not enough. You still need to explicitly state that each twitter "app" - i.e. your Monkey app - is allowed to post to your feed. I think this only needs to happen once though.


erebel55(Posted 2014) [#23]
I am attempting to get a facebook example up and running
format_codebox('
Import socialite
Import mojo.app

#FACEBOOK = true
#FACEBOOK_APPLICATION_ID=""
#FACEBOOK_APPLICATION_NAMESPACE=""

Function Main:Int()
New FacebookTest()
End

Class FacebookTest Extends App

Method OnCreate()
SetUpdateRate(0)

Local fb:FacebookSharer = New FacebookSharer()
fb.AddPermission(Permission.USER_PHOTOS)
fb.AddPermission(Permission.EMAIL)
fb.AddPermission(Permission.PUBLISH_ACTION)
fb.SetPostListener(New PostListener())
fb.SetLoginListener(New LogInOutListener())
fb.Initialize(New InitializationListener())
fb.Login()
fb.ShareText("Testing Android FB Sharing")
End

End
')

However, I am getting a null pointer exception at line 38 of facebookSharer.android.java




sygem(Posted 2014) [#24]
Facebook is a little tricky - the initialization happens in a thread, so you can't call Login() until the initialization is complete. This is my test app - the call to Login() only happens after the InitializationListener returns. Similarly, the actual posting only happens after the LogInOutListener returns.

format_codebox('
Import socialite
Import mojo.app

#FACEBOOK = true
#FACEBOOK_APPLICATION_ID = "<YOUR ID HERE>"
#FACEBOOK_APPLICATION_NAMESPACE = "<YOUR NAMESPACE HERE>"

Function Main:Int()
New FacebookTest()
End

Class FacebookTest Extends App

Method OnCreate()
SetUpdateRate(0)
fb = New FacebookSharer()
fb.AddPermission(Permission.USER_PHOTOS)
fb.AddPermission(Permission.EMAIL)
fb.AddPermission(Permission.PUBLISH_ACTION) ' Only required for Android, which is a bit messy and will change
fb.SetPostListener(New FacebookPostListener())
fb.SetLoginListener(New FacebookLoginListener(Self))
fb.Initialize(New FacebookInitializationListener(Self))

End

Method PostStatusUpdate()
#if TARGET="android"
fb.ShareText("This is an android status update: " + FormatDate());
#else if TARGET="ios"
fb.ShareText("This is an ios status update: " + FormatDate());
#endif
End

Method FormatDate:String()
Local date:= GetDate()
Local months:=["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

Local day:=("0"+date[2])[-2..]
Local month:=months[date[1]-1]
Local year:=date[0]
Local hour:=("0"+date[3])[-2..]
Local min:=("0"+date[4])[-2..]
Local sec:=("0"+date[5])[-2..] + "." + ("00"+date[6])[-3..]

Local now:= hour + ":" + min + ":" + sec + " " + day + " " + month + " " + year
Return now
End

Method InitializationComplete:Void()
If Not fb.IsLoggedIn()
Print("Not logged in")
fb.Login()
EndIf
End

Field fb:FacebookSharer

End

Class FacebookLoginListener Extends LogInOutListener

Method New(fb:FacebookTest)
Self.fb = fb
End

Method OnLoginComplete:Void()
Print("Logged into Facebook!!!");
fb.PostStatusUpdate()
End

Method OnLoginFailure:Void(errorCode:Int, message:String)
Print("Login to Facebook failed: " + errorCode + " " + message)
End

Method OnLogoutComplete:Void()
Print("Logged out of Facebook!!!");
End

Private
Field fb:FacebookTest
End

Class FacebookPostListener Extends PostListener
Method OnPostComplete:Void()
Print("Message Posted Successfully");
End

Method OnPostFailure:Void(errorCode:Int, message:String)
Print("Message posting failed: " + errorCode + " " + message)
End
End

Class FacebookInitializationListener Extends InitializationListener

Method New(fb:FacebookTest)
Self.fb = fb
End

Method OnInitializeComplete:Void()
Print("Init complete!!!");
fb.InitializationComplete()
End

Method OnInitializeFailure:Void(errorCode:Int, message:String)
End

Private
Field fb:FacebookTest
End
')

Hope that helps :)


erebel55(Posted 2014) [#25]
Hm with your example I am still getting a NullPointerException on
format_code('
fb.Initialize(New FacebookInitializationListener(Self))
')


sygem(Posted 2014) [#26]
I have pushed an update to GitHub which should solve the NPE. I also slightly tweaked the example...

format_codebox('
Import socialite
Import mojo.app

#FACEBOOK = true
#FACEBOOK_APPLICATION_ID = "<YOUR ID HERE>"
#FACEBOOK_APPLICATION_NAMESPACE = "<YOUR NAMESPACE HERE>"

Function Main:Int()
New FacebookTest()
End

Class FacebookTest Extends App

Method OnCreate()
SetUpdateRate(0)
fb = New FacebookSharer()
fb.AddPermission(Permission.USER_PHOTOS)
fb.AddPermission(Permission.EMAIL)
fb.AddPermission(Permission.PUBLISH_ACTION) ' Only required for Android, which is a bit messy
fb.SetPostListener(New FacebookPostListener())
fb.SetLoginListener(New FacebookLoginListener(Self))
fb.Initialize(New FacebookInitializationListener(Self))

End

Method PostStatusUpdate()
Print("Post Status Update")
#if TARGET="android"
fb.ShareText("This is an android status update: " + FormatDate());
#else if TARGET="ios"
fb.ShareText("This is an ios status update: " + FormatDate());
#endif
End

Method FormatDate:String()
Local date:= GetDate()
Local months:=["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

Local day:=("0"+date[2])[-2..]
Local month:=months[date[1]-1]
Local year:=date[0]
Local hour:=("0"+date[3])[-2..]
Local min:=("0"+date[4])[-2..]
Local sec:=("0"+date[5])[-2..] + "." + ("00"+date[6])[-3..]

Local now:= hour + ":" + min + ":" + sec + " " + day + " " + month + " " + year
Return now
End

Method InitializationComplete:Void()
If Not fb.IsLoggedIn()
Print("Not logged in")
fb.Login()
Else
PostStatusUpdate()
EndIf
End

Field fb:FacebookSharer

End

Class FacebookLoginListener Extends LogInOutListener

Method New(fb:FacebookTest)
Self.fb = fb
End

Method OnLoginComplete:Void()
Print("Logged into Facebook!!!");
fb.PostStatusUpdate()
End

Method OnLoginFailure:Void(errorCode:Int, message:String)
Print("Login to Facebook failed: " + errorCode + " " + message)
End

Method OnLogoutComplete:Void()
Print("Logged out of Facebook!!!");
End

Private
Field fb:FacebookTest
End

Class FacebookPostListener Extends PostListener
Method OnPostComplete:Void()
Print("Message Posted Successfully");
End

Method OnPostFailure:Void(errorCode:Int, message:String)
Print("Message posting failed: " + errorCode + " " + message)
End
End

Class FacebookInitializationListener Extends InitializationListener

Method New(fb:FacebookTest)
Self.fb = fb
End

Method OnInitializeComplete:Void()
Print("Init complete!!!");
fb.InitializationComplete()
End

Method OnInitializeFailure:Void(errorCode:Int, message:String)
End

Private
Field fb:FacebookTest
End

')


erebel55(Posted 2014) [#27]
Yep, it's working now. Thanks sygem :)


Steve Oliver(Posted 2014) [#28]
Thanks for the module, sygem!

I noticed that I had to make a tweak for iOS for the Email share.

In emailSharer.ios.cpp, I changed 3 lines --

format_code('
//SocialNetworkListener *listener;
SocialPostListener *listener;

//+(SocialiteEmailDelegate*)delegateWithListener:(SocialNetworkListener*)listener;
+(SocialiteEmailDelegate*)delegateWithListener:(SocialPostListener*)listener;

//+(SocialiteEmailDelegate*)delegateWithListener:(SocialNetworkListener*)_listener {
+(SocialiteEmailDelegate*)delegateWithListener:(SocialPostListener*)_listener {
')

and then it worked fine.


rIKmAN(Posted 2014) [#29]
Does this still work with the latest Monkey?

I tried running the example that was posted but I just got errors, though that maybe me doing something wrong?


sygem(Posted 2014) [#30]
I'm still using 77d - did you get errors at compile or run time? What platform are you using?


rIKmAN(Posted 2014) [#31]
It was at compile time using the Android target in v79e, with the example code you gave in post #28.

Sorry I can't give the exact error at the moment as I'm not home right now - I'll post it as soon as I am.

Edit:
Managed to VNC in and get this from the error log...

format_code('
-compile:
[javac] Compiling 3 source files to C:\Rik\socialite\socialite.buildv79e\android\bin\classes
[javac] C:\Rik\socialite\socialite.buildv79e\android\src\com\monkeycoder\monkeygame\MonkeyGame.java:40: error: package com.facebook does not exist
[javac] import com.facebook.SessionState;
[javac] ^
[javac] C:\Rik\socialite\socialite.buildv79e\android\src\com\monkeycoder\monkeygame\MonkeyGame.java:2844: error: cannot access Session
[javac] if (mSimpleFacebook.getSession() != null && mSimpleFacebook.getSession().getState().equals(SessionState.CREATED_TOKEN_LOADED)) {
[javac] ^
[javac] class file for com.facebook.Session not found
[javac] C:\Rik\socialite\socialite.buildv79e\android\src\com\monkeycoder\monkeygame\MonkeyGame.java:2844: error: cannot find symbol
[javac] if (mSimpleFacebook.getSession() != null && mSimpleFacebook.getSession().getState().equals(SessionState.CREATED_TOKEN_LOADED)) {
[javac] ^
[javac] symbol: variable SessionState
[javac] location: class NativeFacebookSharer
[javac] Note: C:\Rik\socialite\socialite.buildv79e\android\src\com\monkeycoder\monkeygame\MonkeyGame.java uses unchecked or unsafe operations.
BUILD FAILED
C:\android-sdk-windows\tools\ant\build.xml:710: The following error occurred while executing this line:
C:\android-sdk-windows\tools\ant\build.xml:723: Compile failed; see the compiler error output for details.

Total time: 4 seconds
[javac] Note: Recompile with -Xlint:unchecked for details.
[javac] 3 errors

TRANS FAILED: Android build failed.
Abnormal program termination. Exit code: -1
')


rIKmAN(Posted 2014) [#32]
Bumpety bump!


sygem(Posted 2014) [#33]
It was at compile time using the Android target in v79e,


Have you downloaded the Facebook SDK and edited your project.properties file to point at the Facebook library project? It should look something like this...

format_code('android.library.reference.1=../../../../SDKs/facebook-android-sdk-3.8.0/facebook')


rIKmAN(Posted 2014) [#34]
No I didn't (*hangs head in shame*)

I didn't realise you had to, but maybe I was confusing this with the other FB module, or maybe I completely missed the instructions - either way no I didn't.
I only tried on Android as I have BlueStacks and wanted a quick test (I normally target iOS) of the FB stuff working, so I'm not too clued up on the Android side of things.

Could you give the steps required to get this working in an actual project please sygem?


sygem(Posted 2014) [#35]
I'm working on it :) I am close to finishing my next game, which uses Socialite for both Twitter & Facebook. I have upgraded to version 3.15 of the Facebook SDK, which has required a few modifications to get it working, so I will upload those to GitHub soon.

The basic steps are:

1. Download the Facebook SDK - probably use version 3.8, as that is what the current version was written with. This should be extracted to the same drive as your Monkey project. The Android tools don't seem to be able to handle different drive letters.
2. Build your Android project at least once - this will fail, but it creates the project.properties file in the android folder of your build.
3. Edit this file as I wrote above - pay attention to the number of levels you need to go up before finding the Facebook SDK
4. Build your project again - hopefully you will see it compiling the Facebook library project

And don't forget to include the preprocessor codes in your Monkey file too. Something like this...

' Facebook config
#FACEBOOK=True
#FACEBOOK_APPLICATION_ID = "1460361630906889"
#FACEBOOK_APPLICATION_NAMESPACE = "com_beatthis"
#ANDROID_MANIFEST_APPLICATION+="<meta-data android:name=~qcom.facebook.sdk.ApplicationId~q android:value=~q1460361630906889~q/>"

Hope that helps...


Zurrr(Posted 2015) [#36]
Facebook work here! Thank a lot.

Is there any way I can get the name of the user? And may be their profile picture to be use in my game


Rieha(Posted 2015) [#37]
Hey sygem - thanks for the module! Any updates? I've tried to run the sample but I'm getting an error: package com.facebook does not exist. Tried to change the SDK path in project.properties but no success. I have the latest version of FB Android SDK installed (3.23.0) and using OS X.

Zurrr - did it work for you without any tinkering?

Is it possible to share a picture to FB with this? Anyway would love to get this working!


sygem(Posted 2015) [#38]
I have the latest version of FB Android SDK installed (3.23.0)


The last version of the Facebook SDK I used was 3.15.0 - can you try using that version? I have never built an Android app using OS X.

Is it possible to share a picture to FB with this?


Do you mean like a screenshot? It is possible to share a link to a picture, so you could upload a picture somewhere first, then share the URL to that picture.

I am nearly at the Facebook/Twitter stage of my latest project, so I will be turning my attention there soon, hopefully next week. I will use the latest FB SDK, so that should iron out any remaining issues.


Rieha(Posted 2015) [#39]
Tried 3.15.0 and getting the same error as before. Maybe this is something to do with OS X paths or something, as I'm still fairly new to developing on a Mac. I'll try to investigate this further soon. Great that you're still working on this! Looking forward to see your game.

Screenshots are exactly what I was thinking of. It would be a cool way to get free promotion to share a screenshot with your score.


sygem(Posted 2015) [#40]
It might be possible to construct a Photo object using ReadPixels and publish that. I'll certainly look into it.