الاستفادة من خدمات تقصير العناوين برمجيا – خدمة bit.ly

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

يمكنك قراءة المزيد عن خدمات تقصير العناوين هنا.

الكود- Elsheimy.Samples.ShortenSvcs.Bitly.cs

المحتويات

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

  • المحتويات
  • نظرة خاطفة
  • مقدمة
  • الواجهة البرمجية
    • نظرة عامة
    • شرح الدوال
    • دالة التقصير
    • دالة التمديد
    • دالة التحقق
    • دالة الإحصائيات
    • دالة البحث
    • دالة البيانات
    • دالة التوثيق
  • دعم JSON
  • المثال
  • ماذا بعد

نظرة خاطفة

اليوم نتكلم عن أشهر وأقوى خدمة تقصير عناوين على الإطلاق، إنها خدمة bit.ly. اليوم نتكلم عن كيفية الوصول إليها برمجيا، نتعرف على واجهتها البرمجية، وندرس تفصيليا دوالها وكيفية برمجتها.

في آخر الدرس ستجد الكود متوفر وجاهز للتحميل.

هيا بنا!

مقدمة

اليوم نتكلم عن أشهر خدمة موجودة على الويب اليوم، الأشهر على الإطلاق، إنها خدمة bit.ly، الخدمة الرائدة في مجال تقصير العناوين.

بالطبع لا نحتاج إلى وصف الخدمة فهي غنية عن التعريف، لذلك فإننا سندخل مباشرة إلى الواجهة البرمجية لهذه الخدمة وكيفية الاتصال معها.

الواجهة البرمجية

نظرة عامة

نظرة عامة على الواجهة البرمجية التي توفرها خدمة bit.ly ومميزاتها:

  • واجهة REST:

مشابها لمعظم الواجهات البرمجية التي تعرضنا إليها، الواجهة البرمجية التي توفرها خدمة bit.ly هي من نوع REST ، أي أنها عبارة عن خدمة ويب تعرض دوالها عن طريق نقاط وصول Endpoints من نوع HTTP. بمعنى آخر، أن لكل دالة عنوان يمكن الوصول إليها من خلاله بسهولة، ويتم إضافة مدخلات هذه الدالة في العنوان تماما مثل مدخلات Query Strings لأي صفحة ويب. (لا يجب عليك أن تقلق حيال هذه المصطلحات، REST، Endpoint، و HTTP، فقط تابع القراءة.)

الإصدار الوحيد الموجود من هذه الواجهة حتى الآن هو الإصدار الثالث وهو الذي يستخدم في كافة العمليات.

جميع الدوال لها صيغة العنوان التالي:

http://api.bit.ly/v3/[function_name]?[args]

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

  • الدوال:

توفر لك الواجهة البرمجية العديد من الدوال، وهذه الدوال هي كالتالي:

  • دالة التقصير Shorten:
    تستخدم لتقصير الروابط.
  • دالة التطويل Expand:
    تستخدم للحصول على الرابط الطويل الأصلي مصدر الرابط القصير.
  • دالة التحقق Validate:
    وتستخدم في عملية التوثيق للتحقق من بيانات استخدام الواجهة البرمجية الخاصة بالمستخدم.
  • دالة الإحصائيات Clicks:
    وتستخدم للحصول على عدد مرات الضغط على الرابط القصير سواء من المستخدم المحدد أو بشكل عام.
  • دالة البحث Lookup:
    وتستخدم للتأكد من أن هناك بيانات لهذا الرابط الطويل أي أنه تم تقصيره قبل ذلك أم لا.
  • دالة البيانات Info:
    وتستخدم للحصول على بيانات الرابط مثل اسم المستخدم الذي قم بإنشائه وعنوان الصفحة ونحو ذلك.
  • دالة التوثيق Authentication:
    تستخدم للتأكد من بيانات الدخول للمستخدم (اسم المستخدم وكلمة المرور.) يجب الاتصال بخدمة bit.ly للحصول على صلاحيات استخدام هذه الدالة.

كما تلاحظ فالواجهة البرمجية لخدمة bit.ly هي الأكبر والأكثر تطورا مقارنة بالواجهات البرمجية الخاصة بخدمات تقصير العناوين الأخرى.

  • المدخلات:

