ケンのいろいろなことを書くブログ

留学体験記、就活体験記、プログラミングの日記など

あと二ヶ月くらいでやりたいこと

あと二ヶ月くらいで、今まで読んできた本とかをまとめた何か1つオリジナルのものを作りたいと考えてて、

せっかくflask と line bot、クローリングスクレイピング を最近勉強したから、それらの機能をまとめたなにかを作りたい!

 

考えてるのは、使用者の要請に対してそれに見合った情報を教えてくれるbot

今日のニュースを切り取って表示してくれるとか、天気を教えてくれるとかはどうだろ、

あとは地名を入れるのその近くの人気のラーメン屋を教えてくれるラーメンbotとか!

あとはこれになにか機械学習も組み込めるようにしたいけど、今のところアイディアはないかなー、

 

 

とりあえずまずはニュースを教えてくれるbotから始めてみよう!

Line bot ってきっと自分の作品を見せる時もボットを見てもらえればいいからすごくわかりやすそうだし。

 

今日はこれだけ、

 

それでは。

 

ケン

 

今日の中国語14

你怎么了?
今天我也写日记使用中文.

今天我们有周会从下午2点开始.
之后我们开始操作机.

我需要留在实验室直到下午12点.

今天我的一个室友有生日.
所以我们去餐厅庆祝他的生日.

我们吃了鱼头,海草, 开胃菜,
后来油炸虾和蔬菜.
我很开心那时他们喜欢这饭.

我希望他有好的时间和女朋友在一起.

我也想我的女朋友.
我想去看看她.



现在让我们来学习一些单词.
金属 Jīnshǔ
留 Liú
大个子 Dà gèzi
打破 Dǎpò
壁 Bì
应该 Yīnggāi
保护 Bǎohù
内 Nèi
胆大 Dǎn dà
秃 Tū
胡子 Húzi
你多高 Nǐ duō gāo

这就是今天.


ken

今日の中国語13

你好, 今天我看了电影.
今年它得到了奖, 叫 "the shape of the water".
"水的形状" 如果用中文?

情节是关于女人在工作在实验室.
她打扫房间.
在实验室里研究员隐藏生物.

但她找出它然后成为他的朋友.
他们爱上对方然后她尝试帮助他逃逸.

但是之后研究员找出这个然后尝试杀他们.

这是主要情节.

但实际上他包含很多社会问题..

所以这也是提名理由.

这是今天的中文课.


ken

今日の中国語12

你好!你好吗
我的方式学习汉语只是
使用谷歌翻译.

今天我想描述一下我的工作.

我是学生在纽约, 我学习物理.
我在实验室工作.

因为我们有环为离子
这个设施用于实验.

然而,其实那里有太多的老人
大家只看看屏幕一整天
合作做得不好

所以我不太喜欢这份工作

我3个月内离开这里
因为我找到了工作在日本

那就是今天

ken

今日のコード14

ご無沙汰してます。
最近も勉強は続けていたけどなかなかいろんなことにジャンプしっ放しで着地地点を今日みたいに見つけてゆっくりまとめる時間を持っていませんでした。これも大事だからたまにはしないとね、反省。
たくさん溜まってるなあ、

最近読んでいた本は、pythonのウェブマイクロフレームワークFlaskの参考書です。
この本は恐らくOraily系列で人気の高い本で、読み進めるにあたってFlaskyと呼ばれるブログ管理webアプリ製作を通してflask,およびsqlalchemyでsqlの取り扱い方などにまず離れて行くのが難しいところでしょうか、私も全くこれらを全て理解できてなどとうていありませんが、少しずつ以前は知りもしなかったコードを少しでも読めているということはいいことではないでしょうか。
読んでいる本は、Miguel Grinberg さんの、この本。



そして、今日の本題はいきなりですが、linebot作成に関してです。
linebot 作成については、たくさんの記事がでていてそれをたくさん徘徊して読んでいただけるとその概要について見えてくると思いますが、大まかにポイントは以下です。

  • line developer サイトにアクセスして、アカウントを作成した後に、message api (bot)を作成する。 

