[day16]机器人对话纪录

以前遇到一个情况阿,使用者输入,我要ㄧ个汉堡,二杯奶茶,到後台却变成,我要\xe3\x84\xa7个汉堡,二杯红茶,截图拍给我,很正常是ㄧ个汉堡,看了半天没看出什麽鬼,最後发现

这个《ㄧ》个汉堡的一,是注音符号的《ㄧ》,你永远不知道使用者会用什麽方式打字,在互动式的设计下,你会需要保留原始的对话纪录,以应对各种神秘的输入法所造成的问题,这边要依据先前创建的Line Bot进行资料纪录

Postgres 初始化 & 连线

新增Postgres模组到你的专案

使用免费方案hobby-dev

heroku addons:create heroku-postgresql:hobby-dev

用heroku pg:info检查Postgres资料库状态

Plan:                  Hobby-dev
Status:                Available
Connections:           5/20
PG Version:            13.4
Created:               2021-09-27 02:30 UTC
Data Size:             8.1 MB/1.00 GB (In compliance)
Tables:                1
Rows:                  3/10000 (In compliance)
Fork/Follow:           Unsupported
Rollback:              Unsupported
Continuous Protection: Off
Add-on:                postgresql-dimensional-#####

建立表格

可以使用pgAdmin 4进行这个步骤,在dashboard内的addons,可以找到Heroku Postgres,Settings,Database Credentials会有从本机连线到资料库的所需资讯

参数 填入Pgadmin栏位
Host Connection -Host Name/Address
Database Connection - Maintance Database & Advanced - DB Restriction
User Connection - User
Port Connection - Port
Password Connection - Password
CREATE TABLE IF NOT EXISTS public.messaging_log
(
    id text COLLATE pg_catalog."default" NOT NULL,
    type text COLLATE pg_catalog."default" NOT NULL,
    text text COLLATE pg_catalog."default",
    datetime timestamp with time zone NOT NULL,
    source_uid text COLLATE pg_catalog."default" NOT NULL,
    source_type text COLLATE pg_catalog."default" NOT NULL,
    CONSTRAINT messaging_log2_pkey PRIMARY KEY (id)
)

TABLESPACE pg_default;

连线

如果你的App与Postgres在相同的专案下,在App内与资料库连线时,你不需要特别设定资料库连线的URL、使用者名称、密码等,在跨专案运作时请参考官方文件

安装连线Driver

pip install psycopg2-binary

安装完Addons你的Vars变数内会自动追加DATABASE_URL

DATABASE_URL = os.environ['DATABASE_URL']
conn = psycopg2.connect(DATABASE_URL, sslmode='require')

测试连线,看能否执行查询资料库版本指令

cur = conn.cursor()
cur.execute('SELECT VERSION()')
rr = cur.fetchall()
app.logger.debug(f"DBver:{rr}")
# "Database Version: [('PostgreSQL 13.4 (Ubuntu 13.4-1.pgdg20.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0, 64-bit',)]"
conn.commit()
cur.close()

纪录Line对话

藉由解析Webhook Event Objects可以从使用者的对话中取得如下资讯

  1. 讯息类型
  2. 讯息ID
  3. 讯息文字(如果是文字讯息)
  4. 讯息来源
  5. 讯息来源使用者ID
  6. 使用者的显示名称....
  7. 以millisecond计算的Timestamp
prof = line_bot_api.get_profile(event.source.user_id)
dt = datetime.fromtimestamp(event.timestamp / 1000.0).astimezone(TWT)
format_time = dt.strftime("%Y/%m/%d %H:%M:%S")
app.logger.debug(f"message:{event.message.type}-{event.message.id} = {event.message.text}, from {event.source.type}:{prof.display_name}({event.source.user_id}) at {format_time}")
# [DEBUG] message:text-<讯息ID> = 王大明爱吃汉堡包, from user:<使用者的显示名称>(<讯息来源使用者ID>_ at 2021/09/28 17:53:00

将对应的参数填入Sql变数

def INS_msg_log(self, id, msgtype, text, dt, stype, suid):
  cur = self.conn.cursor()
  query = sql.SQL("INSERT INTO {}(id, type, text, datetime, source_uid, source_type) VALUES(%s, %s, %s, %s, %s, %s)").format(sql.Identifier('messaging_log'))
  cur.execute(query, (id, msgtype, text, dt, suid, stype))
  self.conn.commit()
  cur.close()

dbpm.INS_msg_log(event.message.id, event.message.type, event.message.text, dt.isoformat(), event.source.type, event.source.user_id)

如果运作正常,你就可以在资料库查询到每一笔使用者的讯息

讯息ID 讯息类型 讯息文字 时间(UTC) UID 使用者类型
14999999999999 text Apple 2021-09-28 07:51:32.835+00 Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx user
14999999999999 text Banana 2021-09-28 07:51:39.133+00 Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx user
14999999999999 text 王大明爱吃汉堡包 2021-09-28 09:53:00.274+00 Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx user

Summary

你有没有注意到,使用者名称如果想储存的话,是不是每一笔讯息都要查询一次,这样对话量一多会频繁的向Line官方送出API请求,很容易造成被Ban,明天做一个UID与名称对应表格吧


<<:  Day12【Web】网路攻击:DoS 与 DDoS

>>:  Day13-TypeScript(TS)修改成员

Day29,使用Dex、OIDC为你的Kubernetes再上一道锁 (2/2)

正文 如果还没有看Day28的话,建议可以先回去看,不然接下来可能搞不清楚状况。 延续昨天的内容,我...

h1~h6标题基础用法

<h1> 标题01 </h1> <h2> 标题02 </...

Day 13 - 函式烤肉

为什麽要用function(函式)? 通常会将statement 放在函数(function)里面,...

[前端暴龙机,Vue2.x 进化 Vue3 ] Day8. v-model 修饰符 -- 省下自己写 JS 处理的时间

v-model 修饰符 Vue 里面为 v-model 提供了一些可以用的修饰符,主要是可以帮我们限...

DAY 12 SASS 间的相似之处

介绍完了前几天的 sass 各种用法,大家有没有觉得有些方法好像很类似? 像是 mixin 跟 ex...