يجب أن تقوم بترميز أي عنوان تقوم بتحديده في المدخلات وذلك لإزالة العلامات مثل ’#‘، ’?‘، و ’=‘، ويتم ذلك ببساطة عن طريق الدالة System.Net.Uri.EscapeUriString().

هناك ثلاثة مدخلات رئيسية تستخدم في جميع الدوال (سيأتي تفصيل أكثر في هذه المدخلات):

  • login:
    اسم المستخدم.
  • apiKey:
    المفتاح البرمجي.
  • format:
    الصيغة.

فهذه الثلاثة لا غنى عنها في أي دالة.

  • التوثيق:

جميع الدوال بلا استثناء تطلب توثيق المستخدم، أي تطلب بيانات استخدام الواجهة البرمجية من المستخدم. وهذه البيانات هي عبارة عن فقط اسم المستخدم Username والمفتاح البرمجي API Key (ليس كلمة المرور) والذي يمكن الحصول عليه إما بالانتقال إلى صفحة الحساب الخاصة به http://bit.ly/a/account بعد تسجيل دخوله في الخدمة، وإما بالانتقال إلى الصفحة http://bit.ly/a/your_api_key بعد تسجيل دخوله أيضا.

من أحد المميزات الجميلة جدا في هذه الواجهة البرمجية أنها توفر لك اسم مستخدم ومفتاح برمجي يمكنك استخدامه في تجاربك على هذه الخدمة وهذه البيانات هي كالتالي:

اسم المستخدم: bitlyapidemo

المفتاح البرمجي: R_0da49e0a9118ff35f52f629d2d71bf07

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

  • الصيغ المدعومة:

البيانات المرتجعة من هذه الدوال إما أن تكون بصيغة XML أو بصيغة JSON (الصيغة الأساسية) حسب تحديدك في المدخل format المستخدم في جميع الدوال. أيضا فهناك دوال مثل دالة التقصير Shorten التي تدعم صيغة أخرى وهي النص البسيط Plain Text أي أنك لن تحتاج إلى عمل أي معالجة للبيانات المرتجعة.

بما أن هناك دعم أكبر لبيانات XML في بيئة الدوت نت فسوف يكون تركيزنا على صيغة XML بالإضافة طبعا إلى صيغة النص البسيط Text.

  • تفادي الأخطاء:

بالنسبة للبيانات النصية البسيطة فإنه عند فشل العملية ستحصل على خطأ Exception يظهر لك في الكود. أما بيانات XML فتختلف.

هناك تركيب وصيغة معروفة لبيانات XML المرتجعة وهي تكون كالتالي:

<?xml version="1.0" encoding="UTF-8"?>
<response>
    <status_code />
    <status_txt />
    ...
</response>

نلاحظ أن العنصر status_code دائما موجود وهو يحوي حالة العملية والتي تساوي 200 في حالة نجاح العملية أو كود الخطأ في حالة فشلها. أيضا يمكنك متابعة العنصر status_txt والذي يحوي وصف الحالة وهي ’OK‘ في حالة نجاح العملية أو وصف الخطأ في حالة فشلها.

أما باقي المحتوى فهو فيتغير تبعا للدالة، فلكل دالة صيغة وتركب لبياناتها المرتجعة.

  • النطاق:

يمكنك تقصير الروابط باستخدام أحد نطاقين تابعان لخدمة bit.ly وهما: http://bit.ly و http://j.mp (الأحدث،) ولا فرق في الخدمة بين الاثنين غير أن في النطاق الأول يكون الرابط عبارة عن 20 حرف (مثلا http://bit.ly/bnPuEX) أما الثانية فيكون الرابط عبارة عن 18 حرف فقط (مثلا http://j.mp/bO9TgE.)

لاحظ أنك تقوم بتحديد النطاق في دالة التقصير باستخدام المدخل domain. لاحظ أيضا أننا نقوم بتسمية الكود الواقع بعد اسم الدومين، مثلا bnPuEX أو bO9TgE، نقوم بتسميته هاش Hash وهو لا يزيد ولا يقل عن 6 أحرف (حساس للحالة.)

