package main import ( "fmt" "log" "os" "time" ) type procEchoDef struct { chatProcedureID } var procEcho = procEchoDef{} func (m *procEchoDef) init(ss *openIDSessionData) { ss.setProcedure(m.getID()) ss.refreshExpire(600) } func (m *procEchoDef) clean(ss *openIDSessionData) { ss.Procedure = "" //log.Println(*ss) } func (m *procEchoDef) start(ss *openIDSessionData, in *InWechatMsg) { ss.setKvPair("started at", time.Now().Format("2006/03:04:05")) } func (m *procEchoDef) serve(ss *openIDSessionData, in *InWechatMsg) (processed bool) { stopEcho := false if in.header.MsgType == "text" { if in.body.(TextMsg).Content == "结束Echo" || in.body.(TextMsg).Content == "结束echo" { stopEcho = true } } if in.header.MsgType == "voice" { if in.body.(VoiceMsg).Recognition == "退出退出。" { stopEcho = true } } if stopEcho { in.replyText("echo 正式结束") procEcho.summary(ss) procEcho.clean(ss) } else { ss.refreshExpire(600) procEcho.doCommand(ss, in) } processed = true return } func (m *procEchoDef) summary(ss *openIDSessionData) { msg := ss.getVal("started at") allmsg := ss.getVal("msg") //may be too long if len(allmsg) > 2000 { sub := allmsg[0:2000] + "..." allmsg = sub } msg = msg + "\n" + allmsg kfSendTxt(ss.OpenID, msg) } func (m *procEchoDef) intro(ss *openIDSessionData, in *InWechatMsg) { in.replyText("请输入不同类型的微信信息,比如文字,图片,视频,地址,链接,我们将原样回应您") kfSendTxt(ss.OpenID, "10分钟静默之后 Echo将自动结束,\n输入 [结束Echo],或者语音 ‘退出退出', 清除Echo模式") } func (m *procEchoDef) doCommand(ss *openIDSessionData, in *InWechatMsg) { openID := in.header.FromUserName str, err := BuildTextMsg(openID, "default") log.Println("echoCommand :" + in.header.MsgType) switch in.body.(type) { case TextMsg: m := in.body.(TextMsg) str, err = BuildTextMsg(openID, m.Content+"\n\n关键词 [转接] 将后续信息都转接到 客服 测试版") procEcho.recordMsg(ss, "文字:"+m.Content) in.replyXML(str) case PicMsg: m := in.body.(PicMsg) str = buildPicMsg(openID, m.MediaId) in.replyXML(str) procEcho.recordMsg(ss, "图片:..") case VoiceMsg: m := in.body.(VoiceMsg) str = buildVoiceMsg(openID, m.MediaId) in.replyXML(str) procEcho.recordMsg(ss, "音译:"+m.Recognition) kfSendTxt(openID, "翻译结果:"+m.Recognition) case VideoMsg: m := in.body.(VideoMsg) str = buildVideoMsg(openID, "e2iNEiSxCX5TV1WbFd0TQMn5lilY3bylh1--lDBwi7I", "航拍春日哈工大", m.MediaId) in.replyXML(str) procEcho.recordMsg(ss, "视频:..") case ShortVideoMsg: m := in.body.(ShortVideoMsg) str = buildVideoMsg(openID, "e2iNEiSxCX5TV1WbFd0TQMn5lilY3bylh1--lDBwi7I", "航拍春日哈工大", m.MediaId) in.replyXML(str) procEcho.recordMsg(ss, "小视频:..") case LocationMsg: m := in.body.(LocationMsg) mid := location2MediaID(m.Location_X, m.Location_Y) str = buildPicMsg(openID, mid) in.replyXML(str) url := location2URL(m.Location_X, m.Location_Y) kfSendTxt(openID, url+"\n"+fmt.Sprintf("long=%f, lat=%f, scale=%d", m.Location_X, m.Location_Y, m.Scale)) procEcho.recordMsg(ss, "坐标:..") case LinkMsg: m := in.body.(LinkMsg) str, _ = BuildTextMsg(openID, m.Url) in.replyXML(str) kfSendTxt(openID, m.Title+m.Description) procEcho.recordMsg(ss, "链接:"+m.Title) case EventMsg: procEcho.doEvents(ss, in) default: str, err = BuildTextMsg(openID, "text message") } if err != nil { log.Println("build response failed") } return } func (m *procEchoDef) doEvents(ss *openIDSessionData, in *InWechatMsg) { openID := in.header.FromUserName str := "" e := in.body.(EventMsg) //log.Println("Event = " + m.Event) procEcho.recordMsg(ss, "事件:"+e.Event) switch e.Event { case "LOCATION": mid := location2MediaID(e.Latitude, e.Longitude) str = buildPicMsg(openID, mid) case "CLICK": str, _ = BuildTextMsg(openID, e.EventKey) case "subscribe": str, _ = BuildTextMsg(openID, e.EventKey) case "unsubscribe": str, _ = BuildTextMsg(openID, e.EventKey) case "SCAN": str, _ = BuildTextMsg(openID, e.EventKey) case "VIEW": str, _ = BuildTextMsg(openID, e.EventKey) case "kf_create_session": kfSendTxt(openID, e.KfAccount) //str, _ = BuildTextMsg(openID, m.KfAccount) // response msg is ignored by wechat case "kf_close_session": kfSendTxt(openID, e.KfAccount+"\n close type ="+e.CloseType) //str, _ = BuildTextMsg(openID, m.KfAccount+"\n close type ="+m.CloseType) //response msg is ignored by wechat case "scancode_waitmsg": log.Println(e.ScanCodeInfo.ScanResult) log.Println(e.ScanCodeInfo.ScanType) msg := fmt.Sprintf("ScanResult =%s, ScanType=%s", e.ScanCodeInfo.ScanResult, e.ScanCodeInfo.ScanType) kfSendTxt(openID, msg) case "pic_photo_or_album": msg := fmt.Sprintf("Count = %d ", e.SendPicsInfo.Count) log.Println(e.SendPicsInfo.Count) for _, v := range e.SendPicsInfo.PicList.Item { log.Println(v.PicMd5Sum) kfSendTxt(openID, v.PicMd5Sum) } kfSendTxt(openID, msg) default: str, _ = BuildTextMsg(openID, " unknown event:"+e.Event) } in.replyXML(str) return } func location2MediaID(lat, long float64) (mediaID string) { url := fmt.Sprintf("https://maps.googleapis.com/maps/api/staticmap?center=%f,%f&markers=color:red|label:S|%f,%f&zoom=17&size=1280x2014", lat, long, lat, long) file, _, _ := saveURL(url) mediaID = uploadImage(file) os.Remove(file) return } func location2URL(lat, long float64) (url string) { url = fmt.Sprintf("http://maps.google.com/maps?z=12&t=m&q=loc:%f+%f", lat, long) log.Println(url) return } func (m *procEchoDef) recordMsg(ss *openIDSessionData, newmsg string) { msg := ss.getVal("msg") msg = msg + newmsg + "\n" ss.setKvPair("msg", msg) }