441 lines
20 KiB
C#
441 lines
20 KiB
C#
using Api.Framework;
|
||
using Api.Framework.SDK;
|
||
using AutoAnswer.Entitys;
|
||
using AutoAnswer.Properties;
|
||
using Chat.Framework;
|
||
using Api.Framework.Tools;
|
||
using Microsoft.JScript;
|
||
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text.RegularExpressions;
|
||
using System.Threading;
|
||
using static AutoAnswer.Controls.Enums;
|
||
using System.Threading.Tasks;
|
||
using Chat.Framework.WXSdk.IPAD;
|
||
using Chat.Framework.WXSdk.Implement;
|
||
|
||
namespace AutoAnswer
|
||
{
|
||
|
||
public class Class1 : Plugin
|
||
{
|
||
public Class1()
|
||
{
|
||
this.Logo = Resources.问答;
|
||
this.Name = Resources.PluginName;
|
||
this.Note = Resources.PluginNote;
|
||
}
|
||
|
||
#region 自定义变量
|
||
public static Config Config;
|
||
private MainForm mainForm = null;
|
||
#endregion
|
||
|
||
public override void Start()
|
||
{
|
||
try
|
||
{
|
||
var session = ApiClient.GetSession();
|
||
#region 判断表是否存在,不存在创建表
|
||
if (!session.TableExist<fl_plugin_autoanswer_definedlib>())
|
||
{
|
||
try
|
||
{
|
||
session.CreateTable<fl_plugin_autoanswer_definedlib>();
|
||
|
||
if (session.TableExist<fl_plugin_autoanswer_userdefinedlibrary>())
|
||
{
|
||
var definedLibList = session.Find<fl_plugin_autoanswer_userdefinedlibrary>("");
|
||
if (definedLibList != null && definedLibList.Count != 0)
|
||
{
|
||
var dlibList = new List<fl_plugin_autoanswer_definedlib>();
|
||
foreach (var item in definedLibList)
|
||
{
|
||
dlibList.Add(new fl_plugin_autoanswer_definedlib()
|
||
{
|
||
antistop = item.antistop,
|
||
chat_type = item.chat_type,
|
||
content = item.content,
|
||
is_alert_admin = item.is_alert_admin,
|
||
match_pattern = item.match_pattern,
|
||
specific_robot_setting_text = string.Empty
|
||
});
|
||
}
|
||
session.Insertable(dlibList).ExecuteCommand();
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{ }
|
||
}
|
||
if (!session.TableExist<fl_plugin_autoanswer__log>()) session.CreateTable<fl_plugin_autoanswer__log>();
|
||
#endregion
|
||
|
||
//创建配置文件
|
||
Config = this.ReadConfig<Config>();
|
||
SDK.ReciveIMEvent += SDK_ReciveIMEvent;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
this.OnLog(ex.Message);
|
||
}
|
||
}
|
||
|
||
public override void ShowForm()
|
||
{
|
||
|
||
try
|
||
{
|
||
if (mainForm == null || mainForm.IsDisposed)
|
||
{
|
||
mainForm = new MainForm();
|
||
mainForm.Show();
|
||
}
|
||
mainForm.TopMost = true;
|
||
mainForm.TopMost = false;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
this.OnLog(ex.Message);
|
||
}
|
||
}
|
||
|
||
public override void Stop()
|
||
{
|
||
try
|
||
{
|
||
if (mainForm != null)
|
||
{
|
||
mainForm.CloseForm();
|
||
mainForm = null;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
this.OnLog(ex.Message);
|
||
}
|
||
}
|
||
|
||
private void SDK_ReciveIMEvent(object sender, ReciveIMEvent e)
|
||
{
|
||
try
|
||
{
|
||
if (Config.TuLing_OnOff)
|
||
{
|
||
if (e.Message.Contains(@"<appmsg appid=")) return;
|
||
if (e.Message.Contains(@"<emoji fromusername")) return;
|
||
string regexMess = string.IsNullOrEmpty(Config.TuLing_prefix) ? @"(?<text>[\w\W]+)" : "^(" + Config.TuLing_prefix.Replace("$", @"\$").Replace("^", @"\^") + @")(?<text>[\w\W]+)";
|
||
var reg = Regex.Match(e.Message.Trim(), regexMess);
|
||
if (reg.Success)
|
||
{
|
||
string htmlResult = Tools.GetHtml(reg.Groups["text"].Value, e.Username);
|
||
var _mess = string.Empty;
|
||
if (!Regex.IsMatch(htmlResult, @"""intent"":{ ""code"":(5000|6000|4000|4001|4002|4003|4004|4005|4007|4100|4200|4300|4400|4500|4600|4602|7002|8008)}"))
|
||
{
|
||
var result = CsharpHttpHelper.HttpExtend.JsonToDictionary(htmlResult);
|
||
var results = result["results"] as ArrayList;
|
||
var obj = results[0] as Dictionary<string, object>;
|
||
var vaules = obj["values"] as Dictionary<string, object>;
|
||
e.SendMessage(vaules["text"].ToString());
|
||
if (Config.CellCustomerServiceSwitch == Api.Framework.Enums.SwitchType.开启) return;
|
||
}
|
||
else
|
||
this.OnLog("图灵响应异常");
|
||
}
|
||
}
|
||
|
||
//是否通知管理员
|
||
bool isAlertAdmin;
|
||
bool isAutoAnswer, issendstatus = false;
|
||
string mess = MessageFactory(e, out isAlertAdmin, out isAutoAnswer);
|
||
bool issend = false;
|
||
if (!string.IsNullOrWhiteSpace(mess) && !isAutoAnswer)//非自动回复消息
|
||
{
|
||
e.SendMessage(mess);
|
||
issend = true;
|
||
//发送管理员
|
||
if (isAlertAdmin)
|
||
{
|
||
string msg = string.Format(@"呼叫客服
|
||
————
|
||
微信账号:{0}
|
||
微信昵称:{1}
|
||
客户账号:{2}
|
||
客户昵称:{3}
|
||
客户备注:{4}
|
||
呼叫时间:{5}
|
||
呼叫内容:{6}", e.RobotName, e.RobotNick, e.Username, e.RealNick, e.NickName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), e.Message);
|
||
Thread.Sleep(300);
|
||
ApiClient.SendNoticeMessage(msg, Config.notice_robotname);
|
||
ApiClient.SendAdminEmail(ApiClient.Setting.SystemConfig.account_admin_email, "客户留言提醒", msg, true);
|
||
}
|
||
}
|
||
|
||
#region 呼叫客服
|
||
if (Class1.Config.CellCustomerServiceSwitch == Api.Framework.Enums.SwitchType.开启)
|
||
{
|
||
if (string.IsNullOrEmpty(e.Groupid)) //私聊信息
|
||
{
|
||
var _event = e.Event as Chat.Framework.WXSdk.Events.WXReiceveFriendMsg;
|
||
if (_event != null && _event.IsRobot)//判断是否自己给自己发送消息
|
||
return;
|
||
}
|
||
|
||
//触发呼叫客服关键词
|
||
if (!string.IsNullOrEmpty(Class1.Config.TriggerAntistop) && Regex.IsMatch(e.Message, Class1.Config.TriggerAntistop))
|
||
{
|
||
var weekDays = Class1.Config.WeekDay.Replace(",", ",").Split(',');//获取设置的上班星期
|
||
if (weekDays != null && weekDays.Length != 0)
|
||
{
|
||
string week = ((WorkdayType)Enum.ToObject(typeof(WorkdayType), System.Convert.ToInt32(DateTime.Now.DayOfWeek.ToString("d")))).ToString();
|
||
//为上班星期
|
||
if (weekDays.Contains(week))
|
||
{
|
||
var isOnDutyTime = false;//记录当前时间是否为上班时间区间
|
||
var now = DateTime.Now;
|
||
|
||
for (int i = 0; i < Class1.Config.WorkDayTimes.Length; i++)
|
||
{
|
||
if (!string.IsNullOrWhiteSpace(Class1.Config.WorkDayTimes[i]))
|
||
{
|
||
var times = Class1.Config.WorkDayTimes[i].Trim().Split('-');
|
||
if (times.Length == 2)
|
||
{
|
||
var begin = DateTime.Parse(times[0].Trim());
|
||
var end = DateTime.Parse(times[1].Trim());
|
||
if (begin <= now && now <= end)
|
||
{
|
||
isOnDutyTime = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//为上班的时间段
|
||
if (isOnDutyTime)
|
||
e.SendMessage(Class1.Config.OnDuty_ReplyMessage);
|
||
else
|
||
e.SendMessage(Class1.Config.OffDuty_ReplyMessage);
|
||
}
|
||
//非上班星期
|
||
else
|
||
e.SendMessage(Class1.Config.UnWeekDay_ReplyMessage);
|
||
string msg = string.Empty;
|
||
if (Config.MatchModel == Enums.ReplyModel.传递最近5条消息)
|
||
{
|
||
var session = ApiClient.GetSession();
|
||
var hist_message = session.Find<fl_plugin_autoanswer__log>("select * from fl_plugin_autoanswer__log where datetime > @datetime and useraccount=@useraccount and chatType = @chatType order by id desc limit 0,5", new { datetime = DateTime.Now.AddMinutes(-10).ToString("yyyy-MM-dd HH:mm:ss"), useraccount = e.Username, chatType = (int)e.ChatType });
|
||
string message_hist = string.Empty;
|
||
int number = 1;
|
||
foreach (var item in hist_message)
|
||
{
|
||
if (item.content.Contains("<msg>")) continue;
|
||
|
||
message_hist += number + "." + GlobalObject.unescape(item.content) + "\r\n";
|
||
number++;
|
||
}
|
||
message_hist = message_hist.Trim();
|
||
if (message_hist.Length > 200) message_hist = message_hist.Substring(0, 200) + "...";
|
||
msg = string.Format(@"客户呼叫提醒
|
||
————
|
||
微信账号:{0}
|
||
微信昵称:{1}
|
||
客户账号:{2}
|
||
客户昵称:{3}
|
||
客户备注:{4}
|
||
呼叫时间:{5}
|
||
————
|
||
未回复:
|
||
{6}", e.RobotName, e.RobotNick, e.Username, e.RealNick, e.NickName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), message_hist);
|
||
}
|
||
else
|
||
{
|
||
if (!e.Message.Contains("<msg>"))
|
||
{
|
||
msg = string.Format(@"客户呼叫提醒
|
||
————
|
||
微信账号:{0}
|
||
微信昵称:{1}
|
||
客户账号:{2}
|
||
客户昵称:{3}
|
||
客户备注:{4}
|
||
呼叫时间:{5}
|
||
————
|
||
消息:
|
||
{6}", e.RobotName, e.RobotNick, e.Username, e.RealNick, e.NickName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), e.Message.Trim());
|
||
}
|
||
}
|
||
if (!string.IsNullOrWhiteSpace(msg))
|
||
{
|
||
var wx = e.Sender as WeixinBase;
|
||
if (wx != null && Config.IsStickSwitch == Api.Framework.Enums.SwitchType.开启)
|
||
wx.EditContacts(e.Username, Chat.Framework.WXSdk.Implement.EditContactsType.置顶, e.NickName);
|
||
|
||
issendstatus = true;
|
||
ApiClient.SendNoticeMessage(msg, Config.notice_robotname);
|
||
if (Config.ForcedResponse == Api.Framework.Enums.SwitchType.开启 && !string.IsNullOrWhiteSpace(mess) && !issend)
|
||
{
|
||
Thread.Sleep(500);
|
||
e.SendMessage(Tools.UrlEncodFactory(Config.DefaultContents[new Random(Guid.NewGuid().GetHashCode()).Next(0, Config.DefaultContents.Count)]));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
if (!string.IsNullOrWhiteSpace(mess) && isAutoAnswer && !issendstatus)
|
||
{
|
||
e.SendMessage(mess);
|
||
//发送管理员
|
||
if (isAlertAdmin)
|
||
{
|
||
string msg = string.Format(@"呼叫客服
|
||
————
|
||
微信账号:{0}
|
||
微信昵称:{1}
|
||
客户账号:{2}
|
||
客户昵称:{3}
|
||
客户备注:{4}
|
||
呼叫时间:{5}
|
||
呼叫内容:{6}", e.RobotName, e.RobotNick, e.Username, e.RealNick, e.NickName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), e.Message);
|
||
var wx = e.Sender as WeixinBase;
|
||
if (wx != null && Config.IsStickSwitch == Api.Framework.Enums.SwitchType.开启)
|
||
{
|
||
wx.EditContacts(e.Username, Chat.Framework.WXSdk.Implement.EditContactsType.置顶, e.NickName);
|
||
}
|
||
Thread.Sleep(300);
|
||
ApiClient.SendNoticeMessage(msg, Config.notice_robotname);
|
||
ApiClient.SendAdminEmail(ApiClient.Setting.SystemConfig.account_admin_email, "客户留言提醒", msg, true);
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
this.OnLog("C:" + ex.Message);
|
||
e.SendMessage(ApiClient.Setting.SystemConfig.msg_error);
|
||
}
|
||
}
|
||
|
||
private string cache_autoanswer_key = "cache_autoanswer_key";
|
||
|
||
#region 自定义回复处理方法(非图灵)
|
||
/// <summary>
|
||
/// 自定义回复处理方法(非图灵)
|
||
/// </summary>
|
||
/// <param name="mess"></param>
|
||
private string MessageFactory(ReciveIMEvent e, out bool isAlertAdmin, out bool isAutoAnswer)
|
||
{
|
||
isAutoAnswer = false;
|
||
try
|
||
{
|
||
var session = ApiClient.GetSession();
|
||
//先看全部匹配的情况,是否满足
|
||
var wordbank = session.Find<fl_plugin_autoanswer_definedlib>("select * from fl_plugin_autoanswer_definedlib where antistop = @antistop and match_pattern = '0' and chat_type like @chattype [随机排序]", new { antistop = GlobalObject.escape(e.Message), chattype = "%" + (int)e.ChatType + "%" }).FirstOrDefault();
|
||
//在看模糊匹配,是否满足
|
||
if (wordbank == null)
|
||
{
|
||
var wordbanks = Tools.wordbanck_cache.Where(f => f.chat_type.Contains(((int)e.ChatType).ToString())).ToList();
|
||
wordbank = wordbanks.FirstOrDefault(f => e.Message.Trim().Contains(GlobalObject.unescape(f.antistop)));
|
||
|
||
//还不满足 择用 正则表达式匹配.获取所有"平台"模糊模式的集合 再通过正则筛选 是否满足
|
||
if (wordbank == null)
|
||
wordbank = wordbanks.FirstOrDefault(f => f.chat_type.Contains(((int)e.ChatType).ToString()) && Regex.IsMatch(e.Message.Trim(), GlobalObject.unescape(f.antistop)));
|
||
}
|
||
bool is_robot = false;
|
||
//如果以上都没有存在的,那看下是否开启默认回复 与 是否开启记录功能了
|
||
if (wordbank == null)
|
||
{
|
||
isAlertAdmin = false;
|
||
string mess = string.Empty;
|
||
|
||
if (string.IsNullOrEmpty(e.Groupid) && Config.Is_Top_User)
|
||
{
|
||
var wx = e.Sender as WeixinBase;
|
||
if (wx != null)
|
||
wx.EditContacts(e.Username, EditContactsType.置顶, e.NickName);
|
||
}
|
||
|
||
//默认回复
|
||
if (Config.Is_Auto_Answer && Config.DefaultContents.Count != 0)
|
||
{
|
||
if (string.IsNullOrEmpty(e.Groupid)) //私聊信息
|
||
{
|
||
if ((e.GetMemberinfo().upd_time - e.GetMemberinfo().crt_time).TotalSeconds > 4)
|
||
{
|
||
var value = ApiClient.Cache.Get<List<long>>(cache_autoanswer_key);
|
||
var _event = e.Event as Chat.Framework.WXSdk.Events.WXReiceveFriendMsg;
|
||
if (_event != null && _event.IsRobot)//判断是否自己给自己发送消息
|
||
{
|
||
is_robot = true;
|
||
if (value == null)
|
||
value = new List<long>();
|
||
value.Add(e.GetMemberinfo().id);
|
||
ApiClient.Cache.Set(cache_autoanswer_key, value, 5);
|
||
return string.Empty;
|
||
}
|
||
else if (value != null && value.Contains(e.GetMemberinfo().id))
|
||
return string.Empty;
|
||
}
|
||
}
|
||
mess = Tools.UrlEncodFactory(Config.DefaultContents[new Random(Guid.NewGuid().GetHashCode()).Next(0, Config.DefaultContents.Count)]);
|
||
isAutoAnswer = true;
|
||
}
|
||
if (Config.Is_Log && !is_robot)
|
||
AddAutoanswerLog(e.Message.Trim(), e.ChatType, e.RobotNick, e.Username, e.NickName, true);
|
||
return mess;
|
||
}
|
||
else //处理信息将随机的信息返回
|
||
{
|
||
string[] result = Tools.UrlEncodFactory(GlobalObject.unescape(wordbank.content), false).Split(new string[] { "\r\n-----------分割线-----------\r\n", "\r\n-----------分割线-----------", "-----------分割线-----------\r\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||
isAlertAdmin = (wordbank.is_alert_admin == 1);
|
||
return result[new Random(Guid.NewGuid().GetHashCode()).Next(0, result.Length)];
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
this.OnLog(ex.Message);
|
||
}
|
||
isAlertAdmin = false;
|
||
return string.Empty;
|
||
}
|
||
#endregion
|
||
|
||
#region 自动记录包含默认回复的关键词
|
||
/// <summary>
|
||
/// 自动记录包含默认回复的关键词
|
||
/// </summary>
|
||
/// <param name="antistop"></param>
|
||
/// <param name="chatType"></param>
|
||
/// <param name="username"></param>
|
||
/// <param name="nicknname"></param>
|
||
/// <param name="status"></param>
|
||
private void AddAutoanswerLog(string mess, ChatType chatType, string robotnick, string username, string nicknname, bool status)
|
||
{
|
||
try
|
||
{
|
||
var recordignored = new fl_plugin_autoanswer__log()
|
||
{
|
||
content = GlobalObject.escape(mess),
|
||
robot_name = robotnick,
|
||
chatType = chatType,
|
||
useraccount = username,
|
||
username = GlobalObject.escape(nicknname),
|
||
status = status,
|
||
datetime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
|
||
};
|
||
var session = ApiClient.GetSession();
|
||
session.Insertable(recordignored).ExecuteCommand(); ;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
this.OnLog(ex.Message);
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
}
|
||
}
|