Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Twitter Plugin is Available Now!
Started by schroederapps Jul 17 2015 06:17 PM

42 replies to this topic
[TOPIC CONTROLS]
Page 1 of 2 1 2
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

schroederapps

[GLOBAL: userInfoPane.html]
schroederapps
  • Contributor

  • 466 posts
  • Corona SDK

Hey everybody,

 

Just a public service announcement that my Twitter plugin, which is free, is up on the Corona Labs plugin store (store.coronalabs.com) and can be used starting today. If you have any interest in integrating Twitter into your apps, I think you may find it very useful, and hopefully easy to use.

 

Full documentation on the plugin, plus a downloadable sample project, can be found at my website: http://twitter.plugin.jasonschroeder.com.

 

I created the Twitter plugin for Corona SDK to give Corona developers an easy way to access the full range of Twitter’s REST APIs from inside their apps, making it simple to get data from or post information to a Twitter user’s account with as little as a single line of code. The plugin automatically handles oAuth authentication, and persistently saves a logged-in user’s token data, so they’ll only need to log in and authorize your app once, even across multiple sessions, until they are manually logged out or revoke your app’s access to their Twitter account. The plugin also comes with a set of “convenience functions” that return Lua tables and/or Corona display objects, for easier access to common-use applications without the need for developers to wade through the raw JSON data that Twitter’s REST APIs return.

 

Here's a video of the sample project, which gives you some idea of how it works and what it can be used for:

 



[TOPIC: post.html]
#2

Michael W.

[GLOBAL: userInfoPane.html]
Michael W.
  • Contributor

  • 276 posts
  • Alumni

Excellent to see this up. Thank you for making this.


  • schroederapps likes this

[TOPIC: post.html]
#3

TandG

[GLOBAL: userInfoPane.html]
TandG
  • Contributor

  • 422 posts
  • Corona SDK

Good work! I'll have to give this a go soon!



[TOPIC: post.html]
#4

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,541 posts
  • Enterprise

Thanks for sharing...



[TOPIC: post.html]
#5

BearHugGames

[GLOBAL: userInfoPane.html]
BearHugGames
  • Enthusiast

  • 33 posts
  • Enterprise

This is an amazing plug-in and so simple to use, love it.

 

Is it possible to add callbacks for failed/cancelled/etc? I have UI elements I need to reset and other logic to perform if the user does not complete the log-in for whatever reason.

 

Great work!



[TOPIC: post.html]
#6

schroederapps

[GLOBAL: userInfoPane.html]
schroederapps
  • Contributor

  • 466 posts
  • Corona SDK

Thanks, @BearHug! And that's a great suggestion!

 

I just pushed out an updated version of the plugin. It could take an hour or more for it to be live on the distribution server, but once it is, here's what's new:

 

  • twitter.login() now accepts two arguments: an "onSuccess" function (which takes the place of the former "callback" function) and an "onFail" function that gets triggered if a user fails to log in (bad password, etc.) or if they choose to cancel the login attempt.

 

Hopefully this'll give you what you're looking for. I'll update the documentation on my own site later today, but here's some sample code to show what I mean:

local twitter = require "plugin.twitter"
twitter.init("API_KEY", "API_SECRET")


local function onSuccess()
	print("Twitter user " .. twitter.user.userName .. " successfully logged in!")
end

local function onFail()
	print("Twitter login attempt failed or was cancelled by user.")
end

twitter.login(onSuccess, onFail)

Thanks again for using the plugin. Enjoy!

 



[TOPIC: post.html]
#7

BearHugGames

[GLOBAL: userInfoPane.html]
BearHugGames
  • Enthusiast

  • 33 posts
  • Enterprise

That's exactly what I'm looking for, brilliant work! Hugely appreciated, thank you.



[TOPIC: post.html]
#8

schroederapps

[GLOBAL: userInfoPane.html]
schroederapps
  • Contributor

  • 466 posts
  • Corona SDK

UPDATE: the plugin now supports the Windows simulator! Previously it did not, because the only way to log in and authorize a Twitter app is through a webpage and URL listener, and the Windows simulator does not support native.newWebView().

 

Now the workaround is a bit of a hack, and does involve an extra step or two, so it's by no means perfect. But it will allow you to test out your Twitter-centric code in the Windows simulator without needing to build for device. You can read detailed instructions for the workaround at http://www.jasonschroeder.com/2015/07/15/twitter-plugin-for-corona-sdk/#gotchas. Or just call twitter.login() from the Windows simulator and it will walk you through the workaround process.