LINE Developers 作成の時に、自分のlineアプリにアクセスして認証を行う必要があります。

  • 作成したラインbotのアクセルトークンを発行する。自分のページですぐに発行出来ます。これをコードを書く時に自分のbotへの住所として明記する必要有り。
  • python, ruby, javascriptなど、自分の好みの言語を使ってlinebotの骨格を作る。これは山のように記事があるので、コピペでおっけー。自分もコピペで作成しました。完成品を下に貼っておきます。
  • 作成したlinebotのコードをサーバーにアップロードしてwebアプリとしてsslアクセス可能にしておく。(この言葉の使い方は正しくないかもしれませんが、超新米のエンジニアとしてご容赦下さい。)ここが一番自分の中で面倒臭く、いろいろなやり方があったのでいくつか紹介します。

私はまずは行きついたサイト 
今さら聞けない、雑談LINE BOTの作り方(1)「おじさんだって、ボットをつくってもいいじゃないか」 - Qiita

で、javascript を使ってそれをgoogle apps script(これすらも知らなかったけど、google アカウントが有ればそこからここに行けて、コードを張るだけで其れをwebappとしてデプロイできるという便利すぎるもの) に貼り付けるやり方。
https://script.google.com/a/macros/stonybrook.edu/d/1Ga-Yg8PeNLptvF7WUAw0yEWpW8_mS4fzLDbcYpM6PR0aa6auM1bNZvcG/edit?splash=yes

javascriptを自分は書けるわけではないですがとりあえずスタート地点として使って、二つ、まず一つ目はオウム返しbot、もう一つはドコモの雑談APIというものを仲介して、linebotに送られてきたメッセージを処理し、雑談APIと会話するbotを作りました。以下のコードをgoogle apps script に貼りつけてwebappとしてデプロイし、取得したURLをlinebot上でwebhook(コードがデプロイされている住所)として登録するとbot完成です。

まずはオウム返しBOT

var CHANNEL_ACCESS_TOKEN = 'ここだけ自分のアクセストークンを入れる必要有り。';


function doPost(e) {
  var reply_token= JSON.parse(e.postData.contents).events[0].replyToken;
  if (typeof reply_token === 'undefined') {
    return;
  }
  var user_message = JSON.parse(e.postData.contents).events[0].message.text;
  
  var url = 'https://api.line.me/v2/bot/message/reply';
  UrlFetchApp.fetch(url, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': reply_token,
      'messages': [{
        'type': 'text',
        'text': user_message,
      }],
    }),
  });
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}

と、雑談bot

var CHANNEL_ACCESS_TOKEN = 'ここだけ自分のアクセストークンを入れる必要有り。';

var line_endpoint = 'https://api.line.me/v2/bot/message/reply';


var dialogueUrl = 'https://api.apigw.smt.docomo.ne.jp/dialogue/v1/dialogue?APIKEY=ドコモ雑談APIに登録して取得したAPIキーを入れるいつ用あり。';
var userId = 'ドコモ雑談APIのuserIDを書く必要有り。'

function doPost(e) {
  var reply_token= JSON.parse(e.postData.contents).events[0].replyToken;
  if (typeof reply_token === 'undefined') {
    return;
  }
  var user_message = JSON.parse(e.postData.contents).events[0].message.text;
  var reply_message = getDialogueMessage(reply_token, user_message);

  
  var url = 'https://api.line.me/v2/bot/message/reply';
  UrlFetchApp.fetch(url, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': reply_token,
      'messages': [{
        'type': 'text',
        'text': reply_message,
      }],
    }),
  });
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}

function getDialogueMessage(userId, mes) {
  var contextId = 'context' + userId;
  var dialogue_options = {
    't': 20,
    'utt': mes
  }
  var options = {
    'method': 'POST',
    'contentType': 'text/json',
    'payload': JSON.stringify(dialogue_options)
  };

  // ここでドコモ雑談会話エンドポイントにメッセージを投げる
  var response = UrlFetchApp.fetch(dialogueUrl, options);

  // ドコモAIからの回答はJSON形式なのでオブジェクト変換
  var content = JSON.parse(response.getContentText());

  // ドコモAIから取得した回答部分を呼び出し元に戻す
  return content.utt;
}

です。


