「あ、やべ!彼女からLINE来たわw」←これを技術で実現する

Qiitaに書いた記事の移転です

友達と遊んでいる時に、友達がトイレに行きました。

テーブルにはその友達のスマホが置かれています。

「ピロン!」

何処からともなく音が鳴りました。

音の鳴る方へ目を向けるとテーブルにあるスマホのロック画面が目に入りました。

IMG_3933.PNG

もくじ

「お前彼女いるんかい!!!」←これがやりたい

もちろん彼女なんていないので、技術でカバーをします。

プロジェクト名は「ラミエルプロジェクト」です。

あまり神話には詳しくないのですが、幻視を支配する存在らしいのでそこから取りました。

ちなみにLINEの会話画面見せても、アプリバッジ見られなきゃ分からないくらい精巧です。

今回はこのラミエルプロジェクトが一旦良い感じまで行ったのでご紹介をさせて頂きます。

IMG_3935.PNG

Project Summary

ラミエルプロジェクトは何かというと、

docomo自然対話API+LINE BOT+Python(Django)を良い感じに組み合わせて、LINE BOTをまるで本物の彼女とのLINEみたいににできたらいいなを実現するプロジェクトです。

動作方法

  1. データベースに彼女のセリフと、使用する時間をストア
  2. 時間が来たらセリフをpush message機能でLINE BOTから送信させる。

Slide1.jpeg

DBからLINE BOTに送信するときに、返答時間を超えたかどうかの判別をいつやるかという話ですが、これはHeroku Schdulerを使って、10分毎にcurlでリクエストを送り、そのリクエストが飛んできたら判別を行う。という仕組みなので普通に設定時刻との誤差は出ます。

でもその方がLINEに悶々出来ていいでしょ??

もちろんDjangoのadminページから送る文章を自作することが出来ます。

Screen Shot 2019-03-02 at 23.45.58.png

My Mission

やはり大学生にもなってくると彼女持ちなどが多く、友達にスマホの画面を見せてもらってるときに、上から彼女からのLINE通知とかがくるとなんかめっちゃ負けた感じになりますよね??

この様に無駄な敗北感を持つ僕は「やり返してやろう!」という気持ちになったのです。

ですが彼女を作るのは非常に難しく、もはやどうすればいいか分からない所まで来てしまいました。

そこ彼女がいる様に見せて、もしこれがBOTだとバレても「これ作ったんだぜw」と言ってマウントが取る事が出来ます。

マウントを取らなくても、

彼女とLINEしてるのかと思ったらBOTだったという事実で笑いが取れます。

Technology

送られてくる文章のモデルは以下の様になっています。

class Vocabulary(models.Model):
    author = models.CharField(max_length=110,null=True,blank=True)
    author_line_id = models.CharField(max_length=120, null=True, blank=True)
    serif = models.TextField()
    created_date = models.DateTimeField(default=timezone.now)
    use_time = models.DateTimeField()
    STATE = (
    ('SENDED', '送信済み'),
    ('WAITING', '未送信'),
    ('DRAFT', '下書き'),
    )
    state = models.CharField(max_length=7, choices=STATE)

max_lengthがガバガバですがこれはデバッグの名残です()

また、LINEユーザのモデルも作っています。

class LINEUser(models.Model):
username = models.CharField(max_length=35)
line_id = models.CharField(max_length=100)
app_id=models.CharField(max_length=100,null=True,blank=True)

このapp_idというのは自然対話APIのものであり、これによりユーザ毎に自然な会話を行う事が出来ます。

送信部分の処理は以下の様にして処理をしています。curlを飛ばすと、この関数が呼ばれて、push messageが行われます。

def push_message_from_model(request):
    objects = Vocabulary.objects.filter(use_time__lte=timezone.now()).filter(state='WAITING').order_by(
        'use_time').first()
    if objects:
        post = objects
    check = post.serif.split('\n')
    if &#039;<tag>&#039; in check[0]:
        target = [check[0].replace(&#039;<tag>&#039;, &#039;&#039;)]
    serifs = [check[i] for i in range(1, len(check))]
    serif = &#039;\n&#039;.join(serifs)
    elif post.author_line_id:
    target = [post.author_line_id]
    serif = post.serif
    else:
    target = [i.line_id for i in LINEUser.objects.all()]
    serif = post.serif
    message = TextSendMessage(text=serif)
    for i in target:
        print(f&#039;{i} to {serif}&#039;)
        line_bot_api.push_message(i, messages=message)
        post.state = &#039;SENDED&#039;
        post.save()
    return HttpResponse(&#039;OK&#039;, status=200)

一応動作未確認ですが、adminサイトから文章を自作する際、先頭の一文にuser_idを入れると、他のユーザにメッセージを送りつける事が出来る機能を実装しています。

メインの処理は送信時刻が過ぎていて、未送信状態のオブジェクトを取得して、送信した後に状態を送信済みに変えるという部分です。

そして肝心のユーザが送信した時の処理です。

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    profile = line_bot_api.get_profile(event.source.user_id)
    user_object = LINEUser.objects.filter(line_id=profile.user_id).first()
    if user_object:
        payload = {&#039;language&#039;: &#039;ja-JP&#039;,
                   &#039;botId&#039;: &#039;Chatting&#039;,
                   &#039;appId&#039;: user_object.app_id,
                   &#039;voiceText&#039;: event.message.text,
                   &#039;clientData&#039;: {
                       &#039;option&#039;: {
                           "nickname": profile.display_name
                       }
                   },
                   "appRecvTime": "2019-03-02 22:22:22",
                   "appSendTime": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                   }
    req = requests.post(docomo_communication_api_url, data=json.dumps(payload), headers=docomo_api_headers)
    notifer.send_message(req)
    res = req.json()
    print(res)
    notifer.send_message(res)
    make_vocabulary(name=profile.display_name, line_id=profile.user_id, text=res[&#039;systemText&#039;][&#039;expression&#039;],
                    date_time=timezone.datetime.now() + timezone.timedelta(minutes=int(random.random() * 30)))
    else:
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=&#039;DataBaseにあなたの名前がありません。友達追加をお手数ですが再度行って下さい。よろしくお願い致します。&#039;))

requestを送って、結果をDBに格納しているのが分かります。

今後

今後は、adminサイトからではなく、別のLINEBOTから喋る言葉の追加を行う様な仕組みにしていきたいと考えています。

ソースコード

ここにありますぞ!

LINE BOT

~プランがFor Developerなので友達が50人までですがよろしければ・・・(adminサイトは使えないため、実質docomo自然対話APIとの会話機能のみです。)~

2019/11/14 下のQRもう使用できません

Screen Shot 2019-03-03 at 19.03.31.png

参考文献

おもしろいダジャレを入力すると布団が吹っ飛ぶ装置を作った

文章の流れの構成をパク・・・参考にさせていただきました

Licensed under CC BY-NC-ND 4.0
Built with Hugo
テーマ StackJimmy によって設計されています。