وهناك نوعان من الهاش Hash:

  • هاش المستخدم User Hash:
    كل مستخدم له كود هاش للعنوان خاص به. فنفس العنوان إذا قمت بتقصيره أكثر من مرة يختلف الهاش الناتج من مستخدم إلى آخر. وهذا الهاش هو الذي يستخدم للانتقال إلى الصفحة المطلوبة.
  • الهاش العالمي Global Hash:
    وهو كود آخر يميز الرابط ولا يختلف من مستخدم إلى آخر.
  • معدل النداء:

لاحظ أنه هناك حدود للنداء على الدوال كل ساعة من نفس عنوان الـ IP. فلا تتوقع مثلا أن تقوم بالنداء على أحد الدوال الآلاف من المرات في الساعة الواحدة.

شرح الدوال

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

مرة أخرى، بيانات الحساب الخاص بمستخدم الخدمة: اسم الدخول: bitlyapidemo. المفتاح البرمجي: R_0da49e0a9118ff35f52f629d2d71bf07. (مع ذلك لا نفضل لك استخدامه.)

دالة التقصير

دالة التقصير وهي دالتنا الأولى اليوم وهي الدالة shorten والتي لها العنوان التالي http://api.bit.ly/v3/shorten، وهي تأخذ مدخلان:

  • longUrl:
    مطلوب. العنوان الطويل المراد تقصيره.
  • domain:
    اختياري. النطاق المفضل. إما bit.ly أو j.mp.

هذا بالطبع بالإضافة إلى المدخلات الأساسية الموجودة في جميع الدوال وهي login، apiKey، و format والتي تحوي بيانات التوثيق والصيغة (json، xml، أو txt.)

بإمكانك تجربة هذه الدالة في متصفحك. لتقصير العنوان http://JustLikeAMagic.com قم بنسخ العنوان التالي إلى المتصفح الخاص بك:

http://api.bit.ly/v3/shorten?login=bitlyapidemo&apiKey=R_0da49e0a9118ff35f52f629d2d71bf07 &format=txt&longUrl=http://JustLikeAMagic.com

تجد العملية استكملت بشكل صحيح وظهر لك الرابط القصير. لاحظ أننا قمنا باستخدام الحساب الخاص بالخدمة bitlyapidemo وهذا لا يفضل أبدا.

لاحظ أيضا أننا قمنا بتحديد الصيغة كنص بسيط txt. يمكنك أيضا تحديد البيانات بصيغة xml فتكون البيانات المرتجعة شبيهة بالتالي:

<?xml version="1.0" encoding="utf-8"?>
<response>
    <status_code>200</status_code>
    <status_txt>OK</status_txt>
    <data>
        <url>http://bit.ly/bO9TgE</url>
        <hash>bO9TgE</hash>
        <global_hash>9gSDEU</global_hash>
        <long_url>http://JustLikeAMagic.com</long_url>
        <new_hash>0</new_hash>
    </data>
</response>

هنا تلاحظ أن نتيجة العملية كانت 200 وهي تعني نجاح العملية (’OK‘.) لاحظ أيضا الصيغة الخاصة ببيانات هذه الدالة والتي تقوم بإرجاع جميع البيانات الخاصة بالرابط القصير وهي:

  • url:
    الرابط القصير.
  • hash:
    الهاش/الكود الخاص بالرابط والموجود في عنوان الرابط.
  • global_hash:
    الهاش/الكود العالمي الخاص بالرابط وهذا له استخدمات أخرى نذكرها قريبا.
  • long_url:
    العنوان الأصلي/الطويل للرابط.
  • new_hash:
    قيمة تساوي 1 إذا كان هذا الرابط لم يتم تقصيره قبل ذلك، أو 0 إذا لم تكن هذه أول مرة يتم تقصيره فيها.

الآن، إلى الكود. دالتنا التالية تقوم بتقصير العناوين عن طريق النداء على دالتنا دالة التقصير. لاحظ المدخلات التي تأخذها الدالة.

لا تنسى إضافة أمر استخدام using للنطاقات System.IO، System.Net، و System.Xml إلى صفحة الكود الخاصة بك.

