05 مرداد 1402
اگر نیازی به ارسال پیامک انبوه نداشته باشیم و بخواهیم بهصورت شخصی (بدون استفاده از پنلهای پیامکی رایج) اقدام به دریافت و ارسال پیامک کنیم، مودمهای GSM دارای سیمکارت، میتوانند گزینه مناسبی باشند؛ بهخصوص اگر بتوانیم با اتصال آن به نرمافزار خودمان پیامکها رو مدیریت کنیم.
در اینجا به بررسی جیاسام مودم Huawei مدل E3372 میپردازیم که از طریق اتصال USB به رایانه ما متصل میشود. بعد از شناخته شدن دستگاه توسط ویندوز، علاوه بر اینکه یک پنل کاربری در اختیارمان قرار میدهد، به کمک برنامهنویسی و دستورات cURL هم میشود با مودم ارتباط گرفت که موضوع مقاله ماست.
الف) نصب مودم در ویندوز
ب) چگونگی ارتباط با مودم
الف) نصب مودم در ویندوز: اولین باری که مودم را به پورت USB متصل میکنیم میبایست به My Computer ویندوز رفته و درایوری که در این صفحه و در کنار سایر پارتیشنها ظاهر شده رو نصب کنیم. پس از نصب علاوه بر اینکه - بهصورت خودکار - یک کانکشن شبکه جدید در ویندوز ساخته میشود، با وارد کردن آدرس 192.168.8.1 در مرورگر میتوانیم به پنل کاربری دسترسی داشته باشیم.
در پنل کاربری مودم امکاناتی مثل نمایش وضعیت آنتن، فهرست پیامهای دریافتی و ارسالی، ارسال و حذف پیامک، موجودی سیمکارت از طریق شمارهگیری USSD و سایر قابلیتهای دیگر را میتوان مشاهده کرد.
ب) چگونگی ارتباط با مودم: در مخزن github کتابخانههایی را - به زبانهای برنامهنویسی گوناگون - میتوانید برای اتصال و ارتباط نرمافزار خود با این نوع مودمها پیدا کنید اما ما در اینجا بدون نصب کتابخانه از طریق دستورات cURL و زبان PHP قصد داریم مراحل زیر را انجام دهیم:
1) بررسی وضعیت مودم
2) دریافت توکن
3) فهرست پیامکها
4) اعلانها
5) ارسال پیامک
6) حذف پیامک
7) مشاهده اعتبار
در ادامه هر یک از موارد رو شرح داده و تابعی برای آن پیشنهاد میدهم. خروجی توابع xml بوده و همانطور که در بالا گفته شد برای دسترسی به مودم از آدرس 192.168.8.1 استفاده خواهیم کرد. یادآوری میکنم توابع دیگری هم با جستجو در اینترنت میتوانید پیدا کنید اما چندان ضروری و کاربردی نیستند.
1) بررسی وضعیت مودم:
برای دریافت وضعیت مودم میبایست درخواست خود رو با استفاده از متد cURL به آدرس api/monitoring/status ارسال کنیم.
<?php $url = "http://192.168.8.1/api/monitoring/status"; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 300); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); $result = curl_exec($curl); curl_close($curl); $xml = new simpleXMLElement($result); echo json_encode($xml); ?>
چنانچه ارتباط با مودم برقرار باشد، پارامترهای خروجی عبارتند از:
پارامتر ConnectionStatus: کد وضعیت اتصال مودم مانند وصل، قطع و ...
پارامتر SignalIcon: میزان آنتندهی سیمکارت
پارامتر maxsignal: حداکثر آنتندهی
پارامتر CurrentNetworkType: کد نوع شبکه مانند No Service، GPRS، LTE و...
پارامتر RoamingStatus: وضعیت رومینگ
پارامتر ServiceStatus: کد وضعیت سرویس
پارامترSimStatus: کد وضعیت سیمکارت
2) دریافت توکن:
در اکثر توابع مهم در مودم نیاز به استفاده از یک «توکن» داریم و بدون آن پاسخی از مودم دریافت نخواهیم کرد. بههمین منظور بهکمک این تابع ابتدا یک «Token» دریافت کرده تا در توابع بعدی از آن بهره بگیریم.
<?php $url = "http://192.168.8.1/api/webserver/token"; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 300); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); $result = curl_exec($curl); curl_close($curl); $xml = new simpleXMLElement($result); echo json_encode($xml); ?>
امکان دارد در برخی از مدلهای مودم بهجز E3372 آدرس وبسرویس فوق و خروجی آن کمی متفاوت باشد اما خروجی این تابع تنها یک پارامتر است:
پارامتر token: مقدار «توکن» جهت استفاده در سایر توابع.
3) فهرست پیامکها:
برای مشاهده و فهرست کردن پیامکهای دریافتی و ارسالی از کدهای زیر استفاده میکنیم. این تابع نیاز به ورودیهایی دارد که با ارسال آن به آدرس api/sms/sms-list میتوان گزارش دلخواه را مشاهده کرد.
پارامتر token: توکن به دست آمده از تابع قبل را جایگزین عبارت <your_token> در تابع زیر میکنیم
متغیر PageIndex و ReadCount: فرض کنید تعداد 50 پیامک ارسال کردهایم که در 5 صفحه 10 تایی مرتب شدهاند؛ PageIndex شماره صفحه و ReadCount تعداد پیامک در صفحه است.
متغیر BoxType: چنانچه مقدار این متغیر «1» باشد، پیامکهای دریافتی نمایش داده میشود و چنانچه «2» باشد، پیامکهای ارسالی
متغیر SortType و Ascending: نوع مرتبسازی فهرست را مشخص میکنند
متغیر UnreadPreferred: پیامکهای دریافتی خوانده نشده را در ابتدای فهرست قرار میدهد
<?php $headers = array( "__RequestVerificationToken: <your_token>", "X-Requested-With: XMLHttpRequest", "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" ); $post_data = ' <?xml version="1.0" encoding="UTF-8"?> <request> <PageIndex>1</PageIndex> <ReadCount>10</ReadCount> <BoxType>1</BoxType> <SortType>0</SortType> <Ascending>0</Ascending> <UnreadPreferred>0</UnreadPreferred> </request>'; $curl = curl_init('http://192.168.8.1/api/sms/sms-list'); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 300); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); $result = curl_exec($curl); curl_close($curl); $xml = new simpleXMLElement($result); echo json_encode($xml,JSON_UNESCAPED_UNICODE); ?>
خروجی تابع فوق 10 پیامک دریافتی اخیر را با تمام جزییات نمایش میدهد:
پارامتر Count: تعداد کل پیامکهای این گزارش
پارامتر Messages: آرایهای از Message ها که خود دارای پارامترهای زیر است:
پارامتر Smstat: وضعیت پیامک به صورت نخوانده، خواندهشده، ارسال شده و...
پارامتر Index: شماره ردیف مختص هر پیامک
پارامتر Phone: شماره تماس گیرنده یا فرستنده
پارامتر Content: متن پیامک
پارامتر Date: زمان ارسال
پارامتر SaveType: نوع ذخیره پیامک در سیمکارت ذخیره شده است یا دستگاه
پارامتر Priority: اهمیت پیامک که عادی است یا بالا
پارامتر SmsType: نوع پیامک که عادی است یا از نوع فلش اساماس
خروجی تابع فوق مانند خطوط زیر است و برای دسترسی به هر یک از پارامترها مانند Index میتوانید از چنین دستوری استفاده نمایید: $xml->Messages->Message[0]->Index
{ "Count":"3", "Messages":{ "Message":[{ "Smstat":"3","Index":"40027","Phone":"09350000000","Content":"صبح بخیر","Date":"2023-08-02 19:21:38","Sca":{},"SaveType":"3","Priority":"4","SmsType":"1" },{ "Smstat":"3","Index":"40026","Phone":"09350000000","Content":"سلام. خوبی؟","Date":"2023-08-02 13:31:32","Sca":{},"SaveType":"3","Priority":"4","SmsType":"1" },{ "Smstat":"3","Index":"40025","Phone":"09350000000","Content":"درود","Date":"2023-08-02 13:30:38","Sca":{},"SaveType":"3","Priority":"4","SmsType":"1" }] } }
4) اعلانها:
تعداد پیامکهای دریافتی یا Inbox که هنوز خوانده نشدهاند توسط آدرس api/monitoring/check-notifications و بدون نیاز به ارسال توکن و داده ورودی نمایش داده میشوند.
<?php $url = "http://192.168.8.1/api/monitoring/check-notifications"; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 300); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); $result = curl_exec($curl); curl_close($curl); $xml = new simpleXMLElement($result); echo json_encode($xml,JSON_UNESCAPED_UNICODE); ?>
خروجی تابع دو پارامتر دیگر نیز به ما نشان می دهد:
پارامتر UnreadMessage: تعداد پیامکهای خوانده نشده
پارامتر SmsStorageFull: پر بودن حافظه
پارامتر OnlineUpdateStatus: وضعیت آپدیت آنلاین
5) ارسال پیامک:
برای ارسال پیامک که مهمترین تابع ماست نیاز به چند ورودی داریم که بایستی آنها را از طریق نشانی api/sms/send-sms به مودم ارسال کنیم.
پارامتر token: توکن به دست آمده از بخش «۲» را جایگزین عبارت <your_token> در تابع زیر میکنیم
متغیر Index: مقدار پیشفرض آن را برابر «-1» قرار میدهیم.
متغیر Phones: آرایهای از شمارههای تماس، یک یا چند Phone که قصد داریم پیامک را به آن شماره (ها) ارسال کنیم
متغیر Content: شرح پیامک
متغیر Length: طول شرح پیامک
متغیر Reserved: مقدار پیشفرض این متغیر «۱» است
متغیر Date: زمان ارسال به صورت میلادی (با فرمت سال-ماه-روز ساعت:دقیقه:ثانیه)
متغیر SendType: نوع ارسال با مقدار پیشفرض «0»
<?php $headers = array( "__RequestVerificationToken: <your_token>", "X-Requested-With: XMLHttpRequest", "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" ); $post_data = ' <?xml version="1.0" encoding="UTF-8"?> <request> <Index>-1</Index> <Phones> <Phone>09150000000</Phone> </Phones> <Sca/> <Content>درود</Content> <Length>4</Length> <Reserved>1</Reserved> <Date>'.date('Y-m-d H:i:s').'</Date> <SendType>0</SendType> </request>'; $curl = curl_init('http://192.168.8.1/api/sms/send-sms'); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 300); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); $result = curl_exec($curl); curl_close($curl); echo $result; ?>
خروجی تابع یک پیام حاوی شرح «OK» و یا شرح خطای ارسال خواهد بود.
6) حذف پیامک:
بهدلیل احتمال پر شدن حافظه دستگاه، بهتر است پیامکها را - پس از ارسال یا دریافت - ابتدا در دیتابیس نرم افزار خود ذخیره کرده و سپس با دستور زیر از مودم پاک کنیم. برای این منظور نیاز به ورودیهای زیر داریم که با ارسال آن به آدرس api/sms/delete-sms بتوانیم پیامک را حذف کنیم.
پارامتر token: توکن به دست آمده از بخش «۲» را جایگزین عبارت <your_token> در تابع زیر میکنیم
متغیر Index: شماره ردیف پیامک مورد نظر.
<?php $headers = array( "__RequestVerificationToken: <your_token>", "X-Requested-With: XMLHttpRequest", "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" ); $post_data = ' <?xml version="1.0" encoding="UTF-8"?> <request> <Index>40027</Index> </request>'; $curl = curl_init('http://192.168.8.1/api/sms/delete-sms'); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 300); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); $result = curl_exec($curl); curl_close($curl); echo $result; ?>
در اینجا نیز خروجی تابع یک پیام حاوی شرح «OK» و یا شرح خطای ارسال خواهد بود.
7) مشاهده اعتبار:
مشاهده مانده اعتبار سیمکارت با ارسال کد USSD توسط توابع زیر امکانپذیر است. روش کار به این صورت است که یک بار کد دستوری را send کرده، صبر میکنیم و بار دوم کد دستوری استعلام اپراتور را get و نتیجه استعلام را مشاهده میکنیم. دادههای مورد نیاز برای ارسال به توابع عبارتند از:
پارامتر token: توکن به دست آمده از بخش «۲» را جایگزین عبارت <your_token> در تابع زیر میکنیم
متغیر content: کد دستوری استعلام اپراتور مانند *555*1*2#
متغیر CodeType: با مقدار پیشفرض CodeType
<?php $headers = array( "__RequestVerificationToken: <your_token>", "X-Requested-With: XMLHttpRequest", "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" ); $post_data = ' <?xml version="1.0" encoding="UTF-8"?> <request> <content>*555*1*2#</content> <CodeType>CodeType</CodeType> </request>'; $curl = curl_init('http://192.168.8.1/api/ussd/send'); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 300); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); $result = curl_exec($curl); curl_close($curl); echo $result; ?>
پس از اجرای موفق یا OK تابع چند ثانیهای صبر می کنیم و تابع بعدی را جهت مشاهده نتیجه فراخوانی میکنیم.
<?php $headers = array( "__RequestVerificationToken: <your_token>", "X-Requested-With: XMLHttpRequest", "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" ); $post_data = ' <?xml version="1.0" encoding="UTF-8"?> <request> <content>*555*1*2#</content> <CodeType>CodeType</CodeType> </request>'; $curl = curl_init('http://192.168.8.1/api/ussd/get'); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 300); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); $result = curl_exec($curl); curl_close($curl); echo $result; ?>
نتیجه استعلام که همان میزان موجودی شارژ است در خروجی این تابع نمایش داده خواهد شد
در پایان لازم است یادآوری کنم استفاده از این مودم در سرور مجازی به راحتی ممکن نیست؛ حداقل من نتوانستم در نسخههای Esxi 6 و Esxi 8 از آن استفاده کنم. محدودیت دیگری که به آن برخوردم این است که بهدلیل عدم تغییر IP پیشفرض E3372، نمیتوان دو عدد از این مودم را در یک سیستم مورد استفاده قرار داد.