次に、pythonのflaskをベースにしたやり方で、これはまだオウム返しBOTしか完成していません。こちらはngrockと呼ばれるソフトウェアを使って、普通flaskを使ってローカルに展開するwebsiteをngrockにIPアドレスssl通信で付与してもらうことでデプロイし、そのアドレスをlinebot api からwebhookとして読み込みます。
書いているのが疲れてきたので、ソースコードを貼ってとりあえず切り上げますが、質問がもし有れば遠慮なくコメントして下さい。ngrockを使うまでは難なく進んだんですが、それをwebhookとしてつなげるところで通信エラーにてこずり、その時とても役に立った記事が、こちら、
line-bot-sdk-pythonでLineBotのサンプルを動かす。 - Qiita


コードの完成品(コピペ)は、こちら。

from __future__ import unicode_literals

import os
import sys
from argparse import ArgumentParser

from flask import Flask, request, abort
from linebot import (
    LineBotApi, WebhookParser
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)

app = Flask(__name__)

# get channel_secret and channel_access_token from your environment variable
channel_secret = os.getenv('LINE_CHANNEL_SECRET', None)
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)
if channel_secret is None:
    print('Specify LINE_CHANNEL_SECRET as environment variable.')
    sys.exit(1)
if channel_access_token is None:
    print('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
    sys.exit(1)

line_bot_api = LineBotApi(channel_access_token)
parser = WebhookParser(channel_secret)


@app.route("/callback", methods=['POST'])
def callback():
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # parse webhook body
    try:
        events = parser.parse(body, signature)
    except InvalidSignatureError:
        abort(400)

    # if event is MessageEvent and message is TextMessage, then echo text
    for event in events:
        if not isinstance(event, MessageEvent):
            continue
        if not isinstance(event.message, TextMessage):
            continue

        line_bot_api.reply_message(
            event.reply_token,
            TextSendMessage(text=event.message.text)
        )

    return 'OK'


if __name__ == "__main__":
    arg_parser = ArgumentParser(
        usage='Usage: python ' + __file__ + ' [--port <port>] [--help]'
    )
    arg_parser.add_argument('-p', '--port', type=int, default=8000, help='port')
    arg_parser.add_argument('-d', '--debug', default=False, help='debug')
    options = arg_parser.parse_args()

app.run(debug=options.debug, port=options.port)

以上。


ケン。

今日の中国語11、韓国語1

学校に行くまで少し時間があるので中国語と韓国語の単語を少し勉強するぞ!
身の回りのものから。

light, 光 Guāng, 빛 ディ
ceiling, 天花板 Tiānhuābǎn,천장 cheonjang
desk,台,Tái, 책상chaegsang
bottle,瓶子 Píngzi, 병 byeong
bag , 袋 Dài, 가방gabang,
chair,椅子 Yǐzi, 의자 uija
nail, 钉 Dīng, 네일 ねいぇぃ
nail clipper, 指甲钳 Zhǐjiǎ qián, 손톱 깎기 sontob kkakkgi
key,键 Jiàn, 키 ki
car, 汽车 Qìchē, 차 cha
computer 电脑 Diànnǎo, 컴퓨터 keompyuteo
screen 屏幕 Píngmù, 화면 hwamyeon
cup,杯子Bēizi, 컵keob
keyboard,键盘Jiànpán, 건반geonban
fan,风扇Fēngshàn, 부채buchae
arm,臂Bì , 팔pal
pen 钢笔Gāngbǐ, 펜pen
hair, 头发Tóufǎ, 머리카락meolikalag
head, 头 Tóu, 머리meoli
eye, 眼Yǎn, 눈nun
nose, 鼻子Bízi, 코ko
mouth, 口Kǒu, 입ib
phone,电话Diànhuà, 전화jeonhwa
white, 白色Báisè, 화이트 hwaiteu
black,黑色 Hēisè, 검은geom-eun
red, 红Hóng, 빨간ppalgan
blue, 蓝色 Lán sè, 푸른puleun
green, 绿色Lǜsè, 녹색nogsaeg
shoes,鞋Xié, 구두gudu
muscle, 肌肉Jīròu, 근육geun-yug
training, 训练Xùnliàn, 훈련hunlyeon
pee,撒尿Sāniào, 오줌ojum
toilet,厕所Cèsuǒ, 화장실hwajangsil
chest,胸部Xiōngbù, 가슴gaseum
charge,充Chōng,요금yogeum
lia little bit,一点点Yī diǎndiǎn, 조금jogeum
small,小Xiǎo, 작은jag-eun
tall,高Gāo, 긴gin
many,许多Xǔduō, 많은 manh-eun


それでは、


ケン