facebook opa tutorial

6
2/1/12 Hands-on experience with Opa 2/7 file:///Users/henri/Downloads/facebook-01/Facebook tutorial 01.html Making friends with Facebook: Making friends with Facebook: Introduction Introduction Lots of announcements lately, but not many tutorials; time to change it. Hopefully by now you know how Lots of announcements lately, but not many tutorials; time to change it. Hopefully by now you know how easy it is to create web apps in Opa (if you don't and/or are new around here I suggest you explore the easy it is to create web apps in Opa (if you don't and/or are new around here I suggest you explore the history of this blog that has a number of tutorials, also for beginners), but as we all know web apps hardly history of this blog that has a number of tutorials, also for beginners), but as we all know web apps hardly ever live in isolation. More often than not they interact with other services and platforms. Today I present ever live in isolation. More often than not they interact with other services and platforms. Today I present you with the first article in the series you with the first article in the series `‘Making friends with Facebook’' `‘Making friends with Facebook’', that will explore how to interact with , that will explore how to interact with Facebook from Opa apps. Ready? You better… Facebook from Opa apps. Ready? You better… Summary Summary You will learn: You will learn: How to use Opa's Facebook API to connect with user's Facebook account. How to use Opa's Facebook API to connect with user's Facebook account. How to write a simple Opa app that will show given user's name and thumbnails of her friends (both How to write a simple Opa app that will show given user's name and thumbnails of her friends (both data obtained from Facebook). data obtained from Facebook). Setting up a Facebook app Setting up a Facebook app To get started we need to create our app's profile on Facebook. To do that go to To get started we need to create our app's profile on Facebook. To do that go to https://developers.facebook.com https://developers.facebook.com. You'll see the following status bar. . You'll see the following status bar. Go the Apps (highlighted in the above screenshot) and choose “Create New App”. Go the Apps (highlighted in the above screenshot) and choose “Create New App”. That will open a dialog with basic info about the new application. For now just put That will open a dialog with basic info about the new application. For now just put OpaIntro1 OpaIntro1 as as App App display name display name (we'd prefer something like (we'd prefer something like HelloFacebook HelloFacebook, but using Facebook trademarks in app names is , but using Facebook trademarks in app names is prohibited) and agree to the Facebook Platform Policies (preferably, after reading ;). prohibited) and agree to the Facebook Platform Policies (preferably, after reading ;).

Upload: henri-binsztok

Post on 17-May-2017

213 views

Category:

Documents


0 download

TRANSCRIPT

2/1/12 Hands-on experience with Opa

2/7file:///Users/henri/Downloads/facebook-01/Facebook tutorial 01.html

Making friends with Facebook:Making friends with Facebook:IntroductionIntroduction

Lots of announcements lately, but not many tutorials; time to change it. Hopefully by now you know howLots of announcements lately, but not many tutorials; time to change it. Hopefully by now you know howeasy it is to create web apps in Opa (if you don't and/or are new around here I suggest you explore theeasy it is to create web apps in Opa (if you don't and/or are new around here I suggest you explore thehistory of this blog that has a number of tutorials, also for beginners), but as we all know web apps hardlyhistory of this blog that has a number of tutorials, also for beginners), but as we all know web apps hardlyever live in isolation. More often than not they interact with other services and platforms. Today I presentever live in isolation. More often than not they interact with other services and platforms. Today I presentyou with the first article in the series you with the first article in the series `‘Making friends with Facebook’'`‘Making friends with Facebook’', that will explore how to interact with, that will explore how to interact withFacebook from Opa apps. Ready? You better…Facebook from Opa apps. Ready? You better…

SummarySummary You will learn:You will learn:

How to use Opa's Facebook API to connect with user's Facebook account.How to use Opa's Facebook API to connect with user's Facebook account.

How to write a simple Opa app that will show given user's name and thumbnails of her friends (bothHow to write a simple Opa app that will show given user's name and thumbnails of her friends (bothdata obtained from Facebook).data obtained from Facebook).

Setting up a Facebook appSetting up a Facebook app

To get started we need to create our app's profile on Facebook. To do that go toTo get started we need to create our app's profile on Facebook. To do that go tohttps://developers.facebook.comhttps://developers.facebook.com. You'll see the following status bar.. You'll see the following status bar.

Go the Apps (highlighted in the above screenshot) and choose “Create New App”.Go the Apps (highlighted in the above screenshot) and choose “Create New App”.

That will open a dialog with basic info about the new application. For now just put That will open a dialog with basic info about the new application. For now just put OpaIntro1OpaIntro1 as as AppAppdisplay namedisplay name (we'd prefer something like (we'd prefer something like HelloFacebookHelloFacebook, but using Facebook trademarks in app names is, but using Facebook trademarks in app names isprohibited) and agree to the Facebook Platform Policies (preferably, after reading ;).prohibited) and agree to the Facebook Platform Policies (preferably, after reading ;).

