Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

Perlで作るモバイルサイトのコツ:第7回

絵文字を含んだメールを送信する

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2007/04/30 08:00

目次

サンプルプログラム

 サンプルプログラムで、絵文字を含むメールを送信してみましょう。前述の規則にのっとり、ドコモとEZwebにはSjift_JISで、SoftBankにはUTF-8で送信します。

 また、<emoji:番号> という独自の絵文字用の番号を作り、それぞれのキャリアごとにどの絵文字コードを使うかをマップさせています。

 絵文字コードについては各キャリアのサポートページを参照ください。

 それでは、サンプルプログラムを見ていきましょう。

send_mail.pl

 メール送信スクリプトです。後述のEmojiMailモジュールを使用してメールを送信します。

send_mail.pl(UTF-8で記述)
#!/usr/local/bin/perl

use strict;
use warnings;
use EmojiMail;

my $mail = EmojiMail->new({
    from    => 送信元アドレス,
    to      => 送信先アドレス,
    subject => 'こんにちは<emoji:1>',
    body    => '天気がいいから、テニスしようよ<emoji:2>',
    emoji_map => 後述の絵文字マップファイルのパス,
});

$mail->send;

emoji_map.yaml

 絵文字マップファイルです。YAML形式で記述しています。例えば、ドコモの端末に送信するメール本文に<emoji:1>と記述した場合、<emoji:1>の部分が太陽の絵文字(F89F)に置換されることになります。

emoji_map.yaml
I:          # ドコモ
  1: F89F   # 太陽の絵文字のS-JISコード16進数値
  2: F8B6   # テニスの絵文字のS-JISコード16進数値

E:          # EZweb
  1: F660   # 太陽の絵文字のKDDI絵文字用Shift_JISコード値
  2: F690   # テニスの絵文字のKDDI絵文字用Shift_JISコード値

S:          # SoftBank
  1: E04A   # 太陽の絵文字のunicode値
  2: E015   # テニスの絵文字のunicode値

EmojiMail.pm

 メール送信部分の本体です。キャリアごとに絵文字を含んだメールを生成します。送信先メールアドレスによるキャリアの判別はMail::Address::MobileJpモジュールを使って行っています。文字コードの変換にはEncodeを使用しています。

EmojiMail.pm(UTF-8で記述)
package EmojiMail;

use strict;
use warnings;
use MIME::Lite;
use MIME::Base64 ();
use Mail::Address::MobileJp;
use Encode;
use Unicode::Transform ();
use YAML::Syck;

sub new {
    my ($class, $opt) = @_;
    my $self = bless {
        from    => $opt->{from},
        to      => $opt->{to},
        subject => $opt->{subject},
        body    => $opt->{body},
    }, $class;
    $self->{emoji_map} = YAML::Syck::LoadFile($opt->{emoji_map});
    $self->build;
    return $self;
}

sub build {
    my $self = shift;
    my $message = MIME::Lite->new(
        From     => $self->{from},
        To       => $self->{to},
        Subject  => $self->subject,
        Data     => $self->body,
        Encoding => 'base64',
    );
    $message->attr('content-type.charset' => $self->charset);
    $message->attr("Content-disposition"  => "");
    $message->field_order(
        'MIME-Version', 'Content-Type', 'Content-Transfer-Encoding');
    $self->{message} = $message;
}

sub send { shift->{message}->send }

sub subject {
    my $self = shift;
    my $subject = $self->converter->($self->{subject});
    return '=?SHIFT-JIS?B?'. MIME::Base64::encode($subject)
                           .'?=' if is_imode($self->{to});
    # EZwebではMIMEエンコードをすると化けるのでそのまま送信する
    return $subject if is_ezweb($self->{to});
    return '=?UTF-8?B?'. MIME::Base64::encode($subject)
                       .'?=' if is_softbank($self->{to});
}

sub body {
    my $self = shift;
    my $body = $self->converter->($self->{body});
    return $body;
}

sub converter {
    my $self = shift;
    return sub {
        my $content = $self->encode_content->(shift);
        $content =~ s{(<emoji:(\d)>)}{
            my $code = $self->emoji_map->{$2};
            if (defined $code) {
                $self->code_to_emoji($code);
            }
        }eg;
        return $content;
    }
}

sub encode_content {
    my $self = shift;
    return sub {
        my $content = shift;
        return encode('Shift_JIS', decode('utf-8', $content))
            if is_imode($self->{to});
        return encode('Shift_JIS', decode('utf-8', $content))
            if is_ezweb($self->{to});
        return $content if is_softbank($self->{to});
    }
}

sub emoji_map {
    my $self = shift;
    return $self->{emoji_map}->{I} if is_imode($self->{to});
    return $self->{emoji_map}->{E} if is_ezweb($self->{to});
    return $self->{emoji_map}->{S} if is_softbank($self->{to});
}

sub code_to_emoji {
    my ($self, $code) = @_;
    return pack("H4", $code) if is_imode($self->{to});
    return pack("H4", $code) if is_ezweb($self->{to});
    return Unicode::Transform::unicode_to_utf8(chr(hex($code)))
        if is_softbank($self->{to});
}

sub charset {
    my $self = shift;
    return 'Shift_JIS' if is_imode($self->{to});
    return 'Shift_JIS' if is_ezweb($self->{to});
    return 'UTF-8'     if is_softbank($self->{to});
}

1;

 上記のサンプルを実行すると、下記のようなメールが送信されるはずです。

送信されるメール
件名: こんにちは[太陽の絵文字]
本文: 天気がいいから、テニスしようよ[テニスの絵文字]

まとめ

 今回は、キャリアごとのメール仕様の違いと送信方法を見てきましたが、いかがだったでしょうか。

 今回の方法で重要になってくるのが、端末タイプです。同じキャリアでも端末タイプによって送信方法が異なる上に、送信先のメールアドレスからはその端末タイプを判断することができないので、サイトでメールアドレスと一緒にUserAgentを保存しておいて、それをもとに送信するなどの工夫が必要となるでしょう。

 サイトで絵文字を使う場合と比較すると注意する点が多いかもしれませんが、本稿が参考になれば幸いです。



  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

バックナンバー

連載:Perlで作るモバイルサイトのコツ

もっと読む

All contents copyright © 2005-2019 Shoeisha Co., Ltd. All rights reserved. ver.1.5