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.
Comments
There are no comments yet. Be the first to comment!