2/1/12 Hands-on experience with Opa

3/7file:///Users/henri/Downloads/facebook-01/Facebook tutorial 01.html

Then (possibly after answering a Captcha) you will be presented with the following settings screen.Then (possibly after answering a Captcha) you will be presented with the following settings screen.

Firstly note on the top of the screen the “App ID” and “App Secret” (they're blurred in the screenshot as theFirstly note on the top of the screen the “App ID” and “App Secret” (they're blurred in the screenshot as thesecret secret should not be sharedshould not be shared with anyone) — we will need those values in a minute. Then in the “Select with anyone) — we will need those values in a minute. Then in the “Selecthow your app integrates with Facebook” section (bottom of the screen; note that we cut out the “Basic info”how your app integrates with Facebook” section (bottom of the screen; note that we cut out the “Basic info”and “Cloud services” sections of the settings in the screenshot) select the “Website” mark, put the URL atand “Cloud services” sections of the settings in the screenshot) select the “Website” mark, put the URL atwhich your application will be hosted — it's important to get that right as the Facebook login will onlywhich your application will be hosted — it's important to get that right as the Facebook login will onlyredirect to this site's URL — and click “Save changes”.redirect to this site's URL — and click “Save changes”.

Ok, we're all set on the Facebook side; now let's do some Opa coding!Ok, we're all set on the Facebook side; now let's do some Opa coding!

Writing the Opa applicationWriting the Opa application

The goal of the app is simple: allow users to login via Facebook and upon connection greet them with theirThe goal of the app is simple: allow users to login via Facebook and upon connection greet them with their

2/1/12 Hands-on experience with Opa

4/7file:///Users/henri/Downloads/facebook-01/Facebook tutorial 01.html

name and a quick info on the number of friends they have.name and a quick info on the number of friends they have.

Since we will be using Facebook API, including authentication and Since we will be using Facebook API, including authentication and Facebook GraphFacebook Graph to have some basic to have some basicinfo about the logged-in user let's start with some imports.info about the logged-in user let's start with some imports.

importimport stdlib stdlib..apisapis..{{facebookfacebook,, facebook facebook..authauth,, facebook facebook..graphgraph}}

Then we need to fill in some basic info about the application; we'll put this inside a module.Then we need to fill in some basic info about the application; we'll put this inside a module.

module OpaIntro1 module OpaIntro1 {{

configconfig == {{ app_id app_id:: "xxxxxxxxxxxxxxx""xxxxxxxxxxxxxxx" ,, api_key api_key:: "xxxxxxxxxxxxxxx""xxxxxxxxxxxxxxx" ,, app_secret app_secret:: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }}

}}}}

Of course the x's need to be replaced with the real data here — Of course the x's need to be replaced with the real data here — app_idapp_id and and app_keyapp_key are the same (there are the same (thereused to be a distinction) and correspond to “App ID” in the Facebook settings screen, whereasused to be a distinction) and correspond to “App ID” in the Facebook settings screen, whereasapp_secretapp_secret is the value of “App secret”. is the value of “App secret”.

Now we initialize the authentication module with this configuration, make an abbreviation for the FacebookNow we initialize the authentication module with this configuration, make an abbreviation for the FacebookGraph module and define the redirect URL — this is where Facebook will redirect after authenticating theGraph module and define the redirect URL — this is where Facebook will redirect after authenticating theuser.user.

FBAFBA == FbAuthFbAuth(OpaIntro1.(OpaIntro1.configconfig))FBGFBG == FbGraph FbGraphredirectredirect == "http://facebook-01.tutorials.opalang.org/connect""http://facebook-01.tutorials.opalang.org/connect"

Now, we have to handle two pages: the login screen that will show the Facebook connect button and theNow, we have to handle two pages: the login screen that will show the Facebook connect button and themain screen that is visible after login. Let's start with the main page.main screen that is visible after login. Let's start with the main page.

