AWS IAM 使用者

到 AWS IAM 服務中增加一個使用者帳號或在現有帳號中賦予 AmazonSNSFullAccess 權限並取得 Access Key 與 Secret Access Key

安裝 aws/aws-sdk-php-laravel 套件

# 安裝
composer require aws/aws-sdk-php-laravel
# 產生設定檔
php artisan vendor:publish  --provider="Aws\Laravel\AwsServiceProvider"

修改 .env 及 config\aws.php

.env 加入 Access Key 與 Secret Access Key 及區域,若有使用其它服務,例如: AWS S3 則新增 AWS_BUCKET

AWS_ACCESS_KEY_ID=取得的 Access Key
AWS_SECRET_ACCESS_KEY=取得的 Secret Access Key
AWS_DEFAULT_REGION=預設所在區域ex: us-east-1
AWS_S3_DEFAULT_REGION=S3所在區域ex: ap-east-1
AWS_SNS_DEFAULT_REGION=SNS所在區域ex: us-east-1
AWS_SES_DEFAULT_REGION=SES所在區域ex: ap-southeast-1
AWS_BUCKET= S3 Bucket 名稱

修改 config\aws.php 由於 SNS 服務在 ap-east-1 並不提供 Moblie 功能,須改到 us-east-1 區域,所以將所有服務區分開來指定區域.

<?php

use Aws\Laravel\AwsServiceProvider;

return [

    /*
    |--------------------------------------------------------------------------
    | AWS SDK Configuration
    |--------------------------------------------------------------------------
    |
    | The configuration options set in this file will be passed directly to the
    | `Aws\Sdk` object, from which all client objects are created. This file
    | is published to the application config directory for modification by the
    | user. The full set of possible options are documented at:
    | http://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/configuration.html
    |
    */
    'credentials' => [
        'key'    => env('AWS_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
    ],
    // 'region' => env('AWS_DEFAULT_REGION'),
    'version' => 'latest',

    // You can override settings for specific services
    's3' => [
        'region' => env('AWS_S3_DEFAULT_REGION'),
    ],
    'sns' => [
        'region' => env('AWS_SNS_DEFAULT_REGION'),
    ],
    'ses' => [
        'region' => env('AWS_SES_DEFAULT_REGION'),
    ]
];

修改 config\app.php

'providers' => [
    ....
    //AWS
    Aws\Laravel\AwsServiceProvider::class,
],

'aliases' => [
    ....
    // AWS
    'AWS' => Aws\Laravel\AwsServiceProvider::class,
],

修改路由

//後台發送簡訊功能測試
Route::get('sms/sendsms','Admin\SMSController@adminSendSMSForm');
Route::post('sms/awssms','Admin\SMSController@awssms')->name('awssms');

建立表單

<form id="myform" action="{{ route('admin.awssms') }}" method="POST" role="form">
    @csrf
    <div class="card-body">
        <div class="form-group">
            <label for="exampleInputEmail1">To</label>
            <div class="input-group">
                <div class="input-group-prepend">
                  <span class="input-group-text"><i class="fas fa-phone"></i></span><span class="input-group-text">+886</span>
                </div>
                {{-- <input class="form-control {{ $errors->has('phone') ? ' is-invalid' : '' }}" type="tel" id="phone" name="phone" pattern="[+]{1}[0-9]{11,14}" placeholder="輸入行動電話號碼,包含國碼及+號" required> --}}
                {{-- <input class="form-control {{ $errors->has('phone') ? ' is-invalid' : '' }}" type="tel" id="phone" name="phone" pattern="[0-9]{9,11}" placeholder="輸入行動電話號碼" required> --}}
                <input class="form-control {{ $errors->has('phone') ? ' is-invalid' : '' }}" type="number" id="phone" name="phone" pattern="[0-9]" placeholder="輸入行動電話號碼">
                @if ($errors->has('phone'))
                <span class="invalid-feedback" role="alert">
                    <strong>{{ $errors->first('phone') }}</strong>
                </span>
                @endif
              </div>
        </div>
        <div class="form-group">
            <label>內容</label>
            <textarea class="form-control {{ $errors->has('content') ? ' is-invalid' : '' }} " rows="3" id="content" name="content" placeholder="輸入訊息內容"></textarea>
            @if ($errors->has('content'))
            <span class="invalid-feedback" role="alert">
                <strong>{{ $errors->first('content') }}</strong>
            </span>
            @endif
        </div>
    </div>
    <div class="card-footer text-center">
        <button type="submit" class="btn btn-primary">發送</button>
    </div>
</form>

建立 Request 驗證

php artisan make:request Admin\adminSendSMSRequest
<?php

namespace App\Http\Requests\Admin;

use Illuminate\Foundation\Http\FormRequest;
use Auth;

class AdminSendSMSRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    //必須登入才可以使用這個Request
    public function authorize()
    {
        return Auth::check();
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    //欄位規則
    public function rules()
    {
        return [
            // 'phone'=>'required|digits:10',
            // 'phone'=>'required|numeric|between:9,11',
            'phone'=>'required|regex:/[0-9]{9,11}/',
            // 'phone'=>'required|regex:/(01)[0-9]{9}/',
            // 'phone'=>'required|regex:/^([0-9\s\-\+\(\)]*)$/|min:10',
            'content'=>'required|string|max:100',
        ];
    }
}

建立 Controller

php artisan make:controller Admin\SMSController
<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

use View;
use Redirect;
use Carbon\Carbon;
use Session;
use AWS;

use App\Http\Requests\Admin\AdminSendSMSRequest;

class SMSController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth:admin');
    }
    /**
     * Display the SMS Form.
     *
     * @return \Illuminate\Http\Response
     */
    public function adminSendSMSForm()
    {
        return view('admin.sms.adminsendSMSform');
    }
    /**
     * 透過 AWS SNS 傳送 SMS
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function awssms(AdminSendSMSRequest $request)
    {
        $phone = '886' . ltrim($request->phone, "0");       //去除掉左邊 0 並加上國碼
        $content = $request->content;                       //訊息內容
        try {
            $sms = AWS::createClient('sns');                //建立 AWS sns 類
            $sms->publish([
                'Message' => $content,                      //訊息內容
                'PhoneNumber' => $phone,                    //行動電話號碼 須符合 E.164 格式,ex: 886990123456
                'MessageAttributes' => [                    //訊息屬性
                    'AWS.SNS.SMS.SMSType'  => [             //訊息類型
                        'DataType'    => 'String',          //資料類型 字串
                        'StringValue' => 'Transactional',   //性質 Transactional (交易類) Promotional (行銷類)
                    ]
               ],
            ]);
        } catch (Exception $e) {
            $message = "簡訊傳送失敗";
            Session::put('error', $message);
        }

        $message = "簡訊已傳送給 $request->phone";
        Session::put('success', $message);

        return view('admin.sms.adminsendSMSform');
    }
}

相關參數設定,參考 發布到行動電話 – Amazon Simple Notification ServiceAWS SDK for PHP 3.x (amazon.com)

測試

最後修改日期: 2020 年 11 月 28 日