Laravel 문자메시지 보내기

sms
Standard

(수정: APIStore 를 이용하여 저렴하게 문자메시지를 보낼수 있는 오픈소스가 https://github.com/jinseokoh/sms 에 공개되어 있습니다.)

미국같았으면 당연히 Twilio API 를 통해서 SMS 를 보냈겠지만, 국내 사용자를 대상으로 SMS 를 보낼때, 국내 업체를 통하는 것이 2-3 배 저렴하다. 단점은 10년전 만들어진 legacy API class 를 직접 뜯어고쳐서 사용해야 한다는 불편함과, sample 코드에 문제가 있어도 정작 그 회사에서는 아무도 tech support 를 안한다는… 한국 IT 의 암울한 현주소. 어쨌든 들어는 봤었을 법한 후이즈 (Whois) 라는 회사의 서비스를 통해서 SMS 를 보내보자.

해당 회사에서 제공하는 샘플코드에는 2개의 레거시 클래스가 있지만, PHP 5.6 에서는 동작하지 않았다. xmlpc.inc.php 라는 파일은 http://gggeek.github.io/phpxmlrpc/ 에서 최신판으로 바꾸고, app/classes 라는 폴더에 넣는다. (그런 다음 php artisan dump-autoload 명령 실행) 나머지 EmmSMM.php 라는 클래스는 지워버린다.

다른 외부 API 서비스들의 credentials 을 저장하는 것과 마찬가지로, app/config/services.php 파일을 열고 후이즈에서 계약당시 받은 계정 아이디와 비밀번호를 아래와 같이 추가한다.

    return array(
        :
        'whois' => [
            'Id' => 'hanlingo.com',
            'Pass' => 'dumbass!'
        ]

    );

그런 다음, App/Sms 폴더에, 아래와 같은 내용으로 WhoIsSms.php 파일을 만든다.

    <?php namespace Teeshot\Sms;

    class WhoIsSms {

        protected $args;
        protected $host;
        protected $port;
        protected $path;
        protected $errMsg;

        public function __construct($app) {
            $this->args = $app['config']['services.whois'];
            $this->host = "www.whoisweb.net";
            $this->port = 80;
        }

        private function setURL($url) {
            if (!$m = parse_url($url))
                return $this->setError("Can't parse the URL provided.");

            $this->host = $m['host'];
            $this->port = isset($m['port']) ? $m['port'] : 80;
            $this->path = ($m['path']) ? $m['path'] : "/";

            return true;
        }

        private function setError($msg) {
            $this->errMsg = $msg;

            return false;
        }

        private function xmlrpc_send($func, $args) {
            $server = new \xmlrpc_client($this->path, $this->host, $this->port);
            $message = new \xmlrpcmsg($func, array(php_xmlrpc_encode($args)));
            $result = $server->send($message);

            if ($result) {
                if ($ret = $result->value()) {
                    return php_xmlrpc_decode($ret);
                } else {
                    return $this->setError($result->faultCode().":".$result->faultString());
                }
            }

            return $this->setError("Transmission error.");
        }

        public function send($To, $From, $Message, $Date='', $SmsType='') {
            if (is_array($To))
                $this->args['To'] = implode(",", $To);
            else
                $this->args['To'] = $To;
            $this->args['From'] = $From;
            $this->args['Message'] = $Message;
            $this->args['Date'] = $Date;
            $this->args['SmsType'] = $SmsType;

            $this->setURL("http://www.whoisweb.net/emma/API/EmmaSend_All.php");
            foreach ($this->args as $key => $value)
                $args[$key] = base64_encode($value);
            $res = $this->xmlrpc_send('EmmaSend', $args);

            if ($res['Code'] != '00')
                return $this->setError($res['CodeMsg']);
            return $res;
        }

        // $message = '[티샷] 비밀번호: '.$secret;
        public function sendSMS($phone, $message) {
            $result = $this->send($phone, '02-2277-3489', $message, '', '');

            if ($result['Code'] == '00') {
                if (intval($result['LastPoint']) < 100) {
                    // inform admin that there are less than 100 points left
                }
                return null;
            }
            return $this->errMsg;
        }

    }

WhoIsSms::sendSMS(‘보낼 번호’, ‘보낼 메시지’) 형식으로 사용할 수 있도록, 서비스 프로바이더와 파싸드를 만든다.

App/Providers/SmsServiceProvider.php 를 생성하고

    <?php namespace App\Providers;

    use Illuminate\Support\ServiceProvider;
    use App\Sms\WhoIsSms;

    class SmsServiceProvider extends ServiceProvider {

        protected $defer = false;

        public function register()
        {
            $this->app->bindShared('sms', function($app) {
                return new WhoIsSms($app);
            });
        }
    } 

App/Providers/Facades/WhoIsSms.php 를 생성하고

    <?php namespace App\Providers\Facades;

    use Illuminate\Support\Facades\Facade;

    class WhoIsSms extends Facade {

        protected static function getFacadeAccessor() {
            return 'sms';
        }
    }

라고 입력한다. app/config/app.php 의 providers 배열과 aliases 배열안에 아래의 라인을 삽입하면,

    'App\Providers\SmsServiceProvider',

    'WhoIsSms' => 'App\Providers\Facades\WhoIsSms',

이제 당신의 애플리케이션 어디에서든

\App\Providers\Facades\WhoIsSms::sendSMS(‘010-9486-7415’, ‘hello there. I am baymax.’);

라고 사용할 수 있지롱.