هلا برمجنا تويتر Twitter؟

This article is available in English too, check it out here.

Code: Geming.twittoo.msi

المحتويات

محتويات هذا الموضوع:

  • المحتويات
  • مقدمة
  • برمجة Twitter
  • دوال الـ API
    • الدوال البسيطة
    • المدخلات للدوال
    • التوثيق Authentication
  • تويتر والدوت نت
    • الوصول إلى الدوال
    • الدوال والتوثيق
    • الترميز Encoding
    • عناصر البيانات
    • تخزين البيانات
  • المثال، برنامج twittoo
    • الوصف
    • لقطات
    • التصميم
    • تقصير العناوين URL Shortening
    • التحميل
  • خاتمة

مقدمة

درسنا اليوم ليس كأي سابق له، درسنا اليوم يتكلم عن موضوع مميز للغاية وهو كيفية برمجة تويتر Twitter.

هل تستخدم Twitter؟ هل لديك حساب في Twitter؟ هل تريد أن تنشئ برنامج أو موقع إنترنت يقوم بالارتباط مع تويتر Twitter؟ إذا كانت إجابتك بنعم، فحتما سوف تعجبك هذه الصفحات القليلة والتي تتحدث عن تويتر Twitter وكيفية استغلاله برمجيا.

درسنا اليوم ليس مقصورا على Twitter فقط! بل إنه يعلمك أفكار جديدة ومتنوعة منها كيفية التعامل مع بيانات الـ XML، وكيفية التعامل مع دوال ومكاتب الويب Web APIs وغيرها. بجانب هذا سوف نتعرض لفكرة أكثر من رائعة وهي كيفية استخدام خدمات تقصير العناوين URL Shortening مثل http://is.gd وبرمجتها والاستفادة منها.

علاوة على هذا كله، يمكنك تحميل مثال رائع عبارة عن برنامج Desktop بسيط للتعامل مع تويتر Twitter.

بداية وقبل أن نبدأ أحب أن أقدم لك حساب الـ Twitter الخاص بي وهو @elsheimy.

أحب أن أنبه على أن برمجة تويتر Twitter هي موضوع كبير للغاية يحتاج إلى كتاب بأكمله! لهذا فطريقنا في هذا الدرس سوف يكون بشرح الأفكار وإعطاء أمثلة حول الدوال وغيرها، وستترك باقي الدوال للقارئ يبحث فيها باستخدام الشرح الخاص بموقع Twitter.

لن نطيل أكثر، هيا بنا إلى الموضوع.

برمجة Twitter

بداية، يجب عليك معرفة بعض الأشياء قبل الشروع في الكود من أهمها ما هو طقم البرمجة أو Twitter API؟ الـ Twitter API هي عبارة عن مجموعة كبيرة من الدوال كل واحدة فيها لها وظيفتها الخاصة بها.

مثلا، هناك دالة تقوم بإرجاع الـ Tweets الخاصة بالأصدقاء الذين تتبعهم، ودالة ثانية تقوم بإرجاع قائمة بالأصدقاء الذين تتبعهم Following، ودالة ثالثة تقوم بإرجاع الأصدقاء الذين يتبعوك Following. بالإضافة إلى ذلك فهناك دالة لإضافة Status أو كما تسمى Update أو Tweet جديدة، وأخرى لعمل Retweet، وأخرى لعمل Reply، وأخيرة لعمل Direct Message.

ولكن، كيف هي هذه الدوال؟ هل هذه الدوال هي عبارة عن مكتبة Library مثلا نقوم بإرفاقها كمرجع Reference في مشروعنا؟ هل هذه الدوال هي عبارة عن خدمة ويب Web Service أو خدمة WCF Service؟ لا هذا ولا ذاك! دوال الـ Twitter ببساطة عبارة عن عناوين إنترنت Web Addresses أو نقاط وصول Endpoints. كيف هذا؟

نأخذ مثلا مثال، هناك الدالة statuses/public timeline method مثلا والتي تقوم بإرجاع آخر تحديثات Updates (أو Tweets) بطريقة عشاوئية، فهذه الدالة لديها العنوان http://api.twitter.com/1/statuses/public_timeline.xml، فنلاحظ أنه يمكنك نسخ هذا العنوان ووضعه في المتصفح الخاص بك ومشاهدة النتائج والتي هي عبارة عن بيانات XML.

ولكن كيف نتعامل مع هذه الدوال من خلال الكود؟ يمكننا من خلال الأنواع Classes الموجودة في الـ Namespace المسماة System.Net بأن نقوم بعمل طلب Request على الدالة (عن طريق عنوانها) ونحصل على الإجابة Response المطلوبة والتي هي عبارة عن بيانات XML أيضا. وبعد حصولنا على هذه البيانات يمكننا معالجتها عن طريق الـ Classes الموجودة في System.Xml كي نستطيع عرضها بالشكل المناسب في موقعنا.

