ソラマメブログ

2007年05月23日

Emailの送受信

久しぶりのスクリプトの記事です。
nyagos kiddさんから以下のような質問がありましたので、これに関連してEmail機能について書きたいと思います。

一つ教えて欲しいのですが、IMにより起動するスクリプトを作りたいと考えているのですがListenのチャンネルでそのような設定はあるのでしょうか?もしご存知でしたら教えてください
Posted by nyagos kidd at 2007年05月22日 00:46

IMを使いたい理由と代替案

まずこの質問への答えですが、残念ながらオブジェクト(スクリプト)はIMを受信できません。従ってIMに反応するようなスクリプトは作ることができません。

nyagosさんご本人に確認していないので、あくまでも推測ですが、スクリプトに指示を出すのにIMを使いたい理由にはどんなものがあるでしょうか。

一つには、IMの「内緒話」という特性に注目し、
「他の人にコマンドを見せたくない」
という理由があるかもしれません。
これであれば、listenのチャンネルを他の人にわからないようなチャンネル(例えば1342とか)に設定すれば、コマンドを人の目から隠すことができます。
スクリプトにコマンドを送るときは、「/1342 command」のように発言すればOKです。この発言は通常他の人には見えません。
listenの使い方については聞き耳を立てる(初級スクリプト第七回)を参照して下さい。

IMを使いたい理由としてもう一つ考えられるのは、
「遠く離れたところから操作したい」
というのもあるでしょう。
IMは距離が関係ないですから、どこからでもメッセージを送ることができます。
もしもIMをスクリプトで受信できるなら、セカンドライフ上のどこに居ても操作可能なスクリプトを作ることができるわけです。

ですが、先に述べたように、スクリプトではIMを受信することができません。
その代替案として、今回説明するEmailの機能が利用できます。

Email機能

セカンドライフではEmailを利用した機能がいくつか存在します。

例えば、オフラインのときに受けたIMをEmailに転送する機能です。
私がセカンドライフに接続していないとき、誰かが私に対してIMすると、そのメッセージはEmailに転送されてきます(転送はデフォルトでは無効になっていたかと思います)。
このとき送信されてくるEmailアドレスは、「セッションのUUID@im.secondlife.com」という一時的なアドレスです。
このアドレスにメールを返すと、IMを送ってきた人にメッセージがIMとして届きます。
つまり、
「IM」ー「Email」間でやり取りができるわけです。
この一時的なメールアドレスを使えるのはIMを受け取ってから5日間の間だけです。
また、IMからEmailには日本語を遅れますが、EmailからIMには日本語は送れないという難点もあります(2007/5月現在)。

さらに、スクリプトからEmailを扱う方法もあります。

セカンドライフのオブジェクトは一つ一つが実はEmailアドレスを持っていて、スクリプトを使うとEmailの送受信ができます。
各オブジェクトのEmailアドレスは「オブジェクトのUUID@lsl.secondlife.com」です。
例えばオブジェクトのUUIDが"a311ce4d-e755-f148-7999-56f289ca3f3b"だとしたら、Emailアドレスは「a311ce4d-e755-f148-7999-56f289ca3f3b@lsl.secondlife.com」になります。

オブジェクトのUUIDはllGetKey()関数で調べられます。
従って、以下のユーザー関数は、オブジェクトのEmailアドレスを取得します。

string get_email_address(){
  return (string)llGetKey() + "@lsl.secondlife.com";
}

default {
  state_entry(){
    llWhisper(0, get_email_address());
  }
}


Emailの送信には、llEmail関数を使います。

  llEmail(string address, string subject, string message)

引数は単純です。
addressには送信先のEmailアドレスを指定します。
subjectはEmailのタイトルです。
messageはEmailの本文になります。

タイトルと本文の長さは、合わせてだいたい4096文字くらいまでです。
実際にはオブジェクト名や送信元SIM名、位置などの情報が追加されるため、4000字よりも少々少なくなります。
しかしながら、スクリプトによるEmailの受信時には、タイトルは78文字、本文は1000文字までという制限があります(後述)。
ですので、4000字程度まで送れるとは言っても、スクリプト間の通信に使う際には1000文字程度が限界値です。

Emailを受信する際には、llGetNextEmail関数を使います。
この関数は「メールが届いていないかどうかをチェックする」関数です。

  llGetNextEmail(string address, string subject)

引数のaddressは送信元Emailアドレスを指定します。
subjectはEmailタイトルです。
例えば、
  llGetNextEmail("hoge@hoge.com", "hogera");
このようにした場合、"hoge@hoge.com"というアドレスから"hogera"というタイトルのメールが届いていないかどうかをチェックします。
全てのメールをチェックしたい場合には、addressとsubjectを空白文字にします。
  llGetNextEmail("", "");
こうすると、あらゆる送信元のあらゆるタイトルをチェックします。

チェックした結果、Emailが届いていた場合は、emailイベントが発生します。
emailイベントは以下のようなイベントです。

  email(string time, string address, string subj, string message, integer num_left) {
     // 処理
  }