// C#
string Shorten(string url, string login, string key, bool xml)
{
    url = Uri.EscapeUriString(url);
    string reqUri =
        String.Format("http://api.bit.ly/v3/shorten?" +
        "login={0}&amp;apiKey={1}&amp;format={2}&amp;longUrl={3}",
        login, key, xml ? "xml" : "txt", url);
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
    req.Timeout = 10000; // 10 seconds
    // if the function fails and format==txt throws an exception
    Stream stm = req.GetResponse().GetResponseStream();
    if (xml)
    {
        XmlDocument doc = new XmlDocument();
        doc.Load(stm);
        // error checking for xml
        if (doc["response"]["status_code"].InnerText != "200")
            throw new WebException(doc["response"]["status_txt"].InnerText);
        return doc["response"]["data"]["url"].InnerText;
    }
    else // Text
        using (StreamReader reader = new StreamReader(stm))
            return reader.ReadLine();
}

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

دالة التمديد

دالة التمديد أو تطويل العنوان والتي تسمى expand ويمكنك من خلالها الحصول على العنوان الطويل من خلال العنوان القصير، فمثلا باستخدام المدخلات http://bit.ly/bnPuEX تحصل على العنوان الطويل http://JustLikeAMagic.com مصدر هذا العنوان.

كما تعرف فإن عنوان أي دالة يبدأ بـ http://api.bit.ly/v3/ ثم اسم الدالة. ودالتنا هذه تأخذ مدخلات العنوان القصير shortUrl المطلوب الحصول على العنوان الطويل منه، بجانب طبعا الثلاثة مدخلات الرئيسية login، apiKey، format.

بنفس الطريقة السابقة تستخدم هذه الدالة غير أن البيانات XML المرتجعة منها لها صيغة أخرى وهي كالتالي:

<?xml version="1.0" encoding="utf-8" ?>
<response>
    <status_code>200</status_code>
    <status_txt>OK</status_txt>
    <data>
        <entry>
            <short_url>http://bit.ly/bnPuEX</short_url>
            <long_url>http://justlikeamagic.com</long_url>
            <user_hash>bnPuEX</user_hash>
            <global_hash>bdE96m</global_hash>
        </entry>
    </data>
</response>