كما ذكرنا، سيكون عمدتنا في هذا الموضوع بإذن الله هو بوابة برمجة تويتر http://apiwiki.twitter.com، سوف نتكلم عن بعض الدوال وستترك باقيها للقارئ يبحث عنها في الموقع.

دوال الـ API

هنا سوف نأخذ جولة سريعة في طقم البرمجة لـ Twitter وسوف نستعرض بعض من أهم الدوال لـ API.

الدوال البسيطة

الدالة الأولى معنا وهي دالة الـ Public Timeline وهي دالة بسيطة أي أنها لا تحتاج إلى توثيق للمستخدم Authentication (أي لا تحتاج إلى اسم الحساب وكلمة المرور) وأيضا لا تحتاج إلى أي مدخلات Arguments.

تقوم هذه الدالة statuses/public timeline method بإرجاع أحدث 20 تحديث Tweet (أو Update) من مستخدمين تويتر بطريقة عشوائية. عنوان هذه الدالة هو http://api.twitter.com/1/statuses/public_timeline.xml. إذا قمت بنسخ هذا العنوان ولصقه في المتصفح الخاص بك سوف تحصل على نتيجة مشابهة للنتيجة التالية:

<?xml version="1.0" encoding="UTF-8"?>
<statuses type="array">
    <status>
        <created_at>Wed Apr 14 19:32:07 +0000 2010</created_at>
        <id>12179999634</id>
        <text>35 Ingenious Examples of Footwear - http://su.pr/1JxMAr</text>
        <source><a href="http://apiwiki.twitter.com/" rel="nofollow">API</a></source>
        <truncated>false</truncated>
        <in_reply_to_status_id></in_reply_to_status_id>
        <in_reply_to_user_id></in_reply_to_user_id>
        <favorited>false</favorited>
        <in_reply_to_screen_name></in_reply_to_screen_name>
        <user>
            <id>15736190</id>
            <name>Smashing Magazine</name>
            <screen_name>smashingmag</screen_name>
            <location>Freiburg, Germany</location>
            <description>Vitaly Friedman, editor-in-chief of SmashingMagazine.com and Noupe.com, online magazines dedicated to designers and developers.</description>
            <profile_image_url>http://a3.twimg.com/profile_images/572829723/original_normal.jpg</profile_image_url>
            <url>http://www.smashingmagazine.com</url>
            <protected>false</protected>
            <followers_count>166019</followers_count>
            <profile_background_color>B2DFDA</profile_background_color>
            <profile_text_color>333333</profile_text_color>
            <profile_link_color>f51616</profile_link_color>
            <profile_sidebar_fill_color>ffffff</profile_sidebar_fill_color>
            <profile_sidebar_border_color>eeeeee</profile_sidebar_border_color>
            <friends_count>394</friends_count>
            <created_at>Tue Aug 05 14:00:40 +0000 2008</created_at>
            <favourites_count>4</favourites_count>
            <utc_offset>-10800</utc_offset>
            <time_zone>Greenland</time_zone>
            <profile_background_image_url>http://s.twimg.com/a/1271213136/images/themes/theme13/bg.gif</profile_background_image_url>
            <profile_background_tile>true</profile_background_tile>
            <notifications>false</notifications>
            <geo_enabled>true</geo_enabled>
            <verified>false</verified>
            <following>false</following>
            <statuses_count>8703</statuses_count>
            <lang>en</lang>
            <contributors_enabled>false</contributors_enabled>
        </user>
        <geo />
        <coordinates />
        <place />
        <contributors />
    </status>
    . . .
</statuses>

نلاحظ أن النتيجة هي عبارة عن بيانات XML. ونلاحظ أيضا أن هذه البيانات لها تركيب معين، والجميل في تويترTwitter هو أنه هناك نظام وتركيب معين XML Schema ينطبق على جميع البيانات من نفس النوع. فهذه البيانات هي عبارة عن قائمة من التحديثات Statuses، فبالتالي أي قائمة من التحديثات مثل تحديثات الأصدقاء لمستخدم معين أو تحديثات هذا المستخدم نفسه سوف يكون لها نفس النظام والتركيب Schema.

المدخلات للدوال

بعض الدوال تحتاج إلى مدخلات. من هذه الدوال دالة users/show method وهي تقوم بإرجاع التحديثات الخاصة بمستخدم معين. وهذه الدالة لديها العنوان http://api.twitter.com/1/users/show.xml وهي تطلب إما تحديد الكود المعرف ID الخاص بالمستخدم المطلوب وإما تحديد اسم الظهور للمستخدم Screen Name.

إذا فعندما تريد الحصول على تحديثات من المستخدم @elsheimy، فإنك تقوم النداء على هذه الدالة بواحدة من أربعة طرق:

فتكون النتيجة لهذه الدالة هي بيانات XML مطابقة تماما لما يظهر لك إذا ذهبت إلى صفحة المستخدم مثلا http://twitter.com/elsheimy.

