ケータイFlashのmailtoリンクを3キャリア対応にしてみよう

By ookura - 09/10/01 - このエントリをはてなブックマークに追加このエントリをYahoo!ブックマークに追加このエントリをdel.icio.usに追加このエントリをFC2ブックマークに追加

ケータイFlashでmailtoリンクを設置する場合、メールアドレスだけであれば問題ないのですが、件名や本文を設定する場合はキャリアやFlashバージョンによって仕様が異なるため、文字化けしたり改行が消えてしまったりすることがあります。
 
そこで本記事ではswfmillでの動的生成を併用してmailtoリンクを3キャリア対応にする方法をご紹介します。
 
※確認に使用した端末は以下の通りです。
DoCoMo N903i(FlashLite1.1)
DoCoMo SH-03A(FlashLite3.0)
au W41CA(FlashLite1.1)
au W51CA(FlashLite2.0)
au CA001(FlashLite3.0)
SoftBank 912T(FlashLite2.0)
 
検証機種はあまり多くありませんので端末によっては本記事での対応ではうまくいかない可能性もありますのでご参考までに。
 
 

キャリア・バージョン別の対応方法

キャリア・バージョン別に以下のように変換してFlash内のmailtoリンクに埋め込むとうまくいくようです。
▼DoCoMo
▽FlashLite1.1のSWF
・改行コードをCRLFに統一しておく
・FlashLite2.0以降の端末では改行コードを直接SJISでURLエンコードしたものに書き換え
・文字列をSJISに変換してURLエンコード
・Flashに埋め込んでそのままmailtoリンクに結合
 
▽FlashLite2.0のSWF
・改行コードをCRLFに統一しておく
・改行コードを直接SJISでURLエンコードしたものに書き換え
・文字列をSJISに変換してURLエンコード
・Flashに埋め込んでActionScriptでURLエンコードしてmailtoリンクに結合
 
▼au
▽FlashLite1.1のSWF
・改行コードをCRLFに統一しておく
・Flashに埋め込んでそのままmailtoリンクに結合
 
▽FlashLite2.0のSWF
・改行コードをCRLFに統一しておく
・Flashに埋め込んでActionScriptでURLエンコードしてmailtoリンクに結合
 
▼SoftBank
・改行コードをCRLFに統一しておく
・UTF-8でURLエンコード
・Flashに埋め込んでActionScriptでURLエンコードしてmailtoリンクに結合
 
 

PHPファイルソース

sample4510.php

<?php
/* 
 * 3キャリア対応のmailtoリンクのサンプル
 */

// 置換パターンを指定
// (0:FlashLite1.1)
// (1:FlashLite2.0)
$pattern = intval($_GET['pattern']);

if ($pattern == 0) {
    
    // SWFファイルの内容を取得
    $swfData = file_get_contents('sample4510_lite_1_1.swf');
    
    // 変換時のエンコード設定
    $swfmillEncode = '-e cp932';
    
} else {
    
    // SWFファイルの内容を取得
    $swfData = file_get_contents('sample4510_lite_2_0.swf');
    
    // 変換時のエンコード設定
    $swfmillEncode = '';
    
}

// DoCoMoの端末振り分け用のFlashLite1.1対応の機種リスト
$docomo_1_1_device = array(
    'SO903iTV','SO903i','SO902iWP+','SO902i','SO704i','SO703i','SO702i',
    'SH904i','SH903iTV','SH903i','SH902iSL','SH902iS','SH902i','SH901iS','SH901iC',
    'SH851i','SH706ie','SH705i2','SH705i','SH704i','SH703i','SH702iS','SH702iD',
    'SH700iS','SH700i','SA800i','SA702i','SA700iS',
    'P904i','P903iX','P903iTV','P903i','P902iS','P902i',
    'P901iTV','P901iS','P901i','P851i',
    'P704imyu','P704i','P703imyu','P703i','P702iD','P702i','P701iD','P700i',
    'N904i','N903i','N902iX','N902iS','N902iL','N902i','N901iS','N901iC',
    'N704imyu','N703imyu','N703iD','N702iS','N702iD','N701iECO','N701i','N700i','N601i',
    'M702iS','M702iG','L852i','L706ie','L705iX','L705i','L704i','L06A','L04A','L03A','L01A',
    'F904i','F903iX','F903iBSC','F903i','F902iS','F902i','F901iS','F901iC',
    'F883iS','F883iESS','F883iES','F883i','F882iES','F801i',
    'F705i','F704i','F703i','F702iD','F700iS','F700i','F05A',
    'D904i','D903iTV','D903i','D902iS','D902i','D901iS','D901i',
    'D851iWM','D800iDS','D705imyu','D705i','D704i','D703i',
    'D702iF','D702iBCL','D702i','D701iWM','D701i'
);

$docomo_1_1_flg = false;

// ユーザーエージェントからキャリア・FlashLiteバージョン判別
$userAgent = $_SERVER['HTTP_USER_AGENT'];
if (preg_match('/^DoCoMo/', $userAgent)) {
    $carrier = 'DoCoMo';
    for ($i = 0; $i < count($docomo_1_1_array); $i++) {
        if (preg_match('/' . $docomo_1_1_array[$i] . '/', $userAgent)) {
            $docomo_1_1_flg = true;
        }
    }
} elseif (preg_match('/^(J\-PHONE|Vodafone|SoftBank|MOT\-)/', $userAgent)) {
    $carrier = 'SoftBank';
} elseif (preg_match('/^(KDDI\-|UP\.Browser)/', $userAgent)) {
    $carrier = 'au';
} else {
    $carrier = 'Unknown';
}