引数が多いですが、難しいものは特にないと思います。
timeは受信時刻、addressは送信元アドレス、subjはEmailのタイトル、messageは本文です。
num_leftには「残り何通のメールがあるか」を示す数値が入ってきます。
残りのメールが無ければ0ですね。

さて、ここで受信されるEmailのタイトルと本文には少々制限があります。
タイトルは78文字、本文は1000文字です。
さらに、本文にはヘッダ情報と言う付加情報が付いています。
例えば他のオブジェクトから送られてきたEmailですと、以下のようなヘッダ情報が付きます。

Object-Name: Kappa head
Region: Walden (254976, 256000)
Local-Position: (244, 122, 21)

hi, jack!


最初の3行がヘッダ情報です。
1行空いて、最後の行がメッセージ本文になります。

ヘッダの1行目はEmailを送信してきたオブジェクトの名前が入ります。
この例では"Kappa head"という名前のオブジェクトからEmailが送信されてきたことになります。
2行目は送信元のSIMの情報です。"Walden"という名前のSIMから送信されています。
3行目はSIM内の送信位置です。座標244, 122, 21から送信されているということです。

メッセージ本文は「hi, jack!」(よぉ、ジャック!)です。
このあとおもむろに襲撃が始まりそうなメッセージです。

Emailスクリプト

では、Emailを受信するスクリプトを作ってみます。
ポイントはllGetNextEmail関数の使い方です。
どのように使うか見てみましょう。

default {
  state_entry() {
    llOwnerSay("My Email Address is " + (string)llGetKey() + "@lsl.secondlife.com");
    llSetTimerEvent(3.0);
  }

  timer() {
    llGetNextEmail("", "");
  }

  email(string time, string address, string subj, string message, integer num_left) {
    llSetTimerEvent(0.0);
    llOwnerSay("Mail Recv:");
    llOwnerSay("Time:" + time);
    llOwnerSay("From:" + address);
    llOwnerSay("Subject:" + subj);
    llOwnerSay("Message:" + message);
    llSetTimerEvent(3.0);
  }
}


まず最初に、スクリプトがスタートするとオブジェクトのEmailアドレスを表示するようにしました。
そしてタイマーを3秒間隔にセットしています。

タイマーイベントの中で、llGetNextEmail関数を使ってEmailが着ていないかどうかチェックをしています。
こうすることで3秒間隔でEmailのチェックが行われるわけです。

Emailが届いていると、emailイベントが発生します。
ここでは単に届いたメールの内容をオーナーに報告するだけにしてありますが、特定のタイトルや本文に応じて何か処理をするようにすることもできます。

email(string time, string address, string subj, string message, integer num_left) {
  llSetTimerEvent(0.0);
  if (subj == "jibaku"){
    // Emailのタイトルが"jibaku"だったときに何か処理する
  }
}