<?xml version="1.0" encoding="UTF-8"?>
<user>
    <id>19645411</id>
    <name>Mohammad Elsheimy</name>
    <screen_name>Elsheimy</screen_name>
    <location>KB, Egypt</location>
    <description>Technology evangelist from Egypt born in 1991</description>
    <profile_image_url>http://a1.twimg.com/profile_images/833061500/02-19-2010__0__-_Small_normal.jpg</profile_image_url>
    <url>http://justlikeamagic.com</url>
    <protected>false</protected>
    <followers_count>278</followers_count>
    <profile_background_color>DBE9ED</profile_background_color>
    <profile_text_color>333333</profile_text_color>
    <profile_link_color>CC3366</profile_link_color>
    <profile_sidebar_fill_color>E6F6F9</profile_sidebar_fill_color>
    <profile_sidebar_border_color>DBE9ED</profile_sidebar_border_color>
    <friends_count>179</friends_count>
    <created_at>Wed Jan 28 10:47:36 +0000 2009</created_at>
    <favourites_count>7</favourites_count>
    <utc_offset>7200</utc_offset>
    <time_zone>Cairo</time_zone>
    <profile_background_image_url>http://s.twimg.com/a/1271811071/images/themes/theme17/bg.gif</profile_background_image_url>
    <profile_background_tile>false</profile_background_tile>
    <notifications></notifications>
    <geo_enabled>true</geo_enabled>
    <verified>false</verified>
    <following></following>
    <statuses_count>1877</statuses_count>
    <lang>en</lang>
    <contributors_enabled>false</contributors_enabled>
    <status>
        <created_at>Wed Apr 21 16:21:46 +0000 2010</created_at>
        <id>12585240751</id>
        <text>I'm reading this, it's really hot: #RFC 2616 - Hypertext Transfer Protocol -- #HTTP /1.1 http://bit.ly/b1353K #tech #www</text>
        <source><a href="http://bit.ly" rel="nofollow">bit.ly</a></source>
        <truncated>false</truncated>
        <in_reply_to_status_id></in_reply_to_status_id>
        <in_reply_to_user_id></in_reply_to_user_id>
        <favorited>false</favorited>
        <in_reply_to_screen_name></in_reply_to_screen_name>
        <geo/>
        <coordinates/>
        <place/>
        <contributors/>
    </status>
</user>

نلاحظ أن هذه البيانات لها نفس التركيب Schema مثل سابقتها.

التوثيق Authentication

بعض الدوال تحتاج إلى عملية توثيق Authentication للمستخدم. فمثلا، الدوال التي تعرض التحديثات Statuses الخاصة بأصدقاء هذا المستخدم تحتاج إلى إدخال اسم المستخدم وكلمة المرور كي يتسنى له مشاهدة البيانات.

فالقاعدة هي كالآتي: البيانات التي لا يسمح لك بمشاهدتها في موقع http://Twitter.com قبل عملية الدخول Sign in هي التي تحتاج دوالها إلى توثيق Authentication، فعملية التوثيق هي بمثابة عملية الدخول Sign in.

هناك نوعين من التوثيق:

  • التوثيق البسيط Basic Authentication:
    وفيها نقوم بإرفاق البيانات المطلوبة (اسم المستخدم وكلمة المرور) في كل عملية نداء Request لأي دالة. هذه الطريقة هي الأسهل وللأسف أعلن Twitter أنها سوف تمنع في وقت لاحق. سوف نستخدم هذا النوع في درسنا.
  • توثيق OAuth:
    وهي عملية أكثر تعقيدا، وتتطلب موضوع بأكلمه، لذلك لن نستخدمها في درس اليوم وسوف نقوم بشرحها في درس آخر بإذن الله تعالى. وهذه العملية تعتمد على قيام المبرمج بتسجيل برنامجه في Twitter والحصول على بيانات خاصة به.

من الدوال التي تحتاج إلى توثيق دالة statuses/friends timeline method وهي التي تقوم بإرجاع التحديثات الخاصة بأصدقاء المستخدم. وهذه الدالة لها العنوان http://api.twitter.com/1/statuses/friends_timeline.xml. عند قيامك بالذهاب إلى هذا العنوان في متصفحك، سوف تظهر أمامك شاشة صغيرة خاصة بالمتصفح مسؤولة عن عملية التوثيق، وهذه الشاشة تكون مشابهة للشاشة التالية:

شكل 1 - شاشة توثيق برنامج Internet Explorer

فقط عند إدخالك لإسم مستخدم وكلمة مرور صحيحين سوف تحصل على البيانات المطلوبة.

من الدوال الأخرى الجميلة جدا دالة direct_messages/new method وهي تقوم بإرسال رسالة شخصية Direct Message من المستخدم الموثق إلى مستخدم آخر. وهذه الدالة تأخذ مدخلين، كود ID المستخدم أو اسم ظهوره Screen Name، ونص الرسالة والذي لا يزيد عن 140 حرف.

