<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های رضا اصغری</title>
        <link>https://virgool.io/feed/@riza</link>
        <description>برنامه‌نویسی که سال‌هاست مبتدی است! علاقه‌مند به حوزه وب، اندروید و لینوکس...</description>
        <language>fa</language>
        <pubDate>2026-06-07 11:12:43</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/32173/avatar/YSKK3i.png?height=120&amp;width=120</url>
            <title>رضا اصغری</title>
            <link>https://virgool.io/@riza</link>
        </image>

                    <item>
                <title>یک نکته ظریف در خصوص توسعه بات‌ تلگرام همراه با وردپرس!</title>
                <link>https://virgool.io/@riza/%DB%8C%DA%A9-%D9%86%DA%A9%D8%AA%D9%87-%D8%B8%D8%B1%DB%8C%D9%81-%D8%AF%D8%B1-%D8%AE%D8%B5%D9%88%D8%B5-%D8%AA%D9%88%D8%B3%D8%B9%D9%87-%D8%A8%D8%A7%D8%AA-%D8%AA%D9%84%DA%AF%D8%B1%D8%A7%D9%85-%D9%87%D9%85%D8%B1%D8%A7%D9%87-%D8%A8%D8%A7-%D9%88%D8%B1%D8%AF%D9%BE%D8%B1%D8%B3-pmk59hbsvo1n</link>
                <description>امروز حین شروع کدنویسی یک ربات تلگرامی برای یک فروشگاه اینترنتی توسعه داده شده بر بستر سیستم مدیریت محتوای وردپرس، با چالشی ساده اما طاقت‌فرسا روبه‌رو شدم که در عین حال که شاید موضوعی نسبتا ساده به نظر رسد، اما تصمیم گرفتم آن را در اینجا منتشر کنم تا شاید روزی برای سایر توسعه‌دهندگان وردپرس و بات‌های تلگرامی مفید واقع گردد.همانطور که می‌دانید، نخستین گام در توسعه یک بات تلگرامی، فراهم‌سازی بسترهای نرم‌افزاری و سخت‌افزاری برای آن است که در ساده‌ترین حالت ممکن، این بستر شامل در اختیار داشتن یک وب‌سرور، یک دامنه اینترنتی و یا IP اختصاصی و همچنین اعمال پروتکل امنیتی SSL بر روی آن می‌باشد. از آنجایی که بات مدنظر می‌بایست برای یک وب‌سایت فروشگاهی در حال ارائه سرویس کدنویسی می‌شد، طبیعتا وب‌سرور و دامنه اینترنتی موجود و از شانس خوب من پروتکل امنیتی SSL نیز بر روی آن فعال بود. بنابراین مستقیما سراغ ساخت بات رفته و در قدم ابتدایی اقدام به ست کردن وب‌هوک جهت مدیریت پیام‌ها و درخواست‌های دریافتی از کابران و ارائه پاسخ‌های متناسب با ورودی‌های کاربر نمودم. اما بر خلاف تجربه‌های گذشته، بات آنچنان که انتظار می‌رفت عمل نکرده و واکنشی به عمل اولیه /start از خود نشان نمی‌داد. با تست بات (با همان توکن و کدها) در سرورهای دیگر با عملکرد صحیح آن مواجه گشته و از صحت کدهای نوشته شده اطمینان حاصل نمودم. تا اینکه با دریافت جزئیات وب‌هوک ست شده با استفاده از متد  getWebhookInfo و بررسی آن‌ها، متوجه دریافت خطای زیر توسط تلگرام هنگام تلاش جهت برقراری ارتباط با اسکریپت PHP که وب‌هوک بر روی آن ست شده است، شدم:Wrong response from the webhook: 403 Forbiddenخطایی که حاکی از عدم صدور مجوزهای لازم از سوی وب‌سرور به تلگرام، جهت برقراری ارتباط و تبادل اطلاعات با اسکریپت بات بود. اما مشکل از کجا می‌توانست باشد؟ در صحت عملکرد کدهای نوشته شده شکی نبود (با توجه به تست در چندین سرور متفاوت و مشاهده عملکرد صحیح)، کد مجوز دسترسی به فایل اسکریپت بات در سرور به درستی تنظیم شده بود و همچنین پروتکل امنیتی SSL توسط یک شرکت معتبر خارجی تنظیم و ست شده بود! پس از ساعت‌ها کلنجار رفتن با بخش پشتیبانی شرکت ارائه دهنده خدمات میزبانی وب و فعال و غیرفعال کردن چندین ماژول امنیتی نصب شده بر روی سرور و... بازهم مشکل بر سر جای خود باقی بود و هیچ فرجی در این معضل معما مانند حاصل نمی‌شد. تا اینکه بالاخره به صورت کاملا اتفاقی به سراغ پلاگین‌های نصب شده در وردپرس رفته (بنابر تجربه حاصل شده از توسعه تم‌های وردپرسی و عیب‌یابی از طریق فعال/غیرفعال کردن پلاگین‌ها و...) و متوجه فعال بودن دو افزونه امنیتی معروف وردپرسی (wordfence و ithemes) بر روی این فروشگاه اینترنتی شدم که در نهایت با غیرفعال‌سازی افزونه ithemes خطای 403 برای وب‌هوک بات تلگرامی رفع، و بات شروع به پاسخ‌دهی به درخواست‌ها و پیام‌های دریافتی نمود. هرچند مدت زیادی را صرف زیر و رو کردن تنظیمات این افزونه نمودم، اما در نهایت موفق به یافتن پیکربندی خاصی جهت رفع محدودیت اعمال شده توسط آن برای ترافیک ورودی از تلگرام نشدم و با غیرفعال‌سازی کامل آن عطایش را به لقایش بخشیدم!</description>
                <category>رضا اصغری</category>
                <author>رضا اصغری</author>
                <pubDate>Mon, 08 Apr 2019 01:12:18 +0430</pubDate>
            </item>
                    <item>
                <title>حل مشکل برعکس شدن swipe direction در ViewPager در طراحی‌های RTL اندروید</title>
                <link>https://virgool.io/MobileLab/%D8%AD%D9%84-%D9%85%D8%B4%DA%A9%D9%84-%D8%A8%D8%B1%D8%B9%DA%A9%D8%B3-%D8%B4%D8%AF%D9%86-swipe-direction-%D8%AF%D8%B1-viewpager-%D8%AF%D8%B1-%D8%B7%D8%B1%D8%A7%D8%AD%DB%8C%D9%87%D8%A7%DB%8C-rtl-%D8%A7%D9%86%D8%AF%D8%B1%D9%88%DB%8C%D8%AF-a8tscdkr0mev</link>
                <description>در این مطلب قصد دارم تا یک راهکار کوتاه و عملی برای حل مشکل تغییر swipe direction در ViewPager در طراحی‌های RTL اندروید را به اشتراک بگذارم.چنانچه اپلیکیشن اندرویدی شما از طراحی راست‌چین یا RTL ساپورت می‌کند (با افزودن android:supportsRtl=&quot;true&quot; به فایل مانیفست پروژه)، احتمالا هنگام استفاده از ViewPager متوجه عملکرد ناصحیح عمل swipe در جابه‌جایی میان pageهای ViewPager شده‌اید، به طوری که با کشیدن انگشت از سمت چپ به سمت راست، از page با پوزیشن N به page با پوزیشن N - 1، و با کشیدن انگشت از سمت راست به سمت چپ، از page با پوزیشن N به page با پوزیشن N + 1 تغییر می‌یابد. این در حالی است که در حالت دیفالت و عملکرد طبیعی عمل swipe، می‌بایست با کشیدن انگشت از سمت چپ به سمت راست، از page با پوزیشن N به page با پوزیشن N + 1، و با کشیدن انگشت از سمت راست به سمت چپ، از page با پوزیشن N به page با پوزیشن N - 1 تغییر یابد. یعنی جهت تغییر pageها و پوزیشن می‌بایست برعکس جهت کشیدن انگشت بر روی ViewPager عمل کند. رفتاری که در طراحی‌های LTR به درستی نمایان شده و تنها در طراحی‌های RTL به مشکل برمی‌خورد. براساس مباحث مطرح شده در وب‌سایت‌هایی همچون stackoverflow، این مشکل در واقع یک باگ برای این  Layout Manager  محسوب می‌گردد.اما پس از جستجوها و آزمایش و خطاهای فراوان، سرانجام به راهکار عملی رفع این باگ به صورت غیرمستقیم رسیدم.قدم اول:viewPager.setRotationY(180);قدم دوم (در متد instantiateItem از PagerAdapter قبل از دستور return view):view.setRotationY(-180);</description>
                <category>رضا اصغری</category>
                <author>رضا اصغری</author>
                <pubDate>Mon, 01 Apr 2019 21:20:03 +0430</pubDate>
            </item>
                    <item>
                <title>حل مشکل اتصال به شبکه (مقصد فاقد TLS) و انتقال ترافیک cleartext در اندروید با API level 28</title>
                <link>https://virgool.io/MobileLab/%D8%AD%D9%84-%D9%85%D8%B4%DA%A9%D9%84-%D8%A7%D8%AA%D8%B5%D8%A7%D9%84-%D8%A8%D9%87-%D8%B4%D8%A8%DA%A9%D9%87-%D8%A8%D9%87-%D9%85%D9%82%D8%B5%D8%AF-%D9%81%D8%A7%D9%82%D8%AF-tls-%D9%88-%D8%A7%D9%86%D8%AA%D9%82%D8%A7%D9%84-%D8%AA%D8%B1%D8%A7%D9%81%DB%8C%DA%A9-cleartext-%D8%AF%D8%B1-%D8%A7%D9%86%D8%AF%D8%B1%D9%88%DB%8C%D8%AF-%D8%A8%D8%A7-api-level-28-dwi91swf6k6u</link>
                <description> چند روز پیش هنگام تست اپلیکیشن تحت وب خود در virtual device با API level 28 در اندروید استودیو، متوجه عدم عبور درخواست‌های خروجی از اپلیکیشن جهت اتصال به Web Service و دریافت دیتا از سرور شدم. مشکلی که هنگام تست اپلیکیشن در ورژن‌های پایین‌تر به هیچ وجه رخ نداده و در ابتدا فرض را بر داون شدن سرور گذاشتم. فرضی که با تست Web Service و همچنین اجرای مجدد اپلیکیشن در دیوایس‌های فیزیکی و مجازی با api levelهای پایین‌تر رد شد و متوجه شدم که این مشکل مختص ورژن 9 اندروید می‌باشد. البته بهتر است به جای واژه مشکل از اصطلاح محدودیت برای اشاره به این مساله استفاده کنیم چرا که در واقع باگ یا مشکلی در سمت اندروید عامل عدم موفقیت اپلیکیشن در برقراری ارتباط با شبکه اینترنت نبوده و این صرفا یک محدودیت امنیتی اعمال شده از سوی تیم توسعه دهنده اندروید در ورژن 9 از این سیستم‌عامل می‌باشد.اما این محدودیت امنیتی چیست؟در اندروید ورژن 9، پروتکل امنیتی TLS به صورت دیفالت از سوی سیستم عامل فعال شده و در حالت عادی تنها ارتباطات اینترنتی رمزنگاری شده توسط این پروتکل اجازه برقراری می‌یابند. با اعمال این محدودیت در اندروید ورژن 9 و بالاتر، متد isCleartextTrafficPermitted  که در واقع یک فلگ برای مشخص ساختن اجازه یا عدم اجازه انتقال ترافیک رمزنگاری نشده از دیوایس می‌باشد به صورت پیشفرض مقدار false را در پاسخ برگشت داده و بدین ترتیب ارتباطات اینترنتی بدون رمزنگاری یا به اصطلاح  cleartext network traffic از سوی لایه‌های امنیتی سیستم‌عامل اندروید بلاک شده و اجازه خروج از دیوایس را ندارند.وجود چنین محدودیتی منجر خواهد شد تا در صورت عدم پیاده‌سازی پروتکل امنیتی TLS در مقصد و در نتیجه عدم رمزنگاری داده‌های ارسالی و دریافتی با استفاده از این پروتکل، اپلیکیشن ما در اتصال به شبکه اینترنت ناکام مانده و در نتیجه برنامه تحت وب ما عملا از کار بیفتد. جهت رفع این محدودیت و دریافت مجوز انتقال ترافیک رمزنگاری نشده، می‌بایست دست به دامان پیکربندی امنیت شبکه (Network Security Configuration) شد. قابلیت تنظیم پیکربندی شبکه به توسعه‌دهندگان این امکان را می‌دهد که تنظیمات امنیتی شبکه مختص برنامه‌های خود را در یک فایل پیکربندی امن و بدون نیاز به تغییر کدهای برنامه انجام دهند. اضافه کردن فایل پیکربندی امنیت شبکه در پروژه اندرویدما می‌توانیم تنظیمات مد نظر خود جهت اعمال در پیکربندی امنیت شبکه را در یک فایل xml تعیین نموده (با ایجاد فایلی در دایرکتوری xml) و سپس این فایل را در فایل manifest پروژه خود بیفزاییم.&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;manifest ... &gt;
    &lt;application android:networkSecurityConfig=&quot;@xml/network_security_config&quot;
        ... &gt;
        ...
    &lt;/application&gt;
