Learn how to create a desktop application for Facebook, using their GraphAPI and Visual Basic.NET
Introduction
Hello
again. If you have read my previous article about creating an application
for Facebook, you most probably have noticed that the application sample might
not be working anymore. Why? Well, because that application was built on the REST
API, which is being deprecated by Facebook and replaced by the GraphAPI
framework. Not to worry, this is the exact purpose of this article, and when
Facebook changes their framework again, we'll cross that bridge when or if we
get there.
GraphAPI
First, let
me explain how the GraphAPI works, and what it is precisely. The GraphAPI
is actually a lot less complicated than one would think. It uses the very
same principle programmers use every day, and that is: everything is connected,
and everything has properties and / or methods. For example, each event in Facebook
has certain properties, each friend has certain properties and methods.
Everything is connected, but how? Very simple. Let us assume I Like a certain
page. Then, somebody else also Likes that page. Right, now we have 2 people who
share a common interest. Let us take it a step further. Because we have Liked
the same page, we are now connected. We'll be able to see which friends each
person has, we will see their Likes, and so on. So everything is connected, via
a certain relationship that has been formed. Have a look at how Facebook
explains their GraphAPI
FQL
Facebook Query
Language
uses a similar style to SQL to extract the correct information from the correct
tables. Anything you see on Facebook forms part of a
database. It is broken down into several
separate tables. For example: Friends is a table, Friend Request is a table,
Messages is a table, Notifications is a table, Like is a table and so on. For a
complete list of available tables, have a look
here. The above tables I mentioned
might have different names, as I was just using them to illustrate my example
better. We will use FQL to extract the information we need in our sample
application.
Sample
I was lucky
enough to stumble upon CodePlex some time ago.
It is an excellent site and it gets better day by day. On CodePlex they
provide an SDK for Facebook. An SDK
is a software development kit, which provides samples and tutorials on a
certain topic. The sad thing here is that the Facebook SDK they provide is
strictly for C#.
Sometimes I wonder if people do not realize how powerful VB.NET is, or if
they just don't care. I love C# and VB equally, and I always try to make the
same things in both languages, just to prove that it is possible. I had an extensive
look at the sample they have provided and was quite happy with them. I then had
the brainwave to make my own Notifier application with VB.NET. I
had two choices, use a C# / VB.NET
converter, or convert it manually. I chose the hard option, which was to
convert the codes manually. Now, do not get me wrong, this is not a verbatim
copy of one of CodePlex's samples. Yes, I do things similar, because that is
the only way, but I do make use of my own logic as well.
Because I
chose to convert the code manually, I encountered a lot of issues, and had to
improvise, and rewrite certain segments completely. With the sample that I am
providing, I aim to first show you that Facebook applications can be done in
VB.NET, and second to provide the ability for lazy people, such as myself, to
check notifications from Facebook on my profile, thus eliminating the need to
open my Internet browser and navigating to my Facebook profile page.
Setup
The first
step is actually optional for this article, but I would really recommend it--that
is if you really want to learn the complete ins and outs of creating a Facebook
application. The first step is to download the SDK from
CodePlex. This will give you access to all the needed DLL files inside
their associated projects. Once downloaded, the samples folder will be
named something in the lines of facebooksdk_b3789011d8e2\Samples; inside
there you will find all of the various samples provided. Have a look at a
sample named CSWinFormsAuthTool. This is the base from which I will be
working. What's important here is the fact that it gives you the Facebook.dll
and the Newtonsoft.Json.dll, which we will use in our application.
The second
step is to think of a proper name for your application, and then let Facebook
know that you intend to make a program. Without setting your application up on
Facebook, you will not get an AppID nor an App Secret. You will
need these if you intend to develop your application further inside Visual Studio. We
will be using Visual Studio 2010 for this example. Once you have a funky name,
you will need to go to the Developers section of Facebook. At the bottom of
your Facebook page, there will be a link entitled Developer. Go there.
You may be asked to install the Developer Application as well. Once you
have done that, you will see that Facebook has given you access to
Documentations, Samples, Forums and the Application Directory. Good, we're
halfway there.
Choose to Create
a New App. Once clicked, the screen will look like the following picture:
[NewApp.jpg]
Figure 1: New Facebook Application
It will pop
up a Security Question screen once Continue is clicked. Fill in all the
required information and Submit it. That's it for now. Once you have
submitted the previous screen, you will be brought to your App Information
page. You will notice that your AppID and APP Secret have been generated. Make
note of these as you will need them inside your VB application. Our sample
application ( Notifier )'s information looks like the following :
[AppInfo.jpg]
Figure 2: Facebook Application Info
Feel free to
enter all the required information in this screen. You can also always
edit it afterwards, so do not worry too much about it now.
Now, we have
set up our application, and Facebook knows about it. Let's now design our
application in Visual Studio 2010.
Design
Create a new
VB.NET Windows Forms application in Visual Studio 2010, and give it a name such
as Notifier.
Notifier
consists of 4 Forms; add the forms along with their associated controls and
properties:
Object
|
Property
|
Setting
|
Form
|
Name
|
frmIntro
|
|
FormBorderStyle
|
FixedToolWindow
|
|
ShowInTaskbar
|
False
|
|
Size
|
170,
84
|
|
StartPosition
|
CenterScreen
|
|
Text
|
Notifier
|
Button
|
Name
|
btnFacebookLogin
|
|
Location
|
20,
16
|
|
Size
|
125,
28
|
|
Text
|
Login
|
Form
|
Name
|
frmInfo
|
|
Size
|
702,
482
|
|
StartPosition
|
CenterScreen
|
|
Text
|
Notifier
is loading info, Please be patient
|
Panel
|
Name
|
Panel1
|
|
Dock
|
Bottom
|
|
Location
|
0,
390
|
|
Size
|
694,
58
|
Panel
|
Name
|
Panel2
|
|
Dock
|
Top
|
|
Location
|
0,
0
|
|
Size
|
694,
36
|
Panel
|
Name
|
Panel3
|
|
Dock
|
Fill
|
|
Location
|
0,
36
|
|
Size
|
694,
354
|
Panel
|
Name
|
Panel4
|
|
Dock
|
Top
|
|
Location
|
0,
0
|
|
Size
|
694,
100
|
Panel
|
Name
|
Panel5
|
|
Dock
|
Fill
|
|
Location
|
0,
100
|
|
Size
|
694,
254
|
Label
|
Name
|
lblName
|
|
Autosize
|
True
|
|
Font
|
Microsoft
Sans Serif, 9.75pt, style=Bold
|
|
Location
|
3,
9 Inside Panel1
|
|
Size
|
45,
16
|
|
Text
|
Hello
|
PictureBox
|
Name
|
picProfilePic
|
|
Location
|
3,
6 Inside Panel4
|
|
Size
|
70,
67
|
Label
|
Name
|
Label1
|
|
AutoSize
|
True
|
|
Location
|
79,
6 Inside Panel4
|
|
Text
|
Post
a Message:
|
TextBox
|
Name
|
txtMessage
|
|
Location
|
82,
21 Inside Panel4
|
|
Multiline
|
True
|
|
Size
|
327,
76
|
Button
|
Name
|
btnPostToWall
|
|
Location
|
415,
21 Inside Panel4
|
|
Text
|
Post
to Wall
|
WebBrowser
|
Name
|
wbNotifier
|
|
Dock
|
Fill
|
|
Location
|
0,0
Inside Panel3
|
|
Size
|
694,
254
|
LinkLabel
|
Name
|
lklNotif
|
|
AutoSize
|
True
|
|
Location
|
8,
33 Inside Panel1
|
|
Size
|
113,
13
|
|
TabStop
|
True
|
|
Text
|
No
New &Notification(s)
|
LinkLabel
|
Name
|
lklMess
|
|
AutoSize
|
True
|
|
Location
|
188,
33 Inside Panel1
|
|
Size
|
103,
13
|
|
TabStop
|
True
|
|
Text
|
No
New &Message(s)
|
LinkLabel
|
Name
|
lklFriend
|
|
AutoSize
|
True
|
|
Location
|
358,
33 Inside Panel1
|
|
Size
|
89,
13
|
|
TabStop
|
True
|
|
Text
|
No
New &Friend(s)
|
Button
|
Name
|
btnExit
|
|
Anchor
|
Bottom,
Right
|
|
Location
|
607,
23 Inside Panel1
|
|
Size
|
75,
23
|
|
Text
|
E&xit
|
Timer
|
Name
|
tmrNotifier
|
|
Enabled
|
True
|
|
Interval
|
20000
|
Timer
|
Name
|
tmrError
|
|
Interval
|
5000
|
Form
|
Name
|
frmFBLogin
|
|
FormBorderStyle
|
FixedDialog
|
|
MaximizeBox
|
False
|
|
MinimizeBox
|
False
|
|
ShowInTaskbar
|
False
|
|
Size
|
438,
376
|
|
StartPosition
|
CenterScreen
|
|
Text
|
Notifier
is logging into Facebook
|
WebBrowser
|
Name
|
webBrowser
|
|
Dock
|
Fill
|
Timer
|
Name
|
tmrError
|
|
Enabled
|
True
|
|
Interval
|
1000
|
Timer
|
Name
|
tmrError2
|
|
Interval
|
5000
|
Form
|
Name
|
frmError
|
|
FormBorderStyle
|
FixedToolWindow
|
|
ShowInTaskbar
|
False
|
|
Size
|
388,
120
|
|
StartPosition
|
CenterScreen
|
|
Text
|
There
has been an error.
|
Once
finished and run, your Forms should look more or less like the following:
[frmIntro.jpg]
Figure 3: frmIntro
[frmFBLogin.jpg]
Figure 4: frmFBLogin
[frmInfo.jpg]
Figure 5: frmInfo
[frmError.jpg]
Figure 6: frmError
Code & Explanations
OK, you can
wipe the sweat from your forehead now :). This was indeed a mission. The funny
thing here is, the code will get quite lengthy, so after you have taken a
break, continue with the coding. As I've said, the whole purpose, which you can
probably figure out by looking at the designs, is to get specific notifications
from your Facebook profile - that will be the easy part, the tough part is
getting access to Facebook.
frmIntro
Open frmIntro's
Code Window. Recall earlier that I spoke about a DLL file named facebook.dll,
well, we will need to add it as a Reference now. Click Project, Add
Reference. Select the Browse tab, and navigate to that DLL.
Once the
reference has been added, we need to add its Imports Statement as well:
Imports Facebook
The next
step is creating an AppId variable inside our application. We will
need to supply the ID Facebook gave us. Without giving the AppID, we will
not be able to log in. Then, we need to specify the Permissions for our
program. We need to do this because each permission setting allows us to access
different information. For example, to read messages we need a certain
permission, to read our wall on Facebook, we need a specific permission
setting, and so on.
Private _appId As String = "211959065496840" 'Notifier App ID on FaceBook
'Add Permissions for our app
Private _extendedPermissions As String() = {"user_about_me", "publish_stream", "offline_access", "read_requests", "read_stream", "read_mailbox"}
For a
complete list of available Permissions, and what they give access to, have a
look here. The next two
variables I have created works with our Error Window. Instead of showing
MessageBoxes, I opted to display this window, which is much more customizable
than a MessageBox.
Private blnMessShown As Boolean 'Was the Error shown?
Private NFE As New frmError 'Error Screen
The sub
procedure that makes everything happen, in this case, all the authentication
and authorization, is called DisplayAppropriateMessage, and looks like :
''' Ensures That we Have Successfully Logged into our Facebook account
Private Sub DisplayAppropriateMessage(ByVal facebookOAuthResult As FacebookOAuthResult)
If facebookOAuthResult Is Nothing Then
'User most likely closed the FacebookLoginDialog, so do nothing
Return
End If
If facebookOAuthResult.IsSuccess Then
'We got the access token, Continue
Dim infoDialog = New frmInfo(facebookOAuthResult.AccessToken)
infoDialog.ShowDialog() 'Show Main Screen
Else
'We failed to get the access token. Most likely the user clicked don't allow
'Inform user that there was an Error
If Not blnMessShown Then 'If Error Screen hasn't been shown yet
NFE.Show() 'Show
NFE.lblMess.Text = facebookOAuthResult.ErrorDescription 'Display Error Information
blnMessShown = True 'Set Message Shown to true, so that we don't show it again
tmrError.Enabled = True 'Enable Error Timer
End If
End If
End Sub
What happens
here is, it checks for a successful return from the Facebook authorization
object. Successful would mean that the correct AppId and Login
credentials were supplied. In the event that IsSuccessful is False, it
will mean that either the user didn't supply his correct details, or he / she
chose not to 'Allow' Notifier to get access to his / her settings. Then,
the error screen would appear and disappear 5 seconds later.
The
following two events show how the frmFBLogin form, which provides the
capability to give Notifier access to your Facebook profile, and to exit in the
event of an error.
Private Sub btnFacebookLogin_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFacebookLogin.Click
Dim facebookLoginDialog = New frmFBLogin(_appId, _extendedPermissions) 'frmFBLogin Object
facebookLoginDialog.ShowDialog() 'Show form with appropriate permissions
DisplayAppropriateMessage(facebookLoginDialog.FacebookOAuthResult) 'Get Result
End Sub
Private Sub tmrError_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrError.Tick
If Me IsNot Nothing Then
NFE.Close() 'Close Error Form
Else
Application.Exit() 'Exit
End If
End Sub
That's it
for frmIntro.
frmFBLogin
Add the same
Imports Statement to frmFBLogin:
Imports Facebook
Declare the
following variables:
Private _navigateUri As Uri 'URI object, easy access to parts of a URL
Private blnMessShown As Boolean 'Error Message Shown?
Private NFE As New frmError 'Error Form
_navigateUri is an URI
object. This makes it easier for us to access certain parts of a URL. We
will use this object to get the url of the authorized object. The other two
objects are again used for our error form.
Now, before
we continue, remember how we created the frmFBLogin object on frmIntro? In case
you have forgotten, we did this :
Dim facebookLoginDialog = New frmFBLogin(_appId, _extendedPermissions) 'frmFBLogin Object
Notice
something strange here? OK, the something strange that I am referring to is how
we have used New. Usually with Form objects there are no parameters
inside its constructor, ie, New. We needed to do this because the authorization
and permissions needed to be there, first. If it had been placed inside the
Form Load event, it would not have worked, as the authorization process already
( by that time ), returned unsuccessful.
Open the
Designer file for frmFBLogin, and edit the New constructor to look like
the following:
Public Sub New(ByVal appId As String, ByVal extendedPermissions As String(), ByVal logout As Boolean)
Dim loginParameters As IDictionary(Of String, Object) = New Dictionary(Of String, Object)() From { _
{"response_type", "token"}, _
{"display", "popup"} _
} 'Login with correct parameters
_navigateUri = FacebookOAuthClient.GetLoginUrl(appId, Nothing, extendedPermissions, logout, loginParameters) 'Get Result
InitializeComponent()
End Sub
Public Sub New(ByVal appId As String, ByVal extendedPermissions As String())
Me.New(appId, extendedPermissions, False) 'Supply AppID & Permissions to get authorized
End Sub
Yes, you see
two New Subs. The first one, makes sure that we are allowed to
login, and determines how it should return its result. Inside there we also
obtain the result from the Authorization client. The second New procedure uses
our AppId and Permissions to login to our account. You can find
more information on how Facebook authorizes users here.
Let us now
go back to frmFBLogin.vb. The next thing we add in here is a Property:
''' Facebook authorization result
Public Property FacebookOAuthResult() As FacebookOAuthResult
Get
Return m_FacebookOAuthResult 'IsSuccessful / Not
End Get
Private Set(ByVal value As FacebookOAuthResult)
m_FacebookOAuthResult = value
End Set
End Property
Private m_FacebookOAuthResult As FacebookOAuthResult 'Authorization Object
This makes
it easier for us to determine what the Authorization object will return, and
easier to manage. So now, we can just check the status of m_FacebookOAuthResult.
The rest of frmFBLogin's events looks like:
Private Sub FacebookLoginDialog_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
webBrowser.Navigate(_navigateUri.AbsoluteUri) 'Navigate to appropriate URL, to authorize Notifier
End Sub
Private Sub webBrowser_Navigated(ByVal sender As Object, ByVal e As WebBrowserNavigatedEventArgs) Handles webBrowser.Navigated
Dim oauthResult As FacebookOAuthResult 'Result of Authorization
If FacebookOAuthResult.TryParse(e.Url, oauthResult) Then
Me.FacebookOAuthResult = oauthResult
Me.DialogResult = If(oauthResult.IsSuccess, DialogResult.OK, DialogResult.No) 'Successful Yes, or No
Else
Me.FacebookOAuthResult = Nothing 'If Nothing, then problems with Internet connection etc.
End If
End Sub
Private Sub tmrError_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrError.Tick
Static i As Integer
If Me.Visible Then 'If This form is Visible for more than 10 seconds, something is wrong, it cannot log in
i += 1
If i >= 10 Then
Me.Hide() 'Hide
If Not blnMessShown Then 'Show error form
NFE.Show()
NFE.lblMess.Text = "Cannot Log In, Possibly Due To Bad Internet Connection"
blnMessShown = True
tmrError2.Enabled = True
End If
End If
End If
End Sub
Private Sub tmrError2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrError2.Tick
Application.Exit() 'Exit
End Sub
Inside Load
we navigate to whichever URI was returned. The WebBrowser_Navigated
event is the most important here. It checks if everything is OK, ie, authorized
properly. If it is, it will allow further access to our Facebook profile. Think
of this form as a bridge. This bridge starts at the Login button on
frmIntro, and stops at displaying the information on frmInfo. Without this
bridge, nothing will happen. We need to authenticate the application's ID; we
need to see if it has the correct permissions, we need to see if the person has
a valid Facebook account and is logged on; this is what happens with this form.
The two Timer events are there to determine any errors. In the first timer
event, we make use of a static counter that counts to ten. If it reaches ten,
there was an error. It should not take longer than 10 seconds to
complete the bridging process, if it does, your internet is giving problems.
This I had to put in, because I live in South Africa, and our Internet service
is very bad on occasion.
That's it
for frmFBLogin. We have all the correct info, in order to read your profile's
information. Let us now go to the meat of the program, frmInfo, where we will
display our new Notification messages.
frmInfo
This form
will be our main interface, which the users will work on. This is also
where we will see all our notifications, etc. Add the following two Imports
statements
Imports Facebook
Imports System.Threading 'Dealing with multiple Threads
Add the
following variables:
Private ReadOnly _accessToken As String 'Access Token
'Font Setup
Private strFont As String = "Microsoft Sans Serif"
Private fSize As Single = 8.5F
Private fStyle1 As FontStyle = FontStyle.Regular
Private fStyle2 As FontStyle = FontStyle.Bold
Private blnFriends As Boolean 'Have Friends
Private blnMess As Boolean 'Have Messages
Private blnNotif As Boolean 'Have Notifications
Private WithEvents fb As FacebookClient 'FaceBook Client
'My Facebook details, for example: Name + Picture
Private strMyDetails1() As String
Private strMyDetails2() As String
Private strFriend1() As String 'Friends FQL Result
'Messages FQL Result(s)
Private strMess1() As String
Private strMess2() As String
Private strMess3() As String
'Notifications FQL Result(s)
Private strNotif1() As String
Private strNotif2() As String
'Error Form
Private blnMessShown As Boolean
Private NFE As New frmError
We will do a
lot of string manipulation with these objects, but more on that later. If your
string handling capabilities are a bit rusty, or limited, have a look at this FAQ. I will be doing the
Subs and events as they are displayed in the program's code. Here's an easy one
to start off with:
Private Sub frmInfo_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
btnExit.PerformClick() 'Exit
End Sub
Hmm, do I
really need to explain that? OK, just in case, this exits the application
properly. Now a tricky one:
''' Load Profile Pic and Call GetInfo
Private Sub GraphApiExample()
Try
fb = New FacebookClient(_accessToken) 'Get Facebook Details
Dim result1 As Object = fb.[Get]("/me") 'get MY Details
lblName.Text = "Hello " 'Initialise Name Label
'Get Profile Picture
picProfilePic.LoadAsync(String.Format("https://graph.facebook.com/{0}/picture?type={1}", result1.id, "square"))
GetInfo(_accessToken) 'Retrieve Notifications
Catch ex As FacebookApiException 'Show Error Form
If Not blnMessShown Then
NFE.Show()
NFE.lblMess.Text = ex.Message
blnMessShown = True
tmrError.Enabled = True
End If
End Try
End Sub
This sub, (You
will notice I've kept the same name as in the C# example), is where the whole
data retrieval process starts. The result1 object will get all my details.
Then, we retrieve and display the profile picture, and call the GetInfo sub,
which collects all the information we want. The rest of the code concentrates
on the error form, in the event of an error. Add this next sub.
''' Use FQL to Retrieve Notifications from associated tables
Public Sub GetInfo(ByVal accessToken As String)
Try
fb = New FacebookClient(accessToken) 'Get Details
'Use a Batch Request, instead of 4 different queries
fb.BatchAsync({
New FacebookBatchParameter().Query("SELECT first_name FROM user WHERE uid=me()"),
New FacebookBatchParameter().Query("SELECT uid_from, uid_to FROM friend_request WHERE uid_to=me()"),
New FacebookBatchParameter().Query("SELECT unread_count FROM mailbox_folder WHERE viewer_id=me()"),
New FacebookBatchParameter().Query("SELECT notification_id FROM notification WHERE is_unread = 1 AND recipient_id=me()")})
Catch ex As Exception 'Error
If Not blnMessShown Then
NFE.Show()
NFE.lblMess.Text = ex.Message
blnMessShown = True
tmrError.Enabled = True
End If
End Try
End Sub
In this sub,
we use FQL to get all the appropriate information. We are making use of the
FaceBookBatchParameter object to group all 4 queries into one. This makes
retrieval faster. There are four queries, each getting information from
separate tables, namely: user, friend_request, mailbox_folder and notifcation.
Remember I said that everything is stored in separate tables, at the beginning
of this article? Well, here you can see that, and you can also see which fields
we need to query for.
The next
event:
''' Fires once all details have been retrieved, we must now use it
Private Sub fb_PostCompleted(ByVal sender As Object, ByVal e As FacebookApiEventArgs) Handles fb.PostCompleted
Try
Dim ResultObject As Object = New Generic.Dictionary(Of String, Object) 'Contains ALL Info asked in GetInfo
ResultObject = e.GetResultData 'Get Results and store all of it
'Original string looks like : [{"first_name":"Ockert"}]
strMyDetails1 = ResultObject(0).ToString.Split(":")
strMyDetails2 = strMyDetails1(1).Split("""")
strFriend1 = ResultObject(1).ToString.Split(":")
'Original string looks like :[{"unread_count":5},{"unread_count":0},{"unread_count":26}]
strMess1 = ResultObject(2).ToString.Split(":")
strMess2 = strMess1(2).Split("""")
strMess3 = strMess2(0).Split("}")
strNotif1 = ResultObject(3).ToString.Split(":")
If strNotif1.Length > 1 Then
strNotif2 = strNotif1(1).Split("""")
End If
Catch ex As Exception 'Error
If Not blnMessShown Then
NFE.Show()
NFE.lblMess.Text = ex.Message
blnMessShown = True
tmrError.Enabled = True
End If
End Try
End Sub
Is where we
format the information correctly. All objects queried are stored in one
dictionary object. How it stores it will require us to do string manipulation; in
other words, split the arrays of information continuously until we get the
result we are looking for. Some of the array objects were quite difficult,
especially the Messages. That one took me a while. But, this is precisely why
there are Debugging tools such as Breakpoints, and the Console.WriteLine
methods, which writes information to the Immediate Window. Those are just two
very powerful, yet simple tools to use, to see if you get the correct data.
Many people don't make use of Breakpoints, or, they just conveniently forget
about them.
'''
''' Interval set so high, to give enough time for all info to be read and threads to complete
''' Use manipulated strings and update display
'''
'''
'''
'''
Private Sub tmrNotifier_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrNotifier.Tick
Try
lblName.Text = "Hello " & strMyDetails2(1) 'Name
'if new friend(s)
If strFriend1(0) <> "[]" AndAlso strFriend1(0) <> "" Then
lklFriend.Font = New Font("Microsoft Sans Serif", 8.5, FontStyle.Bold)
lklFriend.Text = "New &Friend(s)"
End If
'If Unread message count is higher than 0
If Val(strMess3(1)) > 0 Then
lklMess.Font = New Font("Microsoft Sans Serif", 8.5, FontStyle.Bold)
lklMess.Text = "New &Messages(s)"
End If
'If new notifications
If strNotif1.Length > 1 Then
If Val(strNotif2(1)) > "0" Then
lklNotif.Font = New Font("Microsoft Sans Serif", 8.5, FontStyle.Bold)
lklNotif.Text = "New &Notification(s)"
End If
End If
tmrNotifier.Enabled = False 'Disable timer
Me.Text = "Notifier"
Catch ex As FacebookApiException 'Error(s)
If Not blnMessShown Then
NFE.Show()
NFE.lblMess.Text = ex.Message
blnMessShown = True
tmrError.Enabled = True
End If
Catch ex2 As Exception
If Not blnMessShown Then
NFE.Show()
NFE.lblMess.Text = ex2.Message
blnMessShown = True
tmrError.Enabled = True
End If
End Try
End Sub
The above
event will be fired only once, as the Timer is disabled after it has done its
work. What work? Well, it updates the display, meaning it changes the
LinkLabels' texts and fonts, and displays my name. The Timer's interval was set
to 20000, because it has to wait until all the data has been retrieved
successfully form the previous subs.
Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExit.Click
Application.Exit() 'Exit
End Sub
Private Sub lklMess_LinkClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles lklMess.LinkClicked
wbNotifier.Navigate("http://www.facebook.com/?sk=inbox") 'Go to inbox
lklMess.Font = New Font("Microsoft Sans Serif", 8.25, FontStyle.Regular) 'Reset Font
lklMess.Text = "No New &Message(s)"
End Sub
Private Sub lklFriend_LinkClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles lklFriend.LinkClicked
wbNotifier.Navigate("http://www.facebook.com/friends/edit/?sk=requests") 'Go to Requests page
lklFriend.Font = New Font("Microsoft Sans Serif", 8.25, FontStyle.Regular)
lklFriend.Text = "No New &Friend(s)"
End Sub
Private Sub lklNotif_LinkClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles lklNotif.LinkClicked
wbNotifier.Navigate("http://www.facebook.com/notifications.php") 'Go to Notifactions page
lklNotif.Font = New Font("Microsoft Sans Serif", 8.25, FontStyle.Regular)
lklNotif.Text = "No New &Notification(s)"
End Sub
Private Sub tmrError_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrError.Tick
If Me IsNot Nothing Then 'Close Error screen if displayed
NFE.Close()
Else
Application.Exit() 'Exit
End If
End Sub
Almost done,
we only have to do two more things. The first would be to edit the
btnPostToWall button, to actually post a message on your profile's wall:
''' Post Message to wall
Private Sub btnPostToWall_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPostToWall.Click
fb = New FacebookClient(_accessToken) 'Get access
Try
fb.Post("/me/feed", New Dictionary(Of String, Object)() From { _
{"message", txtMessage.Text} _
}) 'Use Post to post the message
MessageBox.Show("Message posted successfully")
Exit Sub
Catch ex As Exception 'Error
If Not blnMessShown Then
NFE.Show()
NFE.lblMess.Text = ex.Message
blnMessShown = True
tmrError.Enabled = True
End If
End Try
End Sub
Here we made
use of the Facebook's object's Post method to physically post a message.
The very
last thing we have to do is to open frmInfo's Designer window and edit it's constructor:
Public Sub New(ByVal accessToken As String)
_accessToken = accessToken
InitializeComponent()
GraphApiExample()
End Sub
If you are
still awake, or didn't fall asleep when I covered frmIntro, you will have
noticed we created a frmInfo object like this:
Dim infoDialog = New frmInfo(facebookOAuthResult.AccessToken)
Inside the DisplayAppropriateMessage
sub. We had to do this, because once we have a valid access token, we can
access the information through the querying methods I have shown. Also, if you
have noticed, I never called the GraphApiExample anywhere inside
frmInfo. We call it inside the constructor, so that it can fire immediately,
and not only after the form has been loaded.
Setup Application
Our
application is now 99.99% complete. Yes, it works and you can use it already,
no problem. But, what if you are indeed writing an application for Facebook?
What is the next step? What are the following steps? If you're interested, let
me tell you. We need to create a decent Setup project. The reason for
this is, once your application is approved, people have to download your
application and install it. The installer will bundle all the DLLs into the
Installer, and will also inform the users that .NET Framework 4.0 is needed, if
they do not have it already.
Add a Setup
project to your existing project, and choose whichever settings you want, like
shortcuts on the Desktop, or Programs menu, etc. Once complete, you'll have an
installer that will install everything where the user wants it.
Managing your Facebook
Application
OK, all of
the real programming work is complete. What we have to do now is to submit our
application, Notifier.exe to the Application Directory on Facebook. We
have to do this so that they can see that it is valid and uses the correct
APIs. They do not store your application, it is only necessary for the reason I
mentioned. Now Facebook has a clue as to what your application looks like, or
what its function is. Approval takes about 3 days. Communication from Facebook
is not very good, you may receive an email notifying you that your application
has been approved, or not - as in my case. Help from their side is also almost
completely non-existent. Luckily they have the Developers Forum, which
you can search through, and then there is Google... Once approved, your
Application's profile should be updated, and it will show you the following
screen.
[NotifierSettings.jpg]
Figure 7: Notifier Settings
You can edit
all of your settings as you like. Now, this may come as a surprise to you. It
doesn't automatically give you the Download App button. You have to do
some modifications to your settings first. This I battled with, because there
were no indications on what to do next. As I mentioned, Facebook really needs
to make their Application Submission process better. This is what you should
do. First, you should upload your Installer to a webserver. If you already have
a website, and have FTP access, you could just upload it to wherever you want
on your domain. Remember that address, as you will need to provide that URL as
the Download link inside the App Settings section. Here's a screenhot of
what mine looks like :
[AppSettings.jpg]
Figure 8: App Settings Download URL
That is not
all. What I figured out myself, (Again, Facebook really needs to give
developers more guidelines and tips), was that you have to make your
application a Native App. Do this by clicking Edit underneath App
Information. Select Mobile and Devices, and then select the Native
App radio button. As displayed in the following picture:
[NativeApp.jpg]
Figure 9: Native App
When we go
back to the Application's Profile page, we will now have the Download button.
[Download.jpg]
Figure 10: Download, Finally!
I also find
that getting Information such as total monthly users and so on is quite
difficult. It is not very easy to manage your application, or maybe I'm just a
bit thick. Eventually I figured out that if you go to My Apps, it will
show you how many people like your app, and how many are using it. In my case,
the count is still growing :)
[Statisctics.jpg]
Figure 11: Statistics
Conclusion
That is it.
I sincerely hope you have enjoyed this article, and learned something valuable.
Until next time...
About the Author
Hannes du Preez is a Microsoft
MVP for Visual Basic. He is a trainer at a South African-based company. He is
the co-founder of hmsmp.co.za, a community for South African developers.