2022-09-20 03:10:29 +00:00
using Api.Framework ;
using Api.Framework.SDK ;
using Api.Framework.Tools ;
using AutoAnswer.Entitys ;
using AutoAnswer.Properties ;
using Chat.Framework.WXSdk.Implement ;
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 ;
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 > ( "select * from 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
//});
try
{
session . Insertable ( 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
} ) . ExecuteCommand ( ) ;
}
catch ( Exception ex )
{ }
finally
{
Thread . Sleep ( 50 ) ;
}
}
}
}
}
catch ( Exception ex )
{ }
}
if ( ! session . TableExist < fl_plugin_autoanswer__log > ( ) ) session . CreateTable < fl_plugin_autoanswer__log > ( ) ;
if ( ! session . TableExist < fl_plugin_autoanswer_unprocessed > ( ) )
{
session . CreateTable < fl_plugin_autoanswer_unprocessed > ( ) ;
session . AddUnique < fl_plugin_autoanswer_unprocessed > ( "rid" ) ;
}
#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 呼 叫 客 服
2022-10-25 01:07:24 +00:00
if ( Class1 . Config . CellCustomerServiceSwitch = = Api . Framework . Enums . SwitchType . 开 启 & & ! issend )
2022-09-20 03:10:29 +00:00
{
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 , 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 )
{
var str = "微信" ;
if ( e . RobotInfo . type = = ChatType . QQ )
str = "QQ" ;
var robot_str = $"{e.RobotInfo.name}_{str}" ;
isAutoAnswer = false ;
try
{
fl_plugin_autoanswer_definedlib wordbank = null ;
var session = ApiClient . GetSession ( ) ;
#region 这 里 是 指 定 机 器 人 回 复 的 内 容
//先看全部匹配的情况,是否满足
wordbank = session . Find < fl_plugin_autoanswer_definedlib > ( "select * from fl_plugin_autoanswer_definedlib where specific_robot_setting_text != '' and antistop = @antistop and match_pattern = '0' and chat_type like @chattype and specific_robot_setting_text like @specific_robot_setting_text [随机排序]" , new { antistop = GlobalObject . escape ( e . Message ) , chattype = "%" + ( int ) e . ChatType + "%" , specific_robot_setting_text = "%" + robot_str + "%" } ) . FirstOrDefault ( ) ;
List < fl_plugin_autoanswer_definedlib > wordbanks = null ;
//在看模糊匹配,是否满足
if ( wordbank = = null )
{
wordbanks = Tools . WordbanckCache . Where ( f = > f . chat_type . Contains ( ( ( int ) e . ChatType ) . ToString ( ) ) & & ! string . IsNullOrWhiteSpace ( f . specific_robot_setting_text ) & & f . specific_robot_setting_text . Contains ( robot_str ) ) . ToList ( ) ;
wordbank = wordbanks . FirstOrDefault ( f = > e . Message . Trim ( ) . Contains ( GlobalObject . unescape ( f . antistop ) ) ) ;
//还不满足 择用 正则表达式匹配.获取所有"平台"模糊模式的集合 再通过正则筛选 是否满足
if ( wordbank = = null )
{
try
{
wordbank = wordbanks . FirstOrDefault ( f = > Regex . IsMatch ( e . Message . Trim ( ) , GlobalObject . unescape ( f . antistop ) ) ) ;
}
catch ( Exception )
{ }
}
}
#endregion
#region 这 里 是 非 指 定 的 机 器 人
if ( wordbank = = null )
{
wordbank = session . Find < fl_plugin_autoanswer_definedlib > ( "select * from fl_plugin_autoanswer_definedlib where specific_robot_setting_text = '' and 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 )
{
wordbanks = Tools . WordbanckCache . Where ( f = > string . IsNullOrWhiteSpace ( f . specific_robot_setting_text ) & & f . chat_type . Contains ( ( ( int ) e . ChatType ) . ToString ( ) ) ) . ToList ( ) ;
wordbank = wordbanks . FirstOrDefault ( f = > e . Message . Trim ( ) . Contains ( GlobalObject . unescape ( f . antistop ) ) ) ;
//还不满足 择用 正则表达式匹配.获取所有"平台"模糊模式的集合 再通过正则筛选 是否满足
if ( wordbank = = null )
{
try
{
wordbank = wordbanks . FirstOrDefault ( f = > Regex . IsMatch ( e . Message . Trim ( ) , GlobalObject . unescape ( f . antistop ) ) ) ;
}
catch ( Exception )
{ }
}
}
}
#endregion
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 ;
}
//未处理消息转发
var unprocesseds = Tools . FindUnprocesseds ( ) ;
if ( unprocesseds ! = null & & unprocesseds . Count ! = 0 )
{
if ( e . RobotName ! = e . Username )
{
var r = unprocesseds . FirstOrDefault ( f = > f . rid = = e . RobotInfo . id ) ;
if ( r ! = null )
{
var flag = false ;
if ( r . messtype . Contains ( "所有类型" ) )
{
//<msg><appmsg appid="" sdkver=""><title><![CDATA[邀请你加入群聊]]></title><des><![CDATA["先森吳"邀请你加入群聊"云享读书会11期",进入可查看详情。]]></des><action>view</action><type>5</type><showtype>0</showtype><content></content><url><![CDATA[https://support.weixin.qq.com/cgi-bin/mmsupport-bin/addopenimchatroombyinvite?ticket=2FH2Z0J14F3FFNvl]]></url><thumburl><![CDATA[http://wx.qlogo.cn/mmcrhead/2SZcy78xxVvBk0ZCqDjYvKNRx2FVqDTQa6ljgmMf4x4Wib78B92oZOyF21Khx0CSpOyWEibNzV2XM3s1AS2gO2WkuUibAnk2PNG/0]]></thumburl><lowurl></lowurl><appattach><totallen>0</totallen><attachid></attachid><fileext></fileext></appattach><extinfo></extinfo></appmsg><appinfo><version></version><appname></appname></appinfo></msg>
if ( e . Message . Contains ( "appmsg appid=" ) & &
e . Message . Contains ( "<![CDATA[邀请你加入群聊]]>" ) )
flag = false ;
else
flag = true ;
}
//是否转发
var isSend = false ;
var nick = string . Empty ;
if ( ! string . IsNullOrWhiteSpace ( e . Groupid ) & & ( flag | | r . messtype . Contains ( "群聊类型" ) ) )
{
isSend = true ;
if ( e . Sender is WXClientImpl_HOOK )
{
var hook = e . Sender as WXClientImpl_HOOK ;
if ( hook ! = null )
{
if ( hook . Friends . ContainsKey ( e . Groupid ) )
nick = hook . Friends [ e . Groupid ] . NickName ;
}
}
if ( e . Sender is WXClientImpl_QYHOOK )
{
var hook = e . Sender as WXClientImpl_QYHOOK ;
if ( hook ! = null )
{
if ( hook . Friends . ContainsKey ( e . Groupid ) )
nick = hook . Friends [ e . Groupid ] . NickName ;
}
}
if ( e . Sender is WXClientImpl_IPAD )
{
var hook = e . Sender as WXClientImpl_IPAD ;
if ( hook ! = null )
{
if ( hook . Friends . ContainsKey ( e . Groupid ) )
nick = hook . Friends [ e . Groupid ] . NickName ;
}
}
nick = $"群:{nick}" ;
}
else
{
if ( string . IsNullOrWhiteSpace ( e . Groupid ) & & ( flag | | r . messtype . Contains ( "私聊类型" ) ) )
{
isSend = true ;
nick = $"私:{e.RealNick}" ;
}
}
if ( isSend )
{
var reg = Regex . Match ( e . Message , @"(<appmsg[\w\W]+</appmsg>)" , RegexOptions . IgnoreCase ) ;
if ( reg . Success )
{
ApiClient . SendMessage ( e . RobotInfo , r . username , $ @ "{nick}
发 送 人 : { e . NickName }
内 容 : 小 程 序 或 卡 片 消 息 ");
Thread . Sleep ( 500 ) ;
ApiClient . SendMessage ( e . RobotInfo , r . username , reg . Groups [ 1 ] . Value ) ;
}
else
ApiClient . SendMessage ( e . RobotInfo , r . username , $ @ "{nick}
发 送 人 : { e . NickName }
内 容 : { e . Message } ");
}
}
}
}
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
}
}