微信开发系列之七 - 使用Redis存储微信聊天记录
In the second blog Wechat development series 2 – development Q&A service using nodejs of this series, we have developed a kind of Q&A service in Wechat which leverages a free Tuning Restful service so that you could chat with this service:
In this blog, I will show the steps how to store all of those conversation logs via Redis, so that you can review the conversations within Wechat app or delete them if necessary.
Implemented feature
Two new sub menus “Review” and “Delete” are developed under menu “Conversation”:
Once Review menu is pressed, the conversation log will be read out from Redis and displayed in Wechat app:
Delete menu will trigger the deletion of the conversation log belonging to current user who has pressed it. Once conversation is deleted, corresponding notification will be sent out if user has pressed the Review menu again.
Implementation detail
(1) Since as before my WeChat server runs on Heroku, which supports Redis as well.
Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs and geospatial indexes with radius queries.
In this blog I will use Redis to store conversation logs.
It is very easy in Heroku to enable an application with Redis support, just select your application from drop down list and press Continue:
The default plan “Hobby Dev” is completely for free and enough for this prototype development.
Once done, in you application dashboard you can see the Redis as addon:
and the actual url for this Redis instance is automatically set in application variable which could be used in your program:
You don’t need any additional configuration on Redis, which is now ready for development.
(2) follow the steps in blog Wechat development series 5 – embedded your UI5 application to Wechat app to create menu and two submenu.
It is enough to create menu via postman. You’d better first remove the old menu done in previous blog and recreate a new menu from scratch:
the source code of HTTP post payload for the new menu creation:
{
"button":[
{
"name":"UI5",
"sub_button":[{
"type": "view",
"name": "Jerry List",
"url": "http://wechatjerry.herokuapp.com/ui5"
},{
"type": "click",
"name": "Other UI5 application",
"key": "dataQuery"
}]
},
{
"name":"Conversation",
"sub_button":[{
"type": "click",
"name": "Review",
"key": "review"
},{
"type": "click",
"name": "Delete",
"key": "delete"
}]
}
]
}
(3) Now every time when Tuning service receives a query from end user and is ready to send the answer of this query, add logic to record this conversation detail.
Just add one line for logging in tuning.js:
The conversationLogService is implemented in conversationLogService.js, which simply delegates the logging call to Redis service wrapper module.
Date.prototype.today = function () {
return ((this.getDate() < 10)?"0":"") + this.getDate() +"/"+(((this.getMonth()+1) < 10)?"0":"") + (this.getMonth()+1) +"/"+ this.getFullYear();
}
Date.prototype.timeNow = function () {
return ((this.getHours() < 10)?"0":"") + this.getHours() +":"+ ((this.getMinutes() < 10)?"0":"") + this.getMinutes() +":"+ ((this.getSeconds() < 10)?"0":"") + this.getSeconds();
}
function logConversation(wholeContent, question, answer){
var fromUserId = formattedValue(getXMLNodeValue('FromUserName', wholeContent));
var toUserId = formattedValue(getXMLNodeValue('ToUserName', wholeContent));
var fromUserName = config.userMap[fromUserId] || fromUserId;
var toUserName = config.userMap[toUserId] || toUserId;
var datetime = "Send Time: " + new Date().today() + " " + new Date().timeNow();
redisClient.insert(toUserId, objectToString(fromUserName, toUserName, datetime, question, answer));
};
function objectToString(fromUserName, toUserName, datetime, question, answer){
var record = {
"from": fromUserName,
"to": toUserName,
"sendTime": datetime,
"question": question,
"answer": answer
};
return JSON.stringify(record);
}
function getList(sToUserOpenId){
return redisClient.getList(sToUserOpenId);
}
function deleteLog(sToUserOpenId){
return redisClient.clearList(sToUserOpenId);
}
var oService = {
log: logConversation,
getLog: getList,
deleteLog: deleteLog
}
module.exports = oService;
Redis service wrapper module is implemented in file redisClient.js.
This wrapper module is built on top of open source Redis module for nodejs, whose source code could be found from github: https://github.com/NodeRedis/node_redis
var redis = require("redis"),
client = redis.createClient(process.env.REDIS_URL || "redis://h:p99a8dd0d92871b9ffe7a026e6d70beecd7f2a0e743fa1e2840a58ce048f41c4a@ec2-34-237-158-248.compute-1.amazonaws.com:9479"); // by default localhost will be used!!
client.on("error", function (err) {
console.log("Trouble......... Redis startup failed: " + err);
});
function insertIntoList(sOpenId, oElement){
client.lpush(sOpenId, oElement);
}
function clearList(sOpenId){
return new Promise(function(resolve,reject){
client.del(sOpenId, function(error, count){
if(error){
console.log("error when clear list:" + error);
reject(error);
}
var reply = "list clear successfully";
console.log(reply);
resolve(reply);
});
});
}
function getListContent(sOpenId){
return new Promise(function(resolve,reject){
client.lrange(sOpenId, 0, -1, function(err, reply) {
console.log("content for list: " + sOpenId + " **********: " + reply + "***");
var content = reply;
if( content == ""){
content = "no conversation log found.";
console.log("reject content: " + content);
reject(content);
}
else {
resolve(formatToWechat(content));
}
});
});
}
function formatToWechat(raw){
var formatted = "[" + raw + "]";
var result = "";
var logs = JSON.parse(formatted);
for( var i = 0; i < logs.length; i++){
var record = "record[" + i + "]:" + " [[from]] " + logs[i].from
+ " [[to]] " + logs[i].to + " [[sendTime]] " + logs[i].sendTime + " [[question]] " + logs[i].question
+ " [[answer]] " + logs[i].answer;
if( i === 0){
result = record;
}
else{
result = result + "\n" + "\n" + record;
}
}
return result;
}
var oRedisClient = {
insert: insertIntoList,
clearList: clearList,
getList: getListContent
};
module.exports = oRedisClient;
(4) implement event handling logic when menu “review” and “delete” are pressed.
Corresponding API provided by Redis are called to read log records from Redis or just clear the list where the log records are stored.
要获取更多Jerry的原创文章,请关注公众号"汪子熙":
相关文章
- 使用Redis简化数据存储的管理(redis存储)
- 阿里推出新技术:Redis即将革新缓存!(阿里redis)
- Redis极速磁盘存储技术突破性进展(redis磁盘存储)
- 提升Redis性能:优化数据更新效率(redis更新效率)
- 如何快速查看Redis存储的数据(查看redis存储的数据)
- Redis备份与还原实践(redis备份还原)
- Redis的高效写入提升性能(redis写入性能)
- 微信钱包如何结合Redis加速支付体验(微信链接redis)
- 存储海量数据,Redis存储更便捷(并发量多大用redis)
- 火热的并发访问探索Redis篇(并发访问redis)
- 倒入Redis,实现表数据本地存储(表数据 倒入 redis)
- 电子订单存储于Redis中稳定性提升数据处理效率(电子订单存放redis)
- 探索Redis新增键值对的奥秘(查看redis新增的键值)
- 红色健康档案在Redis中存储的秘密(健康档案 redis)
- 可用性保证Redis 热点数据可靠性立信不负所托(保证redis 热点数据)
- 加速数据处理使用Redis加快信息存储(使用redis存储信息)
- 稳健可靠Redis集群环境搭建实践(redis集群环境建设)
- 借助Redis集群状态快速检测(redis 集群状态检测)
- 深究原因Redis集群查询速度缓慢(redis集群查询速度慢)
- Redis集群安全存储与取值(redis集群存储和取值)
- Redis集群构建解决数据存储问题(redis集群如何存储)
- 解放双手Redis开启新的应用场景(redis适用领域)
- Redis面面俱到的解决方案(redis详细解决方案)
- Redis妙用编写高效的存储过程(redis编写存储过程)
- 基于Redis的运行逻辑探究(redis运行逻辑)