[TOPIC: post.html]
#9

ChunkyApps

[GLOBAL: userInfoPane.html]
ChunkyApps
  • Contributor

  • 224 posts
  • Corona SDK

Thank you, very cool!



[TOPIC: post.html]
#10

anil8

[GLOBAL: userInfoPane.html]
anil8
  • Contributor

  • 124 posts
  • Corona SDK

Jason,

 

 

Thanks for donating this powerful and easy to use Plugin to the community - I was able to send out a tweet in 10 lines of code!!!

 

Do you have any plans to add any other convenience functions?

 

In particular, I am sure the community would love the ability to add an image along with the tweet text (I know this is also available with the Social Plugin ) - is this on your wish list already?

 

I had a quick look at the Twitter Restful Api and looked at using your twitter.request() call to call the POST media/upload endpoint but got lost with the multipart/form-data requests.

 

Keep up the great work!



[TOPIC: post.html]
#11

schroederapps

[GLOBAL: userInfoPane.html]
schroederapps
  • Contributor

  • 466 posts
  • Corona SDK

Hi Anil,

 

Thanks for the kind feedback! I honestly hadn't spent too much time with uploading photos, so I had left it out of the "convenience functions" but I'll see what I can do. I agree that it'd be a nice addition, and something that (if I do it right) could really take some of the frustration out of the process. I'm a little busy with client projects right now, so I might not be able to add this feature as fast as I'd like, but it's on my radar.

 

Thanks!



[TOPIC: post.html]
#12

anil8

[GLOBAL: userInfoPane.html]
anil8
  • Contributor

  • 124 posts
  • Corona SDK

Jason,

 

 

I am sure that this new convenience function is going to make a lot of people happy - I will be keeping a keen eye out for it in the coming weeks.

 

Don't want to sound cheeky, but if you are keeping a wish list for the plugin, then Twitter also supports adding your current location to the tweet which effectively gives you a 'Checking In' type facility similar to Facebook and Foursqare et al (   https://dev.twitter.com/overview/api/places and https://support.twitter.com/articles/122236). 

 

 

Thanks again.

 

 

Anil



[TOPIC: post.html]
#13

schroederapps

[GLOBAL: userInfoPane.html]
schroederapps
  • Contributor

  • 466 posts
  • Corona SDK

Hi Anil,

 

I'll give some thought to adding support for adding location using twitter.tweet(), but my initial thought is to leave that functionality to twitter.request(), as I don't want to over-complicate the convenience functions too much. But you can certainly add a location easily enough using twitter.request(). Use the "statuses/update" endpoint and add an optional "place_id" parameter in the parameters table.



[TOPIC: post.html]
#14

schroederapps

[GLOBAL: userInfoPane.html]
schroederapps
  • Contributor

  • 466 posts
  • Corona SDK

UPDATE TO PLUGIN SUPPORT ON WINDOWS SIMULATOR:

 

Since Corona Labs added support for native.newTextField() in the latest daily build, I have modified the way the plugin behaves in the Windows simulator - whereas previously you had to copy and paste a valid oAuth token string into your code and relaunch the simulator every time you called twitter.login(), now you are presented with a text field when you call twitter.login() and you can just paste that token string directly into the simulator, with no need to modify your code!

 

The only "gotcha" with this new method is that you must be using daily build # 2015.2695 or later to use the plugin in the Windows simulator. I decided that the hassle of requiring plugin users to update their SDK was worth it, given the much faster and easier authorization process with this new method. Note that you can still build for device using earlier versions of the SDK with no issues - you only need to update your SDK if you want to test plugin functionality in the Windows simulator. If you do try to call twitter.login() using an earlier SDK build, you'll get a native system alert reminding you that you must update to use the plugin in the Windows simulator.

 

I've updated the documentation on my website and have pushed the new plugin version live, so you should see this new functionality next time you fire up the plugin in the Windows simulator. Enjoy!



[TOPIC: post.html]
#15

mmk.verheijden

[GLOBAL: userInfoPane.html]
mmk.verheijden
  • Contributor

  • 203 posts
  • Corona SDK

So I'm trying to upload a photo to twitter using the twitter.request function but getting this error:

 

Your twitter request was received successfully, but returned the following error(s):
CODE 195: Missing or invalid url parameter.

v1 :

twitter.request({
endpoint = "statuses/update_with_media",
method = "POST",
parameters = {
    status = "test tweet",
    media = "pic.png",
},
callback = myCallback,
})

v2 :

