ケータイ

Perl で UTF-8 のメール件名を正しく送る

概要

メールの件名や表示名は、MIME対応ライブラリに文字列として渡します。独自のエンコード処理を重ねず、ヘッダー用APIを使います。

実施例

use Email::MIME;

my $mail = Email::MIME->create(
  header_str => [
    From    => 'sender@example.com',
    To      => 'recipient@example.com',
    Subject => '日本語の件名',
  ],
  attributes => { content_type => 'text/plain', charset => 'UTF-8' },
  body_str => '本文です。',
);

注意点

送信前に実在する宛先ではなくテスト用メールボックスで、件名・本文・添付の表示を確認します。

参考: 公式ドキュメント

続きを読む

Perl で、画像のサムネイルを作成してブラウザから表示させる方法

以下のサンプルファイルを image.cgi と名前を付けて保存、アクセス権を chmod +x image.cgi とかして ブラウザから http://yourname.com/image.cgi とかにアクセスすればよい。 注意点としては、このスクリプトは画像しか表示できないことである。これと一緒に HTML ファイルを表示しようと思っても、HTTP プロトコルの仕様上不可能である。なぜかというと HTTP プロトコルを通して画像を表示する場合は、すでにこのスクリプトが HTTP ヘッダとして Content-type: image/jpeg を最初に出力してブラウザが受け取っているからで、このスクリプトの中で同時に(画像を表示した後に) HTML 文書を表示させようとて Content-type: text/html を出力(print "Content-type: text/html\n\n)してもブラウザは受け付けてくれないのである。 #!/usr/bin/perl use GD;
続きを読む

Requirements for Mobile Phones (English)

I would like to propose the unique requirements for mobile phones. The following items are significant considerations under mobile site development, especially in i-mode phones.

  1. UserAgent type that is, a Browser Name of CGI environments which is sent by a mobile phone to a web server.
  2. Range of IP addresses in each mobile operator, which is required to judge whether a user is using a mobile phone or a PC in order to support both of them in the web site. In Japanese mobile phone operators, they are using their specific proxy servers, which are accompanying with the specific range of IP addresses.
  3. Screen Size of each mobile phone, especially the size of width, which would be found in a CGI environment UserAgent in the latest phones
  4. Image Format such as JPEG, PNG and GIF supported by each mobile phone
  5. Maximum Size of Receiving Bytes per a page
  6. Difference of Handling Colors in each mobile phone
  7. Difference of Smilies (Picture Icons) both in each mobile phone and operator
  8. Name Convention of an E-mail Address in each operator (Japanese i-mode e-mail system violates RFC).
  9. Available Character Set in each operator (Shift-JIS, UTF-8 in Japan)
  10. Available Character Types in each operator (such as ZENKAKU, HANKAKU in Japan)
  11. Available Input Method in each operator (Access-key concept in CHTML)
  12. Support of Native Functions of a mobile phone (i.e. switching a browser screen to an e-mail application with 'mailto:' in CHTML at a single screen of a mobile phone, launching Java application, and directly calling to someone with 'tel:' in CHTML, etc)
  13. Difference in between Official Sites and Unofficial Sites (The acquiring information is different)
  14. Session Management because we cannot use cookie in i-mode phones
続きを読む

ケータイサイト構築のポイント

以下に、ケータイのサイトを開発する上で、ケータイならではの考慮すべきポイントを簡単に挙げてみた(リンクはこのサイト内での技術情報)。

  1. ケータイからサーバに送られてくる、CGI 環境変数の UserAgent の種類(ブラウザ名)
  2. 各ケータイキャリア毎の IP アドレス(PC と連携するときに、ケータイからサイトにアクセスしてきたか、PC からアクセスしてきたかサーバ側で判別するのに必要)
  3. 各ケータイの機種ごとの画面サイズ(特に横幅、これは最近の機種であれば UserAgent から取得できる)
  4. サポートする画像形式(JPEG / PNG / GIF)
  5. 1 画面の最大受信サイズ(バイト数)
  6. 機種ごとに使えるカラーの違い
  7. 各キャリアの絵文字の違い(同一キャリアだとしても、ケータイの世代ごとに使える絵文字が違います)
  8. 各キャリアのメールアドレス体系(iモード / i-mode メールは RFC に準拠していません)
  9. 使える文字コード(シフトJIS、UTF-8 など)
  10. 使える文字の種類(全角、半角)
  11. ケータイのキーパッドでも入力しやすくする工夫(PC にはない、アクセスキーの考え方のこと)
  12. ケータイネイティブ機能との連携(mailto: でメーラーが起動するとか、Java アプリが起動できるとか、tel: で電話の発信ができるとか)
  13. 公式サイトと勝手サイトの考え方、取得できる情報の違い
  14. セッション管理(ケータイは基本的に cookie が使えないから)