こんなふうにしてやれば、セカンドライフのどこからでも自爆スイッチをONにできます。
いや、意味があるかどうかは知らないですが(^^;

ついでに送信用スクリプトも書いてみましょう。

string email_address="a311ce4d-e755-f148-7999-56f289ca3f3b@lsl.secondlife.com";

default {
  touch_start(integer detected){
        llEmail(email_address, "jibaku", "That pot is very nice!");
    }
}


email_addressの定義は変えてください。
このまま動かすと、どこにメール送るかわかりません(^^;

タッチすると、email_addressに指定したアドレスにメールを送ります。
タイトルは"jibaku"。
本文は"That pot is very nice!"(あの壺は良いものだ!)です。

試しに先ほど作った受信用のスクリプトのEmailアドレスを使い、メールを送信・受信してみて下さい。
メールの送信には20秒ほどかかりますが、どこのSIMからでもメッセージが送れることが確認できるかと思います。

※注意!
受信用のオブジェクトをSIMの外に持ち出すと、UUIDが変わってしまうことがあります。
UUIDが変わるということは、Emailアドレスも変わりますので、その際は改めてUUIDを調べる必要があります。


タグ :Email

同じカテゴリー(スクリプト小技)の記事画像
リモートロード
同じカテゴリー(スクリプト小技)の記事
 モジュール化 (2007-09-04 12:15)
 高度なカメラ制御 (2007-07-19 12:15)
 リモートロード (2007-05-29 18:02)
 鍵をかける (2007-05-10 16:24)
 パーティクル (2007-04-09 17:07)
 lslで日本語を使う (2007-04-06 14:21)
この記事へのコメント
ご親切に新たな記事を書いていただき、恐縮至極ですm(__)m
IMで起動させたかった理由は別のところにあって、、、出来ないとわかったので言いますと、チャットがRLでの会話だとすれば、IMはケータイだなwと思い、IMで起動するアニメつきの携帯電話を作ろうと考えたのでした。全然違う理由でスミマセン。チャット中にIMすると、ただ黙ってるだけですが、ケータイを耳に当ててもぞもぞしていれば様子がわかりますよね。そんな感じです。でも、我々の知識がさらに増えたから良かったのかな?^_^
Posted by NYAGOS at 2007年05月23日 22:19
>NYAGOSさん

なるほど、それはまったく思いも寄りませんでした(^^;
私はどうしても「IM=内緒話」と捉えてしまっていましたが、敢えてIMで話しているのをアニメーションで周囲に知らせるというのはとても面白い発想だとおもいます。
Posted by Miz at 2007年05月23日 23:45
はじめまして!
SLを始めて1ヶ月が経ち、見て見ぬ振りをしてきたオブジェクト作りを遂に開始しちゃいました。。。(まだオブジェクトと呼べるしろものではありませんが・・・)
Mizさんのブログはまさにバイブル!!!
これからもお邪魔させてくださいね♪
おねがいしまーす( ´∀`)
Posted by bigfoot torok at 2007年05月24日 00:24
llGiveInventory()は距離に関係なくアイテムを渡せるので組み合わせれば夢がひろがりんぐ。
Posted by Ichigo Mayo at 2007年05月24日 04:21
>bigfoot torokさん

モノ作りはSLの醍醐味の一つだと思いますので、ぜひとも楽しんで下さいませ。
作るだけであれば、別に上手でなきゃいけないものでもありません。
まずは自分が楽しむところからで良いと思いますよ~。

>Ichigo Mayoさん

遠いSIMからEmailで商品を発注して、llGiveInventory()で商品が送られてくるとかも可能ですよね。
時間がかかるのは難点ですが、商品発送用のオブジェクトを一つだけにしておくと、新商品の配置は楽になりそうです(^^
Posted by Miz at 2007年05月24日 10:12
外部からSL内のオブジェクトにE-mailを送ろうとしていますが、どうもうまく送れません。SL内オブジェクトから外部にE-mailは送れています。
E-mailはSL内のオブジェクトからのものしか受信できないのでしょうか?
それとも、Gmail等のフリーメールアカウントは弾かれているのでしょうか?
何か情報をお持ちでしたら教えてください。
Posted by ff at 2007年07月10日 11:48
>ffさん

フリーメールがはじかれるという話は聞きませんが、外部からオブジェクトへの送信がうまくいかない理由として思い当たるのは、メール内に日本語が混じっている場合です。

実際に試したことはないですが、IMでは、SL内から外部メールへの日本語jは通りますが、外部からSLへの日本語は拒否されます。
同じことがオブジェクトへのメールでもあるかもしれません。
Posted by Miz at 2007年07月10日 12:11
> フリーメールがはじかれるという話は聞きませんが、
> 外部からオブジェクトへの送信がうまくいかない理由として
> 思い当たるのは、メール内に日本語が混じっている場合です。

有難うございます。外部からオブジェクトへの送信というのは実績があるのですね。
内部オブジェクトから外部にメールを送信し、そのメールに返信して受信してみてました。もう少しやってみます。
すばやいリプライ有難うございます。
Posted by ff at 2007年07月10日 13:18
この記事もとに mail機能を使い、llGiveInventory()を使い遠方へ
オブジェクトを送信しようと思っているのですが、送信相手がアバターだと
どのSIMにいても問題なく送られてくるのですが、こと送信先が
オブジェクトだと同SIM内が限界のようです。
これではちょっと寂しいので、遠方のSIMにあるオブジェクトに、GIVEする
手立ては何かないでしょうか?
情報をお持ちでしたら、ご教授いただけるでしょうか。
Posted by pe at 2007年07月12日 17:45
>peさん

オブジェクトへのllGiveInventoryは同一SIM内に限り有効です。
仰る通り、アバタ-へならどこに居ても大丈夫なのですが・・・。

他SIMのオブジェクトにアイテムを送りつけるのは多分セキュリティ上の理由からNGになっているのだと思います。
Posted by Miz at 2007年07月12日 22:39
そうですか。やはりって感じですね。
これが出来ればぐっとやれることが広がったんですけど
LSL初めて一週間とちょっと。。。知らなかった。。。
ちょっと残念ですけど、APIの仕様が変わるのを待ちつつ代替案を練るとします。
参考になりました、ありがとうございます。
Posted by pe at 2007年07月13日 12:30
オブジェクトからのメール、日本語通るのですか??

最近試したところ、日本語部分がすべて「?」になっていたので通らないと思いこんでいました。

受信側の設定で文字コードを変えても同じでしたので、送信側じゃないかと思うのですが…原因がわかりません…
Posted by jackfield at 2007年09月12日 16:16
>jackfieldさん

通らないのかもしれませんね。
私は実際に試していないのでハッキリしたことが言えませんが(^^;

LSL上では日本語文字はUTF-8で扱われていると思われますが、EmailはJISコードです。
llEmail関数の実装でマルチバイト文字が考慮されておらず、内部的なコード制御がなされてないのかもしれません。

不在IMをメール転送する仕組みと、llEmailの実装が同じである保証はないですし(^^;
Posted by MizMiz at 2007年09月13日 09:32
オブジェクトにE-mailを送ろうとしていますが、どうもうまく送れません。SL内オブジェクトから外部にE-mailは送れています。
E-mailはSL内のオブジェクトからのものしか受信できないのでしょうか?
それとも、Gmail等のフリーメールアカウントは弾かれているのでしょうか?
Posted by lv bags cheap at 2011年06月17日 17:28
 
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。