apexからPOSTでファイルを送信する 改訂版

前回のファイル送信の動作確認版。

まず、やりたいこととして、
saleseforceで作成したページからファイルをherokuで作成したapiに送信して、
herokuのapiからそのファイルを添付で送信したかった。

結論としては以下の手順で動作した。

  1. visualforceでapex:inputFileを使用してファイルをアプロード
  2. apexでファイルを受け取り、そのファイルをbase64エンコード
  3. base64エンコードした文字列をPOSTのパラメータとして送信
  4. herokuにアップしているphpでPOSTデータを受け取る
  5. 受け取ったbase64データをデコードして保存(一時的)
  6. 保存されたファイルからQdmailを使用してメールを送信

1) visualforceでapex:inputFileを使用してファイルをアプロード
visualforceページでのinputの書き方

<apex:input value="{!Email}" />
<apex:inputFile value="{!FileBody}" filename="{!FileName}"/>

2) apexでファイルを受け取り、そのファイルをbase64エンコード
3) base64エンコードした文字列をPOSTのパラメータとして送信
apex側で受け取る

public String FileName { get; set; }
public Blob FileBody { get; set; }
public String Email { get; set; }

public Pagereference submit() {
    HttpRequest request = new HttpRequest();
    request.setEndpoint('送信先のphp');
    request.setMethod('POST');
    request.setHeader('Accept-Language', 'ja');
    //パラメータ
    Map<String, String> params = new Map<String, String>();
    params.put('to', Email);  //送信先
    params.put('attachName', FileName); //ファイル名
    params.put('attach', EncodingUtil.base64Encode(FileBody)); //ファイル内容
    Set<String> keys = params.keySet();
    String r = '';
    for(String key : keys) {
        //body用にパラメータを整形 to=xx&attach=xx のように
        String val = params.get(key);
        r += key + '=';
        if(val != null) r += val;
        r += '&';
    }
    r = r.removeEnd('&');
    request.setBody(r);

    //送信
    Http http = new Http();
    HttpResponse response = http.send(request);
    ResResult = response.getBody(); //結果を受け取る
}

4) herokuにアップしているphpでPOSTデータを受け取る
5) 受け取ったbase64データをデコードして保存(一時的)
6) 保存されたファイルからQdmailを使用してメールを送信

Qdmailでの送信方法は以前の投稿を参照。

require_once('../lib/qdmail.php');
require_once('../lib/qdsmtp.php');

//送信内容
$to          = $_POST['to'];
$subject     = '件名';
$body        = '本文';
$fromname    = '送り先名';
$fromaddress = '送り先アドレス';
$attachname  = $_POST['attachName'];
$attach      = $_POST['attach'];

$mail = new Qdmail();
$mail -> smtp(true);
$param = array(
    'host'=> $_ENV['MAILGUN_SMTP_SERVER'],
    'port'=> $_ENV['MAILGUN_SMTP_PORT'],
    'from'=> $fromaddress,
    'protocol'=>'SMTP_AUTH',
    'user'=> $_ENV['MAILGUN_SMTP_LOGIN'],
    'pass' => $_ENV['MAILGUN_SMTP_PASSWORD']
);
$mail ->smtpServer($param);
$mail ->to($to);
$mail ->subject($subject);
$mail ->from($fromaddress,$fromname);
$mail ->text($body);

//添付ファイル
$bin = base64_decode(str_replace(' ', '+', $_POST['attach'][0])); //注意
$fp = fopen( "./" . $_POST['attachName'][0], "w" );
fwrite( $fp, $bin );
fclose( $fp );
$attach = array();
$attach[] = array( "./" . $_POST['attachName'][0] , $_POST['attachName'][0] );

//送信
echo $mail ->send(); //成功の場合は「1」が返ってくる

Base64デコードしてファイルに保存する方法は以下を参考にしました。
Flashからアップロードする方法いろいろ
ただし、そのままではエラーになることがあるよう。

どうやら、POSTでデータを渡すと、Base64の「+」記号が勝手にスペースに変換されてしまうらしい。
http://pontago.hatenablog.com/entry/20091028/1256743421

(ヘッダ分を差し引く、の部分は無視しても問題なかった)

   このエントリーをはてなブックマークに追加