最近は、パケ放題などのプランが出てきたので以前ほどは、ページ内のパケットを減らす努力(改行はケータイに送らない、コメントは入れない、など)はしなくてもよくなってきたのではと思う。

このノウハウは、拙作の 「ケータイをシステム手帳にバージョンアップする」 サイト i-Services の構築から得られたノウハウである(このサイトのメインのターゲットはケータイだが、ケータイと PC 両方からアクセスできるように作ってあるので、両方で試してみて欲しい)。ノウハウとしては、かなり凝縮されている。

続きを読む

Perl で、添付ファイル付きのメールを送る方法

Perl で、

open(SEND, '/usr/sbin/sendmail') || die;

などとせずにモジュールを使ってメールを送信するには、以下のようにする。

使用するモジュール


use Net::SMTP;
use MIME::Entity;
#!/usr/bin/perl use Net::SMTP; use MIME::Entity; # Settings our $SENDER = '送信元のメールアドレス'; our $RECIPIENT = '送信先のメールアドレス'; our $SUBJECT = 'タイトル'; our $ATTACHED_FILE_1 = '/home/youraccount/添付ファイル名その1.jpg'; our $ATTACHED_FILE_2 = '/home/youraccount/添付ファイル名その2.jpg'; # Create object my $smtp=Net::SMTP->new('localhost',
                    HELLO=>'yourmailsever.yourdomain.com');
# Built headers $smtp->mail($SENDER); # Sender $smtp->to ($RECIPIENT); # Receiver # Built Data (Create data by MIME::Entity) $smtp->data(); my $mime = MIME::Entity->build(
        From    =>    $SENDER   , # Sender   (data)
        To      =>    $RECIPIENT, # Receiver (data)
        Subject =>    $SUBJECT  , # Subject
        Data    => ['']);         # body
# Attached file $mime->attach(
    Path     => $ATTACHED_FILE_1,
    Type     => 'image/jpeg',
    Encoding => 'Base64'
); # Attached file $mime->attach(
    Path     => $ATTACHED_FILE_2,
    Type     => 'image/jpeg',
    Encoding => 'Base64'
); # Attached file (Text) # $mime->attach( # Path => $ATTACHED_FILE, # Type => 'text/plain', # Encoding => '-SUGGEST' #); $smtp->datasend($mime->stringify); # transfer strings # Data termination and send mail $smtp->dataend(); #Quit SMTP connection $smtp->quit; # for debug print "Sender : $SENDER\n"; print "Recipient : $RECIPIENT\n"; print "Attached : $ATTACHED_FILE\n"; 1;
続きを読む

Perl で、Shift JIS でスクリプトを保存するには?

Perl でケータイ向けのサイトを書いているとき、シフトJIS でスクリプトを保存しないければならない場合がある (文字列テーブルなど)。このとき、


Unrecognized character \x81 at ./your.cgi line XX.

といったエラーに悩まされているなら、

my $group = 'グループ';

などのように、「―」を「ー」で表すようにするとよい (Mac の場合は、「ー」が「―」になるようで、この現象が起こる)。または、文字化けする文字の後ろに「\」を付ける。

以下は、Shift JIS で文字化けする文字の一覧。文字化けを起こしやすいよく使う文字は強調しておいた。

文字 - Shift-JIS - Unicode での記述方法