فعلى سبيل المثال يمكنك إرسال الرسالة “hi, how is it going” إلى المستخدم @elsheimy عن طريق أيا من الطريقتين:

نلاحظ أنه هناك حروف وعلامات مثل المسافة وعلامة الاستفهام (؟) لا يمكنها الظهور في عناوين الإنترنت ولهذا فإنه يستعاض عنها بالرمز الخاص بها، مثلا المسافة تساوي %20 لأ الكود الستعشري Hexadecimal الخاص بها هو 20. سوف نتعلم في هذا الدرس كيفية عمل Encoding للنصوص لتصبح قابلة للتداول في عناوين الإنترنت.

إذا نجحت هذه العملية فإنها تقوم بإرجاع بيانات XML مشابهة للتالية:

<?xml version="1.0" encoding="UTF-8"?>
<direct_message>
    <id>88619848</id>
    <sender_id>1401881</sender_id>
    <text>all your bases are belong to us.</text>
    <recipient_id>7004322</recipient_id>
    <created_at>Wed Apr 08 20:30:04 +0000 2009</created_at>
    <sender_screen_name>dougw</sender_screen_name>
    <recipient_screen_name>igudo</recipient_screen_name>
    <sender>
        <id>1401881</id>
        <name>Doug Williams</name>
        <screen_name>dougw</screen_name>
        <location>San Francisco, CA</location>
        <description>Twitter API Support. Internet, greed, users, dougw and opportunities are my passions.</description>
        <profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/59648642/avatar_normal.png</profile_image_url>
        <url>http://www.igudo.com</url>
        <protected>false</protected>
        <followers_count>1036</followers_count>
        <profile_background_color>9ae4e8</profile_background_color>
        <profile_text_color>000000</profile_text_color>
        <profile_link_color>0000ff</profile_link_color>
        <profile_sidebar_fill_color>e0ff92</profile_sidebar_fill_color>
        <profile_sidebar_border_color>87bc44</profile_sidebar_border_color>
        <friends_count>290</friends_count>
        <created_at>Sun Mar 18 06:42:26 +0000 2007</created_at>
        <favourites_count>0</favourites_count>
        <utc_offset>-18000</utc_offset>
        <time_zone>Eastern Time (US & Canada)</time_zone>
        <profile_background_image_url>http://s3.amazonaws.com/twitter_production/profile_background_images/2752608/twitter_bg_grass.jpg</profile_background_image_url>
        <profile_background_tile>false</profile_background_tile>
        <statuses_count>3394</statuses_count>
        <notifications>false</notifications>
        <following>false</following>
        <verified>true</verified>
    </sender>
    <recipient>
        <id>7004322</id>
        <name>Doug Williams</name>
        <screen_name>igudo</screen_name>
        <location>North Carolina</location>
        <description>A character.</description>
        <profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/15446222/twitter_48_48_normal.jpg</profile_image_url>
        <url>http://www.igudo.com</url>
        <protected>false</protected>
        <followers_count>19</followers_count>
        <profile_background_color>69A1AA</profile_background_color>
        <profile_text_color>000000</profile_text_color>
        <profile_link_color>F00</profile_link_color>
        <profile_sidebar_fill_color>ACBEC1</profile_sidebar_fill_color>
        <profile_sidebar_border_color>8A8F85</profile_sidebar_border_color>
        <friends_count>3</friends_count>
        <created_at>Thu Jun 21 21:16:21 +0000 2007</created_at>
        <favourites_count>0</favourites_count>
        <utc_offset>-18000</utc_offset>
        <time_zone>Eastern Time (US & Canada)</time_zone>
        <profile_background_image_url>http://static.twitter.com/images/themes/theme1/bg.gif</profile_background_image_url>
        <profile_background_tile>false</profile_background_tile>
        <statuses_count>382</statuses_count>
        <notifications>false</notifications>
        <following>true</following>
        <verified>true</verified>
    </recipient>
</direct_message>

تويتر والدوت نت

الوصول إلى الدوال

كي يمكنك النداء على أي دالة ستحتاج إلى عمل طلب Request إلى هذه الدالة وانتظار الجواب Response أو النتيجة من هذه الدالة. ويمكنك عمل هذا عن طريق العناصر Classes الموجود في الـ Namespace المسمى System.Net وبالتحديد العنصرين WebRequest و WebResponse.

الكود التالي يوضح كيفية الوصول إلى دالة بسيطة والنداء عليها:

// C# Code
public static Main()
{
    GetResponse("http://api.twitter.com/1/statuses/public_timeline.xml");
}
public static XmlDocument GetResponse(string uri)
{
    WebRequest req = WebRequest.Create(new Uri(uri));
    XmlDocument doc = new XmlDocument();
    doc.Load(req.GetResponse().GetResponseStream());
    return doc;
}
' VB.NET Code
Sub Main()
    GetResponse("http://api.twitter.com/1/statuses/public_timeline.xml")