function function mainmain()() {{ login_urllogin_url == FBA.FBA.user_login_urluser_login_url([],([], redirect redirect)) <<a a hrefhref=="{"{login_urllogin_url}"}"><><img img srcsrc=="resources/fb_connect.png""resources/fb_connect.png" /><//></aa>>}}

The The user_login_urluser_login_url function of the authentication module of the Opa Facebook API gives us the URL function of the authentication module of the Opa Facebook API gives us the URLto redirect to in order to invoke authentication. The first argument is the list of permissions that weto redirect to in order to invoke authentication. The first argument is the list of permissions that werequire — for now, we keep it empty. Then we just create a regular link to that address and put a nice imagerequire — for now, we keep it empty. Then we just create a regular link to that address and put a nice imagefor it. And that's it.for it. And that's it.

Now let's take a look at the dispatcher of our application:Now let's take a look at the dispatcher of our application:

dispatcherdispatcher == parserparser|| "/connect?""/connect?" datadata=(.*)=(.*) ->-> connectconnect(Text.(Text.to_stringto_string((datadata)))) |>|> page page

2/1/12 Hands-on experience with Opa

5/7file:///Users/henri/Downloads/facebook-01/Facebook tutorial 01.html

|| .*.* ->-> mainmain()() |>|> page page

The The /connect/connect page is where we are redirected upon completing authentication (see the page is where we are redirected upon completing authentication (see the redirectredirectvariable before); it will have an extra parameter after the question mark, which is the Facebookvariable before); it will have an extra parameter after the question mark, which is the Facebookauthentication token that we will use for all functionality requiring Facebook login (in our app: to get someauthentication token that we will use for all functionality requiring Facebook login (in our app: to get somedata about the logged-in user). Any other URL in our sample app is handled with the welcome screen thatdata about the logged-in user). Any other URL in our sample app is handled with the welcome screen thatwe created above. The we created above. The pagepage function is just a simple wrapper to create an HTML-page resource (we skip it function is just a simple wrapper to create an HTML-page resource (we skip ithere but we encourage curious readers to consult the complete listing at the end of the article).here but we encourage curious readers to consult the complete listing at the end of the article).

Finally the Finally the connectconnect function that takes as an argument the part of the URL after the question mark. First function that takes as an argument the part of the URL after the question mark. Firstwe need to extract a token from this string withwe need to extract a token from this string with

FBA.FBA.get_token_rawget_token_raw((datadata,, redirect redirect))

which optionally returns a token that we can subsequently use to get some user data. For that we will use thewhich optionally returns a token that we can subsequently use to get some user data. For that we will use theFacebook Graph API, which one can explore at: Facebook Graph API, which one can explore at: https://developers.facebook.com/tools/explorerhttps://developers.facebook.com/tools/explorer. Two. Twofunctions that are used for this are:functions that are used for this are:

FBG.Read.FBG.Read.objectobject((idid,, options options))FBG.Read.FBG.Read.connectionconnection((idid,, connection connection,, token token,, paging paging))

For instance reading object For instance reading object "me""me" (try (try https://graph.facebook.com/mehttps://graph.facebook.com/me in the Facebook API in the Facebook APIexplorer) will give basic information about the logged-in user (we will extract name from there), whereasexplorer) will give basic information about the logged-in user (we will extract name from there), whereasreading connection reading connection "friends""friends" of object of object "me""me" (try (try https://graph.facebook.com/me/friendshttps://graph.facebook.com/me/friends))will give the list of user's friends.will give the list of user's friends.

The returned data is in The returned data is in JSONJSON format, so we have to do a bit of processing to extract the data we need. See format, so we have to do a bit of processing to extract the data we need. Seefunction function get_nameget_name in the complete listing below for details on how to get logged-in user's name. Similarly in the complete listing below for details on how to get logged-in user's name. Similarlyconsult consult get_friends_idsget_friends_ids to see how to obtain ids of given user's friends, which then is used in the to see how to obtain ids of given user's friends, which then is used in themain_msgmain_msg function where we get a thumbnail of user with given function where we get a thumbnail of user with given idid using the using the FBG.Read.picture_urlFBG.Read.picture_urlfunction.function.

Ideally, the API should be extended with more high level functions that would provide a nice mapping fromIdeally, the API should be extended with more high level functions that would provide a nice mapping fromthe JSON Facebook API to a type-safe world of Opa (essentially doing what we did in those functions butthe JSON Facebook API to a type-safe world of Opa (essentially doing what we did in those functions butfor all possible objects/connections). This can be done of course (volunteers?) but is a bit complicated by thefor all possible objects/connections). This can be done of course (volunteers?) but is a bit complicated by thefact that the shape of the information for different queries depends on application permissions.fact that the shape of the information for different queries depends on application permissions.

So, let us present our first Facebook app in Opa. The complete listing & a link to the running version of theSo, let us present our first Facebook app in Opa. The complete listing & a link to the running version of theapplication below.application below.

importimport stdlib stdlib..apisapis..{{facebookfacebook,, facebook facebook..authauth,, facebook facebook..graphgraph}}importimport stdlib stdlib..{{themesthemes..bootstrapbootstrap,, widgets widgets..bootstrapbootstrap}}

configconfig == OpaIntro1.OpaIntro1.configconfigredirectredirect == "http://facebook-01.tutorials.opalang.org/connect""http://facebook-01.tutorials.opalang.org/connect"

2/1/12 Hands-on experience with Opa

6/7file:///Users/henri/Downloads/facebook-01/Facebook tutorial 01.html

FBAFBA == FbAuthFbAuth((configconfig))FBGFBG == FbGraph FbGraph

function function mainmain()() {{ login_urllogin_url == FBA.FBA.user_login_urluser_login_url([],([], redirect redirect)) <<a a hrefhref=="{"{login_urllogin_url}"}"><><img img srcsrc=="resources/fb_connect.png""resources/fb_connect.png" /><//></aa>>}}

function function show_boxshow_box((tt,, title title,, description description)) {{ WBootstrap.Message.WBootstrap.Message.makemake(( {{ alert alert:: ~~{{ title title,, description description }} ,, closable closable:: false false }},, t t ))}}

function function get_nameget_name((tokentoken)) {{ optsopts == {{ FBG.Read.FBG.Read.default_object default_object withwith token token::tokentoken..token token }} matchmatch (FBG.Read.(FBG.Read.objectobject(("me""me",, opts opts)))) {{ case case {{~object~object}}:: matchmatch (List.(List.assocassoc(("name""name",, object object..datadata)))) {{ case case {{somesome:: {{StringString:: v v}}}}:: somesome((vv)) default default:: none none }} default default:: none none }}}}

function function get_friends_idsget_friends_ids((tokentoken)) {{ optsopts == FBG.FBG.default_pagingdefault_paging matchmatch (FBG.Read.(FBG.Read.connectionconnection(("me""me",, "friends""friends",, token token..tokentoken,, opts opts)))) {{ case case {{successsuccess:: c c}}:: somesome(List.(List.mapmap((function function ((friendfriend)) {{ friend friend..id id }},, c c..datadata)))) default default:: none none }}}}

function function main_msgmain_msg((friendsfriends)) {{ function function friend_imgfriend_img((idid)) {{ {{ href href:: none none ,, onclick onclick:: ignore ignore ,, content content:: <<img img srcsrc=={{FBG.Read.FBG.Read.picture_urlpicture_url((idid,, {{squaresquare}}))}} />/> }} }} <><> <<h4h4>>Your friendsYour friends:</>:</> {{WBootstrap.Media.WBootstrap.Media.gridgrid(List.(List.mapmap((friend_imgfriend_img,, friends friends))))}} </></>}}

function function connectconnect((datadata)) {{ matchmatch (FBA.(FBA.get_token_rawget_token_raw((datadata,, redirect redirect)))) {{ case case {{~token~token}}:: matchmatch ((get_nameget_name((tokentoken)))) {{ case case {{somesome:: name name}}:: matchmatch ((get_friends_idsget_friends_ids((tokentoken)))) {{ case case {{somesome:: friends friends}}:: show_boxshow_box(({{successsuccess}},, "Hello, {"Hello, {namename}!"}!",, main_msgmain_msg((friendsfriends)))) default default:: show_boxshow_box(({{errorerror}},, "Error getting your friends list""Error getting your friends list",, <></>)<></>) }} default default:: show_boxshow_box(({{errorerror}},, "Error getting your name""Error getting your name",, <></>)<></>) }} case case ~~{{errorerror}}:: show_boxshow_box(({{errorerror}},, error error..errorerror,, <><>{{errorerror..error_descriptionerror_description}}</>)</>) }}}}

function function pagepage((bodybody)) {{ Resource.Resource.htmlhtml(("Facebook connect tutorial""Facebook connect tutorial",, WBootstrap.Layout.WBootstrap.Layout.fixedfixed(( <><> <<h1h1>>Facebook connect tutorialFacebook connect tutorial</></> {{bodybody}} </></> )) ))}}

2/1/12 Hands-on experience with Opa

7/7file:///Users/henri/Downloads/facebook-01/Facebook tutorial 01.html

dispatcherdispatcher == parserparser|| "/connect?""/connect?" datadata=(.*)=(.*) ->-> connectconnect(Text.(Text.to_stringto_string((datadata)))) |>|> page page|| .*.* ->-> mainmain()() |>|> page page

Server.Server.startstart(Server.(Server.httphttp,, [[ {{ resources resources:: @static_resource_directory@static_resource_directory(("resources""resources")) }} ,, {{ custom custom:: dispatcher dispatcher }} ]]))

Later we will continue this series of tutorials with examples of some more advancedLater we will continue this series of tutorials with examples of some more advancedinteractions with the Facebook platform. I'm not sure yet what it will involve so requests andinteractions with the Facebook platform. I'm not sure yet what it will involve so requests andgood ideas are welcome — just drop a comment!good ideas are welcome — just drop a comment!

RunRunSeeSee