<strong>―</strong>  81 5C   &#x2015;<br />
<strong>ソ</strong>  83 5C   &#x30BD;<br />
Ы  84 5C   &#x042B;<br />
Ⅸ  87 5C   &#x2168;<br />
噂  89 5C   &#x5642;<br />
浬  8A 5C   &#x6D6C;<br />
欺  8B 5C   &#x6B3A;<br />
圭  8C 5C   &#x572D;<br />
<strong>構</strong>  8D 5C   &#x69CB;<br />
蚕  8E 5C   &#x8695;<br />
<strong>十</strong>  8F 5C   &#x5341;<br />
<strong>申</strong>  90 5C   &#x7533;<br />
曾  91 5C   &#x66FE;<br />
箪  92 5C   &#x7BAA;<br />
<strong>貼</strong>  93 5C   &#x8CBC;<br />
<strong>能</strong>  94 5C   &#x80FD;<br />
<strong>表</strong>  95 5C   &#x8868;<br />
暴  96 5C   &#x66B4;<br />
<strong>予</strong>  97 5C   &#x4E88;<br />
禄  98 5C   &#x7984;<br />
兔  99 5C   &#x5154;<br />
喀  9A 5C   &#x5580;<br />
媾  9B 5C   &#x5ABE;<br />
彌  9C 5C   &#x5F4C;<br />
拿  9D 5C   &#x62FF;<br />
杤  9E 5C   &#x6764;<br />
歃  9F 5C   &#x6B43;<br />
濬  E0 5C   &#x6FEC;<br />
畚  E1 5C   &#x755A;<br />
秉  E2 5C   &#x79C9;<br />
綵  E3 5C   &#x7DB5;<br />
臀  E4 5C   &#x81C0;<br />
藹  E5 5C   &#x85F9;<br />
觸  E6 5C   &#x89F8;<br />
軆  E7 5C   &#x8EC6;<br />
鐔  E8 5C   &#x9414;<br />
饅  E9 5C   &#x9945;<br />
鷭  EA 5C   &#x9DED;<br />
偆  ED 5C   &#x5046;<br />
砡  EE 5C   &#x7821;<br />
続きを読む

Perl で、メールサーバに送られてきたメールを処理する

Procmail を利用すればサーバに送られてきたメールが標準入力から Perl スクリプトに渡すことができる。ここでは Procmail の詳細は割愛するが、以下は標準入力に入っているメールを処理する関数。

使用するクラス


use MIME::Parser;
use MIME::Base64;
use Mail::Address;
use MIME::Parser; use MIME::Base64; use Mail::Address; use Unicode::Japanese; my ($mail) = &parse; print "From: " . $mail->{sender} . "\n"; print "To: " . $mail->{recipient} . "\n"; print "Subject: " . $mail->{subject} . "\n"; sub parse {
my ($mail);

# Parser Setting
my $parser = new MIME::Parser;
$parser->output_to_core(1);    # Keeps body analyzed internally
$parser->tmp_recycling (1);    # Recycles the temporary stuff

my $entity = $parser->parse(\*STDIN) or die "Parse Error in __FILE__\n";

# Headers
$mail->{sender   } =  $entity->head->get('from'   );
$mail->{subject  } =  $entity->head->get('subject');
$mail->{recipient} =  $entity->head->get('to'     );
$mail->{recipient} =~ s/\n//g;

# From
@addrs = Mail::Address->parse($mail->{sender});
foreach $addr (@addrs) {
    $mail->{sender} = $addr->address if $addr->address; # USE CAUTION, for the multiple address
}

# Subject
my $subject = $mail->{subject};
$lws      = '(?:(?:\x0D\x0A|\x0D|\x0A)?[ \t])+';
$ew_regex = '=\?ISO-2022-JP\?B\?([A-Za-z0-9+/]+=*)\?=';
$subject  =~ s/\n//g;
$subject  =~ s/($ew_regex)$lws(?=$ew_regex)/$1/gio;
$subject  =~ s/$lws/ /go;
$subject  =~ s/$ew_regex/decode_base64($1)/egio;
$subject  = Unicode::Japanese->new($subject, 'auto')->sjis_imode;
$mail->{subject} = $subject;

# Get MIME
($mail->{body}, $mail->{filename}, $mail->{mimetype}, $mail->{object}) = &getEntities($entity);
$mail->{body   } =  Unicode::Japanese->new($mail->{body}, 'auto')->sjis_imode;
$mail->{body   } =~ s/[  \n\r]+$//g;    # Delete the white spaces in the end of the line
$mail->{subject} =~ s/[  \n\r]+$//g;    # Delete the white spaces in the end of the line

return $mail;
} sub getEntities {
my $entity = shift;
my $body, $filename, $mimetype, $object;

# BODY
my @parts = $entity->parts;
if (@parts) {                   # multipart...

    my $i;
    foreach $i (0 .. $#parts) { # dump each part...

        &getEntities($parts[$i]);
    }
} else {                        # single part...

    # Get MIME type, and display accordingly...
    my ($type, $subtype) = split('/', $entity->head->mime_type);
    my $bodyhandle = $entity->bodyhandle;

    if ($type =~ /^(text|message)$/) {      # text

        $body .= $bodyhandle->as_string;

    } else {                                # binary

        $filename= $entity->head->recommended_filename;
        $mimetype = $entity->head->mime_type;
        $object = $bodyhandle->as_string;
        binmode($object);
        # if we want to store it as BASE64, you can continue the processs here
    }
}

return ($body, $filename, $mimetype, $object);
} 1;
続きを読む