End Sub
Public Function GetResponse(ByVal uri As String) As XmlDocument
    Dim req As WebRequest = WebRequest.Create(New Uri(uri))
    Dim doc As New XmlDocument()
    doc.Load(req.GetResponse().GetResponseStream())
    Return doc
End Function

نلاحظ أن الكود قام باستخدام العنصر System.Xml.XmlDocument والذي يمكننا من معالجة بيانات الـ XML بسهولة.

الدوال والتوثيق

الكود التالي يوضح كيفية النداء على الدالة statuses/update method والتي تقوم بإرسال تحديث أو Tweet جديد عن طريق المستخدم المحدد. نلاحظ أن الكود استخدم التوثيق البسيط Basic Authentication.

// C# Code
public static void Main()
{
    GetResponse("http://api.twitter.com/1/statuses/update.xml?status=hello%20from%20the%20API", "elsheimy", "b@zzword", true);
}
public static XmlDocument GetResponse(string uri, string username, string password, bool post)
{
    WebRequest req = WebRequest.Create(new Uri(uri));
    if (post)
        req.Method = "POST";
    if ((username != null) && (username.Trim() != String.Empty) && (!String.IsNullOrEmpty(password)))
        req.Credentials = new NetworkCredential(username.Trim(), password);
    XmlDocument doc = new XmlDocument();
    doc.Load(req.GetResponse().GetResponseStream());
    return doc;
}
' VB.NET Code
Sub Main()
    GetResponse("http://api.twitter.com/1/statuses/update.xml?status=hello%20from%20the%20API", "elsheimy", "b@zzword", True)
End Sub
Public Function GetResponse(ByVal uri As String, ByVal username As String, ByVal password As String, ByVal post As Boolean) As XmlDocument
    Dim req As WebRequest = WebRequest.Create(New Uri(uri))
    If (post) Then
        req.Method = "POST"
    End If
    If ((username <> Nothing) And (username.Trim() <> String.Empty) And (Not String.IsNullOrEmpty(password))) Then
        req.Credentials = New NetworkCredential(username.Trim(), password)
    End If
    Dim doc As XmlDocument = New XmlDocument()
    doc.Load(req.GetResponse().GetResponseStream())
    Return doc
End Function

الترميز Encoding

كما ذكرنا سابقا، فإن هناك حروف يجب أن لا تظهر في المدخلات للدوال مثل المسافات وعلامات الاستفهامات وغيرها. وهذه الحروف يجب استبدالها بالتمثيل الستعشري Hexadecimal لأكوادها مسبوقة بعلامة النسبة المئوية %.

الكلاس التالي تقوم بتوضيح عملية الترميز Encoding. الكود لعلمية التوضيح فقط، فنحن لا نحتاج إلى تسجيل كل حرف بمقابله.