// メール件名
$subject = "件名";

// メール本文
$body  = "本文1行目\n";
$body .= "本文2行目";

// SWFからXMLに変換

// コマンド実行時の入出力とエラー出力先を指定
$descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w"),
   2 => array("file", "error-output.txt", "a")
);

// swfmillコマンドを実行してリソースとファイルポインタを取得
$process = proc_open('/usr/local/bin/swfmill ' . $swfmillEncode . ' swf2xml stdin stdout', $descriptorspec, $pipes);

if (is_resource($process)) {
    // 標準入力にSWFファイルのバイナリデータを書き込み
    fwrite($pipes[0], $swfData);
    fclose($pipes[0]);
    
    // 標準出力からXMLデータを読み込み
    $xmlString = stream_get_contents($pipes[1]);
    fclose($pipes[1]);
    
    // パイプを全て閉じてからプロセスを閉じる
    proc_close($process);
}

// 件名・本文・キャリアを文字列置換
$replaceStrings = array(
    'subject' => $subject,
    'body' => $body,
    'carrier' => $carrier,
);
foreach($replaceStrings as $key => $value){
    
    // 改行コードはCRLFに統一
    $value = str_replace(array("\r\n", "\r", "\n"), "\r\n", $value);
    
    // ドコモの場合は改行コードのみをあらかじめエスケープ
    if (($carrier == 'DoCoMo') || ($carrier == 'Unknown')) {
        // 1.1の機種の場合は置換しない
        if ($docomo_1_1_flg === false) {
            $value = str_replace("\r\n", "%0D%0A", $value);
        }
        if ($pattern == 0) {
            $value = mb_convert_encoding($value, 'SJIS', 'UTF-8');
            $value = rawurlencode($value);
        }
    // ソフトバンクの場合は先に全てエスケープ
    } elseif ($carrier == 'SoftBank') {
        $value = rawurlencode($value);
    // auの場合は特に何もしない
    } elseif ($carrier == 'au') {
        
    }
    // 文字列内の改行コードと特殊文字をエスケープ
    $value = str_replace(
        array('&', "\r\n", "\n", "\r", '<', '>', '"'), 
        array('&amp;', '&#13;','&#13;','&#13;', '&lt;', '&gt;', '&quot;'), 
        $value
    );
    
    // 文字列を連想配列の値に置換
    $xmlString = str_replace('{$' . $key . '}', $value, $xmlString);
    
}

$descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w"),
   2 => array("file", "error-output.txt", "a")
);

// swfmillコマンドを実行してリソースとファイルポインタを取得
$process = proc_open('/usr/local/bin/swfmill ' . $swfmillEncode . ' xml2swf stdin stdout', $descriptorspec, $pipes);

if (is_resource($process)) {
    
    // 標準入力にXMLデータを書き込み
    fwrite($pipes[0], $xmlString);
    fclose($pipes[0]);
    
    // 標準出力からSWFファイルのバイナリデータを読み込み
    $swfOutput = stream_get_contents($pipes[1]);
    fclose($pipes[1]);
    
    // パイプを全て閉じてからプロセスを閉じる
    proc_close($process);
}

// SWFのヘッダを出力
header('Content-type: application/x-shockwave-flash');

// SWFのデータを出力
echo $swfOutput;

※UTF-8で記述しています。
※同階層に書き込み可能権限で「error-output.txt」を配置しています。
 
 

Flashファイルソース

ボタンアクション
▽FlashLite1.1版(sample4510_lite_1_1.swf)

on (press) {
    set("subject", "{$subject}");
    set("body", "{$body}");
    set("carrier", "{$carrier}");
    if (carrier eq "SoftBank") {
        fscommand2("escape", subject, "encoded_subject");
        fscommand2("escape", body, "encoded_body");
        set("url", "mailto:?subject=" add encoded_subject add "&body=" add encoded_body);
    } else {
        set("url", "mailto:?subject=" add subject add "&body=" add body);
    }
    getURL(url);
}

※キャリアによってURLエスケープの動作を変更する必要がありますのでキャリア情報も埋め込んでいます。
※FlashLite1.1ではfscommand2関数でURLエスケープを行うことができます。
 
▽FlashLite2.0版(sample4510_lite_2_0.swf)
ボタンアクション

on (press) {
    getURL("mailto:?subject=" add escape("{$subject}") add "&body=" add escape("{$body}"));
}


 
 

実行例

実行例はこちらからご確認下さい。

URLをメールで送る
http://ookura.tanikaze.com/Sample/post4510/
 
 

サンプルファイル

sample4510.zip
上記サンプルのFlashファイル及びPHPファイル一式です。
 
 

参考URL

hi-posi ≫ Blog Archive ≫ [FlashLite]メール本文の改行
→メール本文の改行について詳しく調査されており、非常に参考になりました。
 
 


関連ページ

ケータイFlash関連の記事一覧