Perl で、RSS を処理する

使用するモジュール


use Encode;
use Encode::Guess;
use XML::RSS;
use LWP::UserAgent;
use HTTP::Request;
#!/usr/bin/perl use Encode; use Encode::Guess; use XML::RSS; use LWP::UserAgent; use HTTP::Request; my $url = 'http://perltips.twinkle.cc/index.rdf'; # 初期化 my $proxy = new LWP::UserAgent; # UseAgent の作成 my $req = new HTTP::Request(GET=>$url); my $rss = new XML::RSS; my $res = $proxy->request($req); # $url にアクセスする my $xml = $res->content; # コンテンツ (この場合は RSS/XML) を取得 my $enc = guess_encoding($xml, qw/euc-jp shiftjis 7bit-jis utf8/); # 文字コードを判定 ref($enc) or die "Can't guess: $enc"; # 自動判定がうまくいかなかったときのエラー処理 # utf8 で保存 ($enc->name を decode することにより、utf8 で変数に保管される $xml = decode($enc->name, $xml); eval {
$rss->parse($xml);
}; if($@) { # $rss->parse が失敗したとき
print "error\n";
} # @{$rss->{items}} に、RSS のすべてのエントリー (item) が入る foreach my $item ( @{$rss->{items}} ) {
# ケータイ (iモード) で出力したいので Shift_JIS にする
my $title       = encode('shiftjis', $item->{title});
my $description = encode('shiftjis', $item->{description}); # 上に同じ

print qq|<a href="$item->{link}">$title</a>\n|; # タイトルをリンクつきで出力
print qq|$description<br />\n|;                 # 概要 (description) を出力
} exit;
続きを読む

Perl で、iモード (ケータイ) 用に全角カナを半角カナに変換したい

Unicode::Japanese を使う。つまりは SJIS に変換するが絵文字とかもこのモジュールでは考慮されている。このモジュール、モバイル用にいろいろ考えられている。こんな感じ。
絵文字が入ったテキストでは、Jcode などを使うと文字化けして使いものにならない。
$isiMode は、モバイルでアクセスされたときのフラグ用変数。この変数のために前もって自分で関数を書いておくこと。

使用するモジュール


use Unicode::Japanese;

# C コンパイラが使えれば XS も利用できる
#!/usr/bin/perl my $text = 'テスト'; my $output = print4i(¥$text); sub print4i {
my $str = shift;
use Unicode::Japanese;
$$str = Unicode::Japanese->new($$str, 'sjis-imode')->z2h->sjis_imode
if $isiMode;
print $$str;
}
続きを読む
ケータイ を購読