// C# Code
public static class UrlEncoder
{
private static string[,] _chars = new string[,]
        {
        { "%", "%25" },     // this is the first one
        { "$" , "%24" },
        { "&", "%26" },
        { "+", "%2B" },
        { ",", "%2C" },
        { "/", "%2F" },
        { ":", "%3A" },
        { ";", "%3B" },
        { "=", "%3D" },
        { "?", "%3F" },
        { "@", "%40" },
        { " ", "%20" },
        { "\"" , "%22" },
        { "<", "%3C" },
        { ">", "%3E" },
        { "#", "%23" },
        { "{", "%7B" },
        { "}", "%7D" },
        { "|", "%7C" },
        { "\\", "%5C" },
        { "^", "%5E" },
        { "~", "%7E" },
        { "[", "%5B" },
        { "]", "%5D" },
        { "`", "%60" } };
public static string EncodeUrl(string url)
{
    for (int i = 0; i < _chars.GetUpperBound(0); i++)
        url = url.Replace(_chars[i, 0], _chars[i, 1]);
    return url;
}
public static string DecodeUrl(string url)
{
    for (int i = 0; i < _chars.GetUpperBound(0); i++)
        url = url.Replace(_chars[i, 1], _chars[i, 0]);
    return url;
}
' VB.NET Code
Public Module UrlEncoder
    Private _chars(,) As String = _
        { _
        {"%", "%25"}, _
        {"$", "%24"}, _
        {"&", "%26"}, _
        {"+", "%2B"}, _
        {",", "%2C"}, _
        {"/", "%2F"}, _
        {":", "%3A"}, _
        {";", "%3B"}, _
        {"=", "%3D"}, _
        {"?", "%3F"}, _
        {"@", "%40"}, _
        {" ", "%20"}, _
        {"\", "%22"}, _
        {"<", "%3C"}, _
        {">", "%3E"}, _
        {"#", "%23"}, _
        {"{", "%7B"}, _
        {"}", "%7D"}, _
        {"|", "%7C"}, _
        {"\", "%5C"}, _
        {"^", "%5E"}, _
        {"~", "%7E"}, _
        {"[", "%5B"}, _
        {"]", "%5D"}, _
        {"'", "%60"}}
    Public Function EncodeUrl(ByVal url As String) As String
        For i As Integer = 0 To _chars.GetUpperBound(0) - 1
            url = url.Replace(_chars(i, 0), _chars(i, 1))
        Next
        Return url
    End Function
    Public Function DecodeUrl(ByVal url As String) As String
        For i As Integer = 0 To _chars.GetUpperBound(0) - 1
            url = url.Replace(_chars(i, 1), _chars(i, 0))
        Next
        Return url
    End Function
End Module

الآن يمكننا استخدام هذا الكود لتغيير الحالة المستخدم Status:

// C# Code
public static void Main()
{
    string uri;
    string text = UrlEncoder.EncodeUrl("hello from the API");
    uri = "http://api.twitter.com/1/statuses/update.xml?status=" + text;
    GetResponse(uri, "elsheimy", "b@zzwrd", true);
}
' VB.NET Code
Public Sub Main()
    Dim uri As String
    Dim text As String = UrlEncoder.EncodeUrl("hello from the API")
    uri = "http://api.twitter.com/1/statuses/update.xml?status=" & text
    GetResponse(uri, "elsheimy", "b@zzwrd", True)
End Sub

عناصر البيانات

ماذا بعد حصولنا على بيانات XML كيف سنقوم بتخزينها؟ يمكننا ذلك عن طريق استخدام عناصر Classes تحوي البيانات المطلوبة وهذه العناصر، نظريا، تسمى عناصر البيانات أو Business Objects.

الكود التالي هو عبارة عن ثلاثة أنواع Classes تمثل الثلاثة عناصر التي نريدها وهي المستخدم والحالة والرسالة:

// C# Code
public structure TwitterUser
{
    public long ID;
    public string Name;
    public string ScreenName;
    public string Location;
    public string Description;
    public string ProfileImage;
    public string Url;
    public bool IsProtected;
    public long FollowersCount;
    public long FriendsCount;
    public string CreatedAt;
    public long FavoritesCount;
    public bool Verified;
    public bool Following;
    public long StatusCount;
}
public structure TwitterStatus
{
    public string CreatedAt;
    public long ID;
    public string Text;
    public string Source;
    public bool Truncated;
    public long InReplyToStatusID;
    public long InReplyToUserID;
    public bool Favorited;
    public string InReplyToScreenName;
    public TwitterUser User;
}
public structure TwitterMessage
{
    public long ID;
    public long SenderID;
    public long SenderScreenName;
    public long RecipientID;
    public long RecipientScreenName;
    public string Text;
    public string CreatedAt;
    public TwitterUser Sender;
    public TwitterUser Recipient;
}
' VB.NET Code
Public Structure TwitterUser
    Public ID As Long
    Public Name As String
    Public ScreenName As String
    Public Location As String
    Public Description As String
    Public ProfileImage As String
    Public Url As String
    Public IsProtected As Boolean
    Public FollowersCount As Long
    Public FriendsCount As Long
    Public CreatedAt As String
    Public FavoritesCount As Long
    Public Verified As Boolean
    Public Following As Boolean
    Public StatusCount As Long
End Structure
Public Structure TwitterStatus
    Public CreatedAt As String
    Public ID As Long
    Public Text As String
    Public Source As String
    Public Truncated As Boolean
    Public InReplyToStatusID As Long
    Public InReplyToUserID As Long
    Public Favorited As Boolean
    Public InReplyToScreenName As String
    Public User As TwitterUser
End Structure
Public Structure TwitterMessage
    Public ID As Long
    Public SenderID As Long
    Public SenderScreenName As Long
    Public RecipientID As Long
    Public RecipientScreenName As Long
    Public Text As String
    Public CreatedAt As String
    Public Sender As TwitterUser
    Public Recipient As TwitterUser
End Structure

تخزين البيانات

بعد أن قمنا باسترجاع البيانات الـ XML وبعد أن قمنا بتجهيز العناصر Classes التي ستحويها، يأتي الدور الآن على تحويل هذه البيانات إلى قائمة من هذه العناصر كي يتنسى لنا استخدامها في برنامجنا بسهولة.

الكود التالي يقوم باسترجاع التحديثات Statuses الخاصة بأصدقاء المستخدم ويحولها إلى قائمة من العنصر TwitterStatus. لاحظ الكود (الكود مختصر للإفادة):

// C# Code
public static void Main()
{
    GetStatuses("elsheimy", "b@zzword");
}
public static List<TwitterStatus> GetStatuses(string username, string password)
{
    XmlNode node = GetResponse("http://api.twitter.com/1/statuses/friends_timeline.xml",
        username, password, true);
    List<TwitterStatus> lst = new List<TwitterStatus>(node.ChildNodes.Count);
    foreach (XmlNode nd in node.ChildNodes)   // for each status
        lst.Add(HandleStatus(nd));
    return lst;
}
public static TwitterStatus HandleStatus(XmlNode nd)
{
    // HandleNumber, FormatText, HandleBool
    // are just functions that converts strings
    // to numbers, decoded strings, and bool
    TwitterStatus status = new TwitterStatus(
        nd["created_at"].InnerText,
        HandleNumber(nd["id"]),
        FormatText(nd["text"]),
        FormatText(nd["source"]),
        HandleBool(nd["truncated"]),
        HandleNumber(nd["in_reply_to_status_id"]),
        HandleNumber(nd["in_reply_to_user_id"]),
        HandleBool(nd["favorited"]),
        FormatText(nd["in_reply_to_screen_name"]),
        HandleUser(nd["user"]));
    return status;
}
public static TwitterUser HandleUser(XmlNode nd)
{
    // HandleNumber, FormatText, HandleBool
    // are just functions that converts strings
    // to numbers, decoded strings, and bool
    long id = HandleNumber(nd["id"]);
    TwitterUser user;
    user = new TwitterUser(
        id,
        FormatText(nd["name"]),
        FormatText(nd["screen_name"]),
        FormatText(nd["location"]),
        FormatText(nd["description"]),
        nd["profile_image_url"].InnerText,
        nd["url"].InnerText,
        HandleBool(nd["protected"]),
        HandleNumber(nd["followers_count"]),
        HandleNumber(nd["friends_count"]),
        nd["created_at"].InnerText,
        HandleNumber(nd["favourites_count"]),
        HandleBool(nd["verified"]),
        HandleBool(nd["following"]),
        HandleNumber(nd["statuses_count"]));
    return user;
}
' VB.NET Code
Sub Main()
    GetStatuses("elsheimy", "b@zzword")
End Sub
Public Function GetStatuses(ByVal username As String, ByVal password As String) As List(Of TwitterStatus)
    Dim node As XmlNode = GetResponse("http://api.twitter.com/1/statuses/friends_timeline.xml", username, password, True)
    Dim lst As New List(Of TwitterStatus)(node.ChildNodes.Count)
    For Each nd As XmlNode In node.ChildNodes
        lst.Add(HandleStatus(nd))
    Next
    Return lst
End Function
Public Function HandleStatus(ByVal nd As XmlNode) As TwitterStatus
    ' HandleNumber, FormatText, HandleBool
    ' are just functions that converts strings
    ' to numbers, decoded strings, and bool
    Dim status As New TwitterStatus( _
            nd("created_at").InnerText, _
            HandleNumber(nd("id")), _
            FormatText(nd("text")), _
            FormatText(nd("source")), _
            HandleBool(nd("truncated")), _
            HandleNumber(nd("in_reply_to_status_id")), _
            HandleNumber(nd("in_reply_to_user_id")), _
            HandleBool(nd("favorited")), _
            FormatText(nd("in_reply_to_screen_name")), _
            HandleUser(nd("user")))
    Return status
End Function
Public Function HandleUser(ByVal nd As XmlNode) As TwitterUser
    ' HandleNumber, FormatText, HandleBool
    ' are just functions that converts strings
    ' to numbers, decoded strings, and bool
    Dim id As Long = HandleNumber(nd("id"))
    Dim user As New TwitterUser( _
        id, _
        FormatText(nd("name")), _
        FormatText(nd("screen_name")), _
        FormatText(nd("location")), _
        FormatText(nd("description")), _
        nd("profile_image_url").InnerText, _
        nd("url").InnerText, _
        HandleBool(nd("protected")), _
        HandleNumber(nd("followers_count")), _
        HandleNumber(nd("friends_count")), _
        nd("created_at").InnerText, _
        HandleNumber(nd("favourites_count")), _
        HandleBool(nd("verified")), _
        HandleBool(nd("following")), _
        HandleNumber(nd("statuses_count")))
    Return user
End Function

المثال، برنامج twittoo

الوصف

وإلى النقطة الأكثر إثارة في موضوعنا، وهي المثال. مثالنا عبارة عن برنامج بسيط اسمه twittoo تستطيع من خلاله تصفح التحديثات Tweets وكذلك إضافة تحديثات أخرى، وتصفح الرسائل، والأصدقاء وغيرها.

لقطات

وهذه لقطات من البرنامج:

شكل 2 - twittoo 1

شكل 3 - twitto 2

شكل 4 - twitto 3

شكل 5 - twitto 4

شكل 6 - twitto 5

شكل 7 - twitto 6

تم تطوير المثال باستخدام تقنية C# و WinForms.

التصميم

واجهة البرنامج بسيطة جدا لا تعتمد على أي أدوات Controls خارجية، جميع الأدوات هي أدوات الويندوز المعروفة. قمنا باستخدام الأداة System.Windows.Forms.TableLayoutPanel لعرض الحالات Statuses وكذلك الرسائل Direct Messages، لاحظ الشكل التالي.

شكل 8 - تصميم الحالة Status

تقصير العناوين URL Shortening

يتيح لك البرنامج تقصير أي عنوان إنترنت URL Shortening عن طريق خدمة http://is.gd وهذه الخدمة لها نظام API مشابه إلى حد كبير نظام التويتر. الكود التالي عبارة عن دالة تقوم بعمل تفصير لأي عنوان URL Shortening:

// C# Code
public static string Shorten(string url)
{
    if (!System.Text.RegularExpressions.Regex.IsMatch
        (url, @"(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&;:/~\+#]*[\w\-\@?^=%&;/~\+#])?"))
        throw new FormatException("The URL you specificed is not in the current format.");
    url = Uri.EscapeUriString(url);
    string reqUri = String.Format(@"http://is.gd/api.php?longurl={0}", url);
    WebRequest req = WebRequest.Create(reqUri);
    req.Timeout = 5000;
    using (System.IO.StreamReader reader =
        new System.IO.StreamReader(req.GetResponse().GetResponseStream()))
    {
        return reader.ReadLine();
    }
}
' VB.NET
Public Function Shorten(ByVal url As String) As String
    If (Not System.Text.RegularExpressions.Regex.IsMatch _
        (url, "(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&;:/~\+#]*[\w\-\@?^=%&;/~\+#])?")) Then
        Throw New FormatException("The URL you specificed is not in the current format.")
    End If
    url = Uri.EscapeUriString(url)
    Dim reqUri As String = String.Format("http://is.gd/api.php?longurl={0}", url)
    Dim req As WebRequest = WebRequest.Create(reqUri)
    req.Timeout = 5000
    Dim reader As New System.IO.StreamReader(req.GetResponse().GetResponseStream())
    url = reader.ReadLine()
    reader.Close()
    Return url
End Function

التحميل

حمل البرنامج من هنا

خاتمة

وأخيرا، أرجو أن أكون وفقت في عرض الموضوع، وعذرا على الإطالة، وأتمنى أن تشاركنوا بآرائكم واقتراحاتكم.

مواضيع مشابهة:

اخترنا لك:

أحدث المواضيع:

هل أعجبتك؟ شارك بها...
  • abdullah

    ما شاء الله عليك
    الله يوفقك يا محمد

    عبدالله القحطاني

    • شكرا على مروركم الكريم

      • شكرا استاذ محمد عمل رائع وانا من المتابعين لك منذ فتره
        ولكن هل لاحظت مشكلة الترميز والكتابة باللغه العربية حيث ان تويتر لا يسمح لك بكتابة 140 حرف ( عربي )

  • abdullah

    ما شاء الله عليك
    الله يوفقك يا محمد

    عبدالله القحطاني

  • Pingback: Creating a Simple Twitter Client Application | Just Like a Magic()

  • مقالة رائعة، أفادتني كثيراً في عمل برنامج فيجوال بيسك سكربت بسيط.
    أتمني أن أري مقالات مشابهة تتحدث عن الآي بي آي بالعربية

    بالتوفيق =)

  • شكرا جزيلا شكرا لمشاركتك معنا

    هل لديك أي اقتراحات للموقع، مقالات، أفكار، إلخ؟

  • :) جميل جدًا
    لقد سبقتني , فقد كنت أود كتابة درس عن هذا الموضوع وعمل تطبيق جاهز
    ولكن أنت مبدع , شكرًا لك أخي الحبيب