نلاحظ أن هناك عنصر جديد وهو user_hash وهو ذلك الجزء الموجود في العنوان الواقع بعد اسم النطاق (مثلا bnPuEX  في http://bit.ly/bnPuEX.) وهناك فرق بين هاش المستخدم User Hash والهاش العالمي Global Hash كما تعرف (راجع الجزء الخاص بالنطاق.)

ثم إلى الكود، الكود التالي يقوم باسترجاع العنوان الأصلي من العنوان القصير.

// C#
string Expand(string url, string login, string key, bool xml)
{
    url = Uri.EscapeUriString(url);
    string reqUri =
        String.Format("http://api.bit.ly/v3/expand?" +
        "login={0}&amp;apiKey={1}&amp;format={2}&amp;shortUrl={3}",
        login, key, xml ? "xml" : "txt", url);
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
    req.Timeout = 10000; // 10 seconds
    // if the function fails and format==txt throws an exception
    Stream stm = req.GetResponse().GetResponseStream();
    if (xml)
    {
        XmlDocument doc = new XmlDocument();
        doc.Load(stm);
        // error checking for xml
        if (doc["response"]["status_code"].InnerText != "200")
            throw new WebException(doc["response"]["status_txt"].InnerText);
        return doc["response"]["data"]["entry"]["long_url"].InnerText;
    }
    else // Text
        using (StreamReader reader = new StreamReader(stm))
            return reader.ReadLine();
}

دالة التحقق

الدالة الثالثة معنا وهي دالة التحقق validate والتي يمكنك استخدامها للتحقق من أن مستخدم آخر اسمه ومفتاحه البرمجي صالحان. أي أنك لديك اسم ومفتاح برمجي صالحان تستخدمهما للتحقق من أن اسم آخر ومفتاح آخر صحيحان وصالحان للعمل. وهذه الدالة بجانب المدخلات الرئيسية والتي تضم اسم الدخول والمفتاح البرمجي الرئيسيان تأخذ مدخلان آخران وهما اسم الدخول x_login والمفتاح البرمجي x_apiKey الذي يرجا التأكد من صحتهما.

وهذه الدالة تقوم بإرجاع إما قيمة نصية عبارة عن رقم 1 إذا كانت البيانات صحيحة أو رقم 0 إذا كانت خاطئة، وإما أن تقوم بإرجاع بيانات XML شبيهة بالتالية:

<?xml version="1.0" encoding="UTF-8"?>
<response>
    <status_code>200</status_code>
    <status_txt>OK</status_txt>
    <data>
        <valid>0</valid>
    </data>
</response>

هنا أيضا لدينا العنصر valid يحوي قيمة تساوي 1 في حالة كون البيانات صحيحة أو 0 في حالة كونها خاطئة.

الدالة التالية تقوم بالتحقق من اسم مستخدم ومفتاحه البرمجي.

// C#
string Validate(string login, string key,
    string xLogin, string xKey, bool xml)
{
    string reqUri =
        String.Format("http://api.bit.ly/v3/validate?" +
        "login={0}&amp;apiKey={1}&amp;x_login={4}&amp;x_key={5}&amp;format={2}" +
        login, key, xLogin, xKey, xml ? "xml" : "txt");
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
    req.Timeout = 10000; // 10 seconds
    // if the function fails and format==txt throws an exception
    Stream stm = req.GetResponse().GetResponseStream();
    if (xml)
    {
        XmlDocument doc = new XmlDocument();
        doc.Load(stm);
        // error checking for xml
        if (doc["response"]["status_code"].InnerText != "200")
            throw new WebException(doc["response"]["status_txt"].InnerText);
        return int.Parse(doc["response"]["data"]["valid"]) == 1 ? true : false;
    }
    else // Text
        using (StreamReader reader = new StreamReader(stm))
            return int.Parse(reader.ReadLine()) == 1 ? true : false;
}

دالة الإحصائيات

ثم إلى دالة مثيرة جدا وهي دالة الإحصائيات clicks والتي تقوم بإرجاع عدد مرات الوصول إلى هذا الرابط القصير أي عدد مرات استخدامه سواء تم الضغط عليه أم كتابته مباشرة في خانة العنوان في المتصفح. هذه الدالة لا تأخذ بالإضافة إلى الثلاثة مدخلات الرئيسية إلا مدخلا واحدا وهو العنوان القصير shortUrl ولا تقوم بإرجاع نص بسيط، بل XML (وأيضا JSON بالطبع) ويكون له الصيغة التالية:

<?xml version="1.0" encoding="utf-8" ?>
<response>
    <status_code>200</status_code>
    <data>
        <clicks>
            <short_url>http://bit.ly/bnPuEX</short_url>
            <global_hash>bdE96m</global_hash>
            <user_clicks>0</user_clicks>
            <user_hash>bnPuEX</user_hash>
            <global_clicks>0</global_clicks>
        </clicks>
    </data>
    <status_txt>OK</status_txt>
</response>

تقوم هذه الدالة بإرجاع الهاش الخاص بالرابط (هاش المستخدم والهاش العالمي) بالإضافة إلى إحصائيات الرابط وهي تتمثل في رقمين (شبيهين بالهاش):

  • إحصائيات المستخدم:
    عدد مرات استخدام نفس هذا الرابط الذي أنشأه المستخدم.
  • إحصائيات عالمية:
    عدد مرات استخدام أي رابط قصير يرمز إلى نفس العنوان الطويل. فكما تعرف ربما يكون لنفس العنوان الطويل أكثر من رابط قصير أنشأه أكثر من مستخدم. فهذه تحدد إجمالي عدد مرات الوصول إلى هذا العنوان من جميع الروابط القصيرة الخاصة به.

الكود التالي يقوم باسترجاع الإحصائيات الخاصة بأي رابط قصير (بالطبع خاص بـ bit.ly أو j.mp):

// C#
int GetClicks(string url, string login, string key, out int globalClicks)
{
    url = Uri.EscapeUriString(url);
    string reqUri =
        String.Format("http://api.bit.ly/v3/clicks?" +
        "login={0}&amp;apiKey={1}&amp;shortUrl={2}&amp;format=xml" +
        login, key, url);
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
    req.Timeout = 10000; // 10 seconds
    Stream stm = req.GetResponse().GetResponseStream();
    XmlDocument doc = new XmlDocument();
    doc.Load(stm);
    // error checking for xml
    if (doc["response"]["status_code"].InnerText != "200")
        throw new WebException(doc["response"]["status_txt"].InnerText);
    XmlElement el = doc["response"]["data"]["clicks"];
    globalClicks = int.Parse(el["global_clicks"].InnerText);
    return int.Parse(el["user_clicks"].InnerText);
}

دالة البحث

دالة البحث lookup وهي تستخدم للتأكد من أن هناك بيانات لهذا الرابط أي أنه تم تقصيره قبل ذلك أم لا. وهي كما توقعت لا تأخذ إلا مدخلا واحدا وهو الرابط الطويل url، وأيضا فإنها لا تدعم النصوص البسيطة Plain Text. وهي تقوم بإرجاع بيانات مشابهة للتالية في حالة كون الرابط موجودا:

<?xml version="1.0" encoding="utf-8" ?>
<response>
    <status_code>200</status_code>
    <status_txt>OK</status_txt>
    <data>
        <lookup>
            <url>http://JustLikeAMagic.com</url>
            <short_url>http://bit.ly/9gSDEU</short_url>
            <global_hash>9gSDEU</global_hash>
        </lookup>
    </data>
</response>

فهنا قامت بإرجاع بيانات الرابط مع الرابط القصير الخاص به.

أما إذا لم يكن الرابط موجودا فتكون البيانات كالتالية:

<?xml version="1.0" encoding="utf-8" ?>
<response>
    <status_code>200</status_code>
    <status_txt>OK</status_txt>
    <data>
        <lookup>
            <url>http://JustLikeAMagic.com/books</url>
            <error>NOT_FOUND</error>
        </lookup>
    </data>
</response>

والآن إلى الكود. الدالة التالية تقوم بالتأكد من وجود هذا الرابط في قاعدة بيانات الخدمة وتقوم بإرجاع الرابط القصير في حالة وجوده.

// C#
string Lookup(string url, string login, string key)
{
    url = Uri.EscapeUriString(url);
    string reqUri =
        String.Format("http://api.bit.ly/v3/lookup?" +
        "login={0}&amp;apiKey={1}&amp;url={2}&amp;format=xml" +
        login, key, url);
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
    req.Timeout = 10000; // 10 seconds
    Stream stm = req.GetResponse().GetResponseStream();
    XmlDocument doc = new XmlDocument();
    doc.Load(stm);
    // error checking for xml
    if (doc["response"]["status_code"].InnerText != "200")
        throw new WebException(doc["response"]["status_txt"].InnerText);
    if (doc["response"]["data"]["lookup"]["error"] == null)
        return null; // not found
    return doc["response"]["data"]["lookup"]["short_url"].InnerText;
}

دالة البيانات

دالة البيانات info وهي تأخذ الرابط القصير shortUrl وتقوم بإرجاع جميع البيانات الخاصة به، وتكون البيانات بصيغة XML (أو JSON بالطبع) وتكون شبيهة بالتالي:

<?xml version="1.0" encoding="utf-8" ?>
<response>
    <status_code>200</status_code>
    <status_txt>OK</status_txt>
    <data>
        <info>
            <short_url>http://bit.ly/bnPuEX</short_url>
            <global_hash>bdE96m</global_hash>
            <user_hash>bnPuEX</user_hash>
            <created_by>elsheimy</created_by>
            <title>Just Like a Magic</title>
        </info>
    </data>
</response>

هنا نلاحظ أنك حصلت على اسم المستخدم الذي قام بتقصير هذا الرابط (في خانة created_by) وحصلت على عنوان الصفحة title.

الدالة التالية تقوم بإرجاع بيانات الرابط القصير الذي يحدده المستخدم:

// C# Code
string GetInfo(string url, string login, string key, out string createdBy)
{
    url = Uri.EscapeUriString(url);
    string reqUri =
        String.Format("http://api.bit.ly/v3/info?" +
        "login={0}&amp;apiKey={1}&amp;shortUrl={2}&amp;format=xml" +
        login, key, url);
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
    req.Timeout = 10000; // 10 seconds
    Stream stm = req.GetResponse().GetResponseStream();
    XmlDocument doc = new XmlDocument();
    doc.Load(stm);
    // error checking for xml
    if (doc["response"]["status_code"].InnerText != "200")
        throw new WebException(doc["response"]["status_txt"].InnerText);
    XmlElement el = doc["response"]["data"]["info"];
    createdBy = el["created_by"].InnerText;
    return el["title"].InnerText;
}

دالة التوثيق

دالتنا الأخيرة اليوم وهي دالة التوثيق authenticate والتي تستخدم للتأكد من أن اسم مستخدم وكلمة مروره صحيحان. ربما تشتبه عليك هذه الدالة بدالة التحقق validate، ولكن الفرق أن دالة التحقق تستخدم للتأكد من اسم مستخدم ومفتاحه البرمجي، أما دالة التوثيق فتستخدم مع كلمة المرور وليس المفتاح البرمجي. لاحظ وجه الشبه وهو أنه يطلب منك إدخال اسم مستخدم ومفتاح برمجي صحيحان للتأكد من اسم المستخدم الآخر وكلمة مروره.

نظرا لوظيفة هذه الدالة والتي تجعلها عرضة للاستخدام الخاطئ فإن الوصول إليها غير متاح للمستخدم ولكن يجب عليه أولا أن يقوم بالاتصال بالخدمة عن طريق البريد الإلكتروني api@bit.ly وتوفير بياناته وبيانات برنامجه حتى يسمح له باستخدام هذه الدالة.

كما علمت هذه الدالة تأخذ مدخلين إضافيين وهما اسم المستخدم x_login المراد التحقق من حسابه وكلمة مروره x_password. وهذه البيانات لا يمكنك تحديدها في العنوان بل في جسم الطلب Request الذي يستخدم للنداء على الدالة. وأيضا فإن هذه الدالة يجب فيها استخدام الطريقة POST.

وفي حالة نجاح العملية تكون البيانات المرتجعة كالتالي:

<?xml version="1.0" encoding="UTF-8"?>
<response>
    <status_code>200</status_code>
    <data>
        <authenticate>
            <username>bitlyapidemo</username>
            <successful>1</successful>
            <api_key>R_0da49e0a9118ff35f52f629d2d71bf07</api_key>
        </authenticate>
    </data>
    <status_txt>OK</status_txt>
</response>

فهنا تقوم الدالة بإرجاع اسم المستخدم ومفتاحه البرمجي. أما في حالة كون البيانات غير صحيحة فيكون الناتج كالتالي:

<?xml version="1.0" encoding="UTF-8"?>
<response>
    <status_code>200</status_code>
    <data>
        <authenticate>
            <successful>0</successful>
        </authenticate>
    </data>
    <status_txt>OK</status_txt>
</response>

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

// C#
string Authenticate(string login, string key, string xLogin, string xPassword)
{
    string reqUri = "http://api.bit.ly/v3/authenticate";
    string body =
        string.Format("login={0}&amp;apiKey={1}&amp;x_login={2}" +
        "&amp;x_password={3}&amp;format=xml",
        login, key, xLogin,xPassword);
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
    req.Timeout = 10000;
    req.Method = "POST";
    StreamWriter writer = new StreamWriter(req.GetRequestStream());
    writer.WriteLine(body);
    Stream stm = req.GetResponse().GetResponseStream();
    XmlDocument doc = new XmlDocument();
    doc.Load(stm);
    // error checking for xml
    if (doc["response"]["status_code"].InnerText != "200")
        throw new WebException(doc["response"]["status_txt"].InnerText);
    XmlElement el = doc["response"]["data"]["authenticate"];
    if (el["successful"].InnerText == "1")
        return el["api_key"].InnerText;
    else
        return null;
}

لاحظ كيف قمنا بإضافة البيانات في جسم الطلب Request.

دعم JSON

كنا قد ركزنا في كلام على صيغتي XML والنص البسيط وأرجأنا الكلام عن الصيغة الأولى والأساسية ألا وهي JSON (اختصار لـ JavaScript Object Notation) وهي أسلوب آخر لصياغة البيانات على الويب. بالرغم من أن صيغتي XML والنص البسيط كافين في أغلب الأحوال وهذا بسبب شهرتهم وبساطتهم إلا أنه يتوجب علينا الكلام عن صيغة JSON والتي في بعض الأحوال ستضطر إلى استخدامها خاصة أن هناك بعض خدمات الويب التي لا تدعم إلا هذه الصيغة، وأيضا سبب آخر وهو استكمال الكلام عن حزمة تطبيق bit.ly.

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

أول ما يجب عليك معرفته هو أنه يمكنك الحصول على بيانات بصيغة JSON من دوال bit.ly بطرقتين، الأولى: بتحديد القيمة json في المدخل format الموجود في جميع الدوال. الثانية: بحذف المدخل format بالكامل، وبالتالي ستطبق الصيغة الأساسية وهي JSON.

فلنأخذ مثال. في دالة تقصير الروابط يمكنك النداء عليها بالطريقة التالية (بتحديد json في مدخل الصيغة format):

http://api.bit.ly/v3/shorten?login=bitlyapidemo&apiKey=R_0da49e0a9118ff35f52f629d2d71bf07
&format=json&longUrl=http://JustLikeAMagic.com

وبالتالي تحصل على النتيجة التالية وهي بصيغة JSON:

{
    "status_code": 200,
    "status_txt": "OK",
    "data":
    {
        "long_url": "http:\/\/justlikeamagic.com",
        "url": "http:\/\/bit.ly\/bnPuEX",
        "hash": "bnPuEX",
        "global_hash": "bdE96m",
        "new_hash": 0
    }
}

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

بالنظر إلى قطعة الـ JSON السابقة يمكننا إدراك أنها مكونة من عدة عناصر كل عنصر له اسم وقيمة يفصلهما نقطتان (:)، وبين كل عنصر والآخر فاصلة (,)، ويحد اسم العنصر وكذلك يحد قيمته علامتي تنصيص (“”). أيضا نلاحظ أن هذه البيانات هي عبارة عن تركيب Structure تحده أقواس ملتوية ({}). أيضا نجد أن العنصر data هو عبارة عن عنصر مركب، أي أنه يحوي عناصر أخرى بداخله محاطة بدورها بالأقواس الملتوية.

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

    // C#
    class ShortUrl
    {
        public int status_code;
        public string status_txt;
        public ShortUrlData data;
    }
    class ShortUrlData
    {
        public string long_url;
        public string url;
        public string hash;
        public string global_hash;
        public int new_hash;
    }

الآن يأتي العمل. يأتي دور العنصر DataContractJsonSerializer. هذا العنصر موجود في النطاق System.Runtime.Serialization.Json والموجود في المكتبة System.Runtime.Serialization.dll إذا كنت تستخدم الدوت نت 4.0، أو المكتبة System.ServiceModel.Web.dll إذا كنت تستخدم الدوت نت 3.5 (هذه الإمكانية ليست موجودة في الإصدارات السابقة.)

العنصر DataContractJsonSerializer يعمل بأسلوب التسلسلية Serialization، فله طريقتان، الأولى: التسلسل Serialize (وهو تحويل عناصر الدوت نت إلى بيانات بصيغة JSON)، الثانية وهي فك التسلسل (وهو تحويل بيانات JSON إلى عناصر الدوت نت.) تتم العملية الأولى عن طريق الدوال WriteXXX()، بينما الثانية تتم عن طريق الدوال ReadXXX().

الآن، ننتقل إلى التكويد. أولا، أضف المكتبة الصحيحة كمرجع إلى المشروع، ولا تنسى إضافة النطاق System.Runtime.Serialization.Json.

الآن، يمكننا كتابة الكود الخاص بنا:

// C#
ShortUrl Shorten(string url, string login, string key)
{
    url = Uri.EscapeUriString(url);
    string reqUri =
        String.Format("http://api.bit.ly/v3/shorten?" +
        "login={0}&apiKey={1}&format={2}&longUrl={3}",
        login, key, "json", url);
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(reqUri);
    req.Timeout = 10000; // 10 seconds
    // if the function fails and format==txt throws an exception
    Stream stm = req.GetResponse().GetResponseStream();
    DataContractJsonSerializer con =
        new DataContractJsonSerializer(typeof(ShortUrl));
    ShortUrl shortUrl = (ShortUrl)con.ReadObject(stm);
    return shortUrl;
}

استمتع مع JSON!

المثال

قم بتحميل الكود من هنا.

ماذا بعد

يمكنكم قراءة المزيد عن خدمات تقصير العناوين هنا.

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

اخترنا لك:

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

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