&lt;/manifest&gt;در ادامه جهت اعطای مجوز انتقال ترافیک cleartext جهت اتصال به سروهای فاقد پروتکل امنیتی TLS می‎بایست پیکربندی زیر را در فایل xml ایجاد شده قرار دهیم.&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;network-security-config&gt;
    &lt;base-config cleartextTrafficPermitted=&quot;true&quot;&gt;
        &lt;trust-anchors&gt;
            &lt;certificates src=&quot;system&quot; /&gt;
        &lt;/trust-anchors&gt;
    &lt;/base-config&gt;
&lt;/network-security-config&gt;</description>
                <category>رضا اصغری</category>
                <author>رضا اصغری</author>
                <pubDate>Wed, 27 Mar 2019 01:58:29 +0430</pubDate>
            </item>
                    <item>
                <title>آشنایی با واژه کلیدی super در جاوا و کاربردهای آن</title>
                <link>https://virgool.io/MobileLab/java-super-keyword-qvmca5tieaar</link>
                <description>این اولین نوشته من در ویرگول است و مطمانا کم‌تجربگی‌ام چه در زمینه نوشتن و چه در زمینه برنامه‌نویسی در پایین بودن کیفیت آن بی‌تاثیر نخواهد بود. اگر شما هم یک برنامه‌نویس جاوا و به صورت اختصاصی‌تر یک توسعه‌دهنده اپلیکیشن‌های اندرویدی با استفاده از این زبان برنامه‌نویسی هستید، مطمانا بارها و بارها با کلمه کلیدی super، به خصوص در شرایطی که قصد بازنویسی متدهای ارث‌بری شده از کلاس والد و یا ایجاد متد سازنده برای کلاس‌های فرزند خود را دارید، مواجه شده‌اید.با وجود گذشت بیش از یک سال از ورود به دنیای برنامه‌نویسی اندروید و آغاز توسعه اپلیکیشن برای این سیستم‌عامل موبایلی، و همچنین با وجود مواجهه روزانه با کلمه کلیدی super، اما هیچ‌گاه به دنبال یافتن ماهیت وجودی و کاربردهای آن نرفته و صرفا به استفاده و یا نادیده گرفتن آن بسنده کرده‌ام.اما حس کنجکاوی موجود در ذات هر انسان و به خصوص برنامه‌نویسی و همچنین ضرورت آشنایی با مفاهیم پایه و کاربردی زبان برنامه‌نویسی مورد استفاده در فرآیند توسعه نرم‌افزار، در نهایت منجر شد تا این کلمه کلیدی در ظاهر ساده اما بسیار پرکاربرد و مهم جاوا را با مراجعه به منابع مختلفی مورد مطالعه قرار داده و به سوالات شکل گرفته در ذهنم پاسخ‌هایی بیابم.هرچند که ممکن است این مبحث از سوی بسیاری از برنامه‌نویسان باتجربه جاوا/اندروید موضوعی ابتدایی و ساده تلقی شود، اما تصمیم گرفتم تا با انتشار خلاصه‌ای از یافته‌هایم در خصوص دستور super آن را با سایر برنامه‌نویسان مبتدی اندروید و هم‌سطح با خودم به اشتراگ بگذارم تا شاید مفید واقع گردد. جهت توضیح ماهیت و کاربرهای کلمه کلیدی super، ابتدا لازم است تا با اصطلاحات super class و sub class در زبان برنامه‌نویسی جاوا آشنا شویم.در جاوا یک کلاس می‌تواند ویژگی‌ها (Attributes) و متدهای (Methods) کلاس دیگری را ارث‌بری کند. در فرآیند ارث‌بری با دو دسته از کلاس‌ها سروکار داریم:سوپرکلاس‌ (Super Class): کلاس والدی که از آن ارث‌بری می‌شودساب‌کلاس (Sub Class): کلاس فرزندی که از یک کلاس والد ارث‌بری می‌کنددر جاوا برای آنکه یک کلاس از کلاس دیگر ارث‌بری کند، باید از کلمه کلیدی extends استفاده کنیم.نکته قابل توجه در خصوص ارث‌بری در جاوا این است که ساب‌کلاس یا کلاس‌های فرزند یا کلاس‌هایی که ارث‌بری می‌کنند تنها می‌توانند به ویژگی‌ها (متغیرها یا پارامترها) و متدهایی از سوپرکلاس والد دسترسی داشته باشند که access modifier آنها یا از نوع public باشد یا protected. به بیانی دیگر، کلاس فرزند نمی‌تواند به متدها یا ویژگی‌هایی از سوپرکلاس دسترسی داشته باشد و آن‌ها را به ارث برد که از نوع private باشند.در جاوا کلاس  java.lang.Object در راس سلسله‌مراتب ارث‌بری کلاس‌ها قرار داشته و تمامی کلاس‌ها چه به صورت مستقیم و چه به صورت غیرمستقیم از این سوپرکلاس والد ارث‌بری می‌کنند. هر چه در سلسله‌مراتب ارث‌بری کلاس‌ها به پایین بیاییم (از والد به سمت فرزندها)، کلاس‌ها اختصاصی‌تر می‌شوند. حال که با مفاهیم Super Class و Sub Class در جاوا آشنا شدیم، می‌توانیم به تشریح کلمه کلیدی و دستور super بپردازیم.به مثال زیر که درواقع بازنویسی متد onCreate از سوپرکلاس AppCompatActivity در ساب‌کلاس MainActivity در یک پروژه اندروید می‌باشد توجه کنید:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
   // rest of the code
}در بازنویسی این متد شاهد استفاده از دستور super می‌باشیم. همانطور که می‌توان حدس زد، نام این کلمه کلیدی با مفهوم super class بی‌ارتباط نیست. همانطور که در بالا نیز اشاره شد، در جاوا زمانی که کلاسی از کلاس دیگری ارث‌بری می‌کند، می‌توان متدهای غیر private کلاس والد را براساس نیازهای خودمان بازنویسی کرده و رفتار آنها را تغییر دهیم. در پروسه بازنویسی متدهای کلاس والد در کلاس فرزند، دو رویکرد پیش‌روی برنامه‎نویسان و توسعه‌دهندگان قرار دارد.بازنویسی و جایگزینی کامل متد توسعه متد موجود در کلاس والد و اینجا است که دستور super وارد عمل شده و امکان پیاده‌سازی رویکرد دوم را برای برنامه‌نویس عملی می‌سازد. در واقع در مثال فوق، با افزودن تکه کد  super.onCreate(savedInstanceState); به ابتدای متد بازنویسی شده، به ماشین مجازی Dalvik می‌گوییم که کد نوشته شده توسط ما را همراه با کدهای موجود در متد onCreate سوپرکلاس AppCompatActivity به اجرا درآورد و با حذف این statement فقط و فقط کدهای نوشته شده توسط ما به اجرا درخواهد آمد.به بیانی دیگر می‌توان گفت در صورتی که قصد داشته باشیم تا علاوه بر رفتار مورد انتظار ما از یک متد، رفتار تعیین شده از سوی کلاس والد نیز در خروجی متد ارث‌بری شده اعمال گردد، از دستور super استفاده می‌کنیم. به منظور درک کامل کاربرد کلمه کلیدی super به مثال زیر توجه کنید. کلاس زیر را به عنوان یک super class با قابلیت ارث‌بری از آن که دارای متدی تحت عنوان print() می‌باشد، در نظر بگیرید:public class Superclass {
    public void print() {
        System.out.println(&quot;Printed in Superclass.&quot;);
    }
} 
 کلاس زیر را نیز به عنوان یک sub class که از کلاس Superclass  فوق ارث‌بری کرده و متد print() آن را بازنویسی می‌کند در نظر بگیرید:public class Subclass extends Superclass {
    // overrides print in Superclass
    public void print() {
        super.print();
        System.out.println(&quot;Printed in Subclass&quot;);
    }
    public static void main(String[] args) {
        Subclass s = new Subclass();
        s.print();    
    }
}زمانی که در کلاس فرزند، با استفاده از نمونه‌سازی، متد print را صدا می‌زنیم، در واقع متد print واقع در خود کلاس فرزند به اجرا درمی‌آید. متدی که خود یک بازنویسی از متد print موجود در کلاس والد می‌باشد. با توجه به استفاده از دستور super در ابتدای متد بازنویسی شده در کلاس فرزند، همانطور که حدس می‌زنیم خروجی اجرای کد فوق می‌بایست بدین شکل باشد:Printed in Superclass.
Printed in Subclassچرا که ما متد print را به صورت کامل بازنویسی نکرده و آن را با استفاده از دستور super توسعه دادیم. یعنی علاوه بر کدهای موجود در بدنه این متد در کلاس فرزند، کدهای موجود در بدنه متد مدنظر در کلاس والد نیز به اجرا درخواهند آمد.یکی دیگر از کاربردهای super، استفاده از آن در متدهای سازنده کلاس‌های فرزند (Subclass Constructors) به منظور فراخوانی متد سازنده سوپرکلاس در متد سازنده ساب‌کلاس می‌باشد. فراخوانی سازنده کلاس والد در بدنه سازنده کلاس فرزند می‌بایست در خط اول از متد صورت گیرد. public Subclass () {
    super(); //  invoke superclass&#039;s constructor
    // Subclass Constructor codes
}   </description>
                <category>رضا اصغری</category>
                <author>رضا اصغری</author>
                <pubDate>Wed, 27 Mar 2019 00:46:37 +0430</pubDate>
            </item>
            </channel>
</rss>