    • لست مبدعا إطلاقا، بل أنت المبدع. شكرا لك أخي الكريم لمشاركتك معنا. بالتأكيد عند كتابتك لنفس الموضوع سوف يكون أفضل مني بملايين المرات، أنا متأكد من ذلك. :)

  • غير معروف

    جهد رائع ومشكور

    للأسف الشديد تويتر منع التوثيق البسيط

    واعتبرني من اليوم متابع دائم لك ولمدونتك الرائعة

    • بداية أتشرف بمتابعة حضرتك لينا، ويا رب دايما نكون عند حسن ظنك.

      فعلا، تويتر منع التوثيق البسيط أعلن عنه بعد فترة من نشر المقالة وبدأ في استخدام الأوأوث OAuth وبالفعل فيه خطة لتعديل الموضوع ليشمل توثيق الأوأوث، وسوف يتم نشر الموضوع الأحدث قريبا بإذن الله تعالى.

      شكرا على مروركم.

  • Pingback: مدونة شمس - تويتر()

  • Mohamed Osman

    برافو محمد ، درس كتير حلو و إستفدت منه كتير

  • Waseem_khalel

    السلام عليكم

    ما شاء الله درس رائع و كنت أبحث عنه في جووجل و الحمد لله وجدته .. 

    لكن هل هناك مصادر أخرى أو دروس أخرى يمكن أن تنصح بها جزاك الله خير

    أبحث عن برمجة تويتر لموقع بواسطة الPHP 

    يا ريت لو تقدر تساعدني بارك الله فيك

    شكرا جزيلاً