twitter.request({
endpoint = "statuses/update_with_media",
method = "POST",
url = "https://api.twitter.com/1.1/statuses/update_with_media.json",
contentType = "multipart/form-data",
parameters = {
    status = "test tweet",
    media = "pic.png",
},
callback = myCallback,
})

 

v3 :

twitter.request({
endpoint = "statuses/update_with_media",
method = "POST",
parameters = {
    status = "test tweet",
    media = "pic.png",
    url = "https://api.twitter.com/1.1/statuses/update_with_media.json",
    contentType = "multipart/form-data",
},
callback = myCallback,
})

ps this works :

twitter.request({
endpoint = "statuses/update",
method = "POST",
parameters = {
status = "test tweet",
},
callback = myCallback,
})

 



[TOPIC: post.html]
#16

mmk.verheijden

[GLOBAL: userInfoPane.html]
mmk.verheijden
  • Contributor

  • 203 posts
  • Corona SDK

v4 :P


baseDir = system.DocumentsDirectory
display.save( backGroup, "screenshot.png", system.DocumentsDirectory )
 
local function read_image()
local path = system.pathForFile( "screenshot.png", system.DocumentsDirectory )
local f = assert(io.open( path ))
local image_data = f:read("*a")
f:close()
return image_data
end
 
 
twitter.request({
endpoint = "statuses/update_with_media",
method = "POST",
parameters = {
 
    status = "Hello World From Lua!" .. os.time(),
    --["media"] = 
    ["media[]"] = {
filename = "@screenshot.png",
data = read_image()
}
},
callback = myCallback,
})
 

 

but still getting the Your twitter request was received successfully, but returned the following error(s):
CODE 195: Missing or invalid url parameter. error, not sure what to do 


[TOPIC: post.html]
#17

schroederapps

[GLOBAL: userInfoPane.html]
schroederapps
  • Contributor

  • 466 posts
  • Corona SDK

@mmk: I don't think the current version of the plugin is going to do what you want it to. Because the plugin does not handle converting image files into multipart form data (which Twitter requires), you're going to keep running into this issue. I'm working on a solution, but it's going to take me some time, sorry. Adding to the confusion is the fact that the "statuses/update_with_media" endpoint is deprecated, so I'm not sure how well it's going to work, if at all. And any other Twitter modules I've seen for Corona have used that specific endpoint to handle media uploads. It's a sticky wicket, that's for sure. Sorry to ask you to wait, but I'll see what I can do. It's going to be several days, at least - and possibly longer, I'm afraid, before I'll be able to dedicate enough time to this to properly identify and implement a solution, given my schedule constraints at the moment.



[TOPIC: post.html]
#18

mmk.verheijden

[GLOBAL: userInfoPane.html]
mmk.verheijden
  • Contributor

  • 203 posts
  • Corona SDK

i see no worries ill will wait :D 



[TOPIC: post.html]
#19

schroederapps

[GLOBAL: userInfoPane.html]
schroederapps
  • Contributor

  • 466 posts
  • Corona SDK

Well, despite my warnings that it would take me a while to implement this, I got a bee in my bonnet about it yesterday and wound up adding support for image uploads to the plugin! I've updated the documentation on my website (http://twitter.plugin.jasonschroeder.com) but here's a quick primer on how to upload images using twitter.tweet and/or twitter.request:

 

Adding an image to a twitter.tweet() call is super easy. Just pass in an image file like you would for display.newImage() as the second argument to twitter.tweet() and it'll upload that picture and attach it to your tweet. If you are specifying a callback function (which used to go in the second argument slot), just make that the third argument now - unless you don't want to upload an image, in which case you can use the old syntax, where the callback function is the 2nd argument. For example, this bit of code:

 

twitter.tweet("Tweeted from @schroederapps #CoronaSDK Twitter plugin. Now supporting image uploads!", "yes.jpg", callbackFunction)

 

will result in this tweet:

tweetImgSample.png

 

Or, if you'd rather take more control and use twitter.request, then this bit of code would result in the same tweet getting posted (but you'd get access to the full returned JSON in your callback function):

 

twitter.request({
   endpoint = "statuses/update_with_media",
   method = "POST",
   parameters = {
      status = "Tweeted from @schroederapps #CoronaSDK Twitter plugin. Now supporting image uploads!",
      media = system.pathForFile("yes.jpg", system.ResourceDirectory),
   },
   callback = callbackFunction,
})

 

Enjoy!



[TOPIC: post.html]
#20

mmk.verheijden

[GLOBAL: userInfoPane.html]
mmk.verheijden
  • Contributor

  • 203 posts
  • Corona SDK

works like a charm :D



[TOPIC: post.html]
#21

mmk.verheijden

[GLOBAL: userInfoPane.html]
mmk.verheijden
  • Contributor

  • 203 posts
  • Corona SDK

if you want to tweet your level or score :D

 

showLevel = settings.get('levelSelect') -- level currently playing

twitter.request({
   endpoint = "statuses/update_with_media",
   method = "POST",
   parameters = {
      status = "im struggling with level " .. showLevel .. " playing ...... bla bla bla link",
      media = system.pathForFile("screenshot.png", system.DocumentsDirectory),
   },
   callback = tweetCallback,
})


[TOPIC: post.html]
#22

marksumarksu

[GLOBAL: userInfoPane.html]
marksumarksu
  • Enthusiast

  • 42 posts
  • Enterprise

Seems great! Is this available for Enterprise users as well?



[TOPIC: post.html]
#23

AidanWolf

[GLOBAL: userInfoPane.html]
AidanWolf
  • Enthusiast

  • 92 posts
  • Corona SDK

Hi schroederapps,

 

Thank you for this great plugin!

 

There is a major bug with the Twitter login though. If you have a username (screenName) with an underscore "_" (Aidan_Wolf), you get a Runtime Error:

Runtime error
	?:0: attempt to concatenate field 'screenName' (a nil value)
stack traceback:
	[C]: ?
	?: in function '?'
	?: in function <?:164>

Please fix!

 

And while I'm at it, do you think you could integrate the quick twitter login feature on iOS? The popup that displays your currently connected accounts.

 

Thank you,

Aidan



[TOPIC: post.html]
#24

schroederapps

[GLOBAL: userInfoPane.html]
schroederapps
  • Contributor

  • 466 posts
  • Corona SDK

Hi @AidanWolf,

 

Thanks for the kind words. I was able to login successfully and utilize the full range of APIs with an account that has underscores in its name (@screen_sat_app), so I think there might be an issue with your code that is preventing it from working. The runtime error you pasted indicates that the screenName was nil, which leads me to believe that you are not putting the screen name in quotes when making an API call - am I right in that assumption?

 

When making an API call that takes a screen name as an argument, that screen name must be a string - meaning it has to be in quotes, or it must be a variable name that references a string value. For example, here are two valid ways of getting basic user information for your twitter handle:

--passing a string directly into the API call:
twitter.getUser("Aidan_Wolf", callback)
-- passing a variable into the API call that references a string:
local myScreenName = "Aidan_Wolf"
twitter.getUser(myScreenName, callback)

Let me know if you still can't get it to work, and please attach a simple lua file that illustrates exactly how you are getting the error and I'll investigate further if need be. But I suspect that a simple modification to your code will fix the issue.

 

As to your second request, I'm afraid that because I wrote this plugin as a pure Lua module, I'm unable to access native OS features like the one you mentioned. An enterprise developer might be able to do that, but it's not something I'm able to do at this time. Sorry. Note that if you simply want to post a tweet to the user's (already logged-in) Twitter account, you can do that using the built-in Corona social plugin. My Twitter plugin's primary value is that it allows you to pull data from a Twitter account - posting simple tweets was already possible via the social plugin.

 

Thanks for using the plugin - good luck with your app! :)



[TOPIC: post.html]
#25

AidanWolf

[GLOBAL: userInfoPane.html]
AidanWolf
  • Enthusiast

  • 92 posts
  • Corona SDK

Thank you for the quick reply.

 

This is all the code required: 

local twitter = require("plugin.twitter")
twitter.init("xxx", "xxx")

local function onSuccess()
   print("successful!")
end
local onFail 
function onFail()
   print("Twitter login attempt failed or was cancelled by user.")
end
twitter.login(onSuccess, onFail)

Response for "Aidan_Wolf"

Runtime error
	?:0: attempt to concatenate field 'screenName' (a nil value)
stack traceback:
	[C]: ?
	?: in function '?'
	?: in function <?:164>

Response for "CapsuleDev"

Successfully authorized Twitter user "CapsuleDev"
Jan 24 02:21:39.358 successful!

In your documentation, there is an error with the code, possibly needs updated?

 

print("Twitter user " .. twitter.user.userName .. " successfully logged in!")

 

Switching "userName" to "screenName" fixed it. I can imagine there's something in the code that is not updated to handle "screenName" when there's some type of special formatting necessary.




[topic_controls]
Page 1 of 2 1 2
 
[/topic_controls]