From 5cc142e00902aa7f882a53c7043fad097339133e Mon Sep 17 00:00:00 2001 From: shylinux Date: Fri, 23 Oct 2020 11:22:31 +0800 Subject: [PATCH] opt chat --- base/aaa/user.go | 11 +- base/web/serve.go | 24 ++- base/web/share.go | 4 +- base/web/spide.go | 4 +- core/chat/header.go | 3 + core/chat/location.go | 15 +- core/chat/river.go | 2 +- core/chat/scan.go | 4 +- core/wiki/feel.go | 5 +- meta.go | 8 +- misc.go | 1 - misc/alpha/alpha.go | 23 +- misc/input/input.go | 11 +- misc/lark/lark.go | 488 +++++++++++++++++------------------------- misc/lark/lark.shy | 20 +- misc/mp/mp.go | 51 +++-- misc/mp/mp.shy | 18 +- misc/wx/wx.go | 204 ++++++++++++------ misc/wx/wx.shy | 28 ++- 19 files changed, 467 insertions(+), 457 deletions(-) diff --git a/base/aaa/user.go b/base/aaa/user.go index 97f086db..6a7f5a42 100644 --- a/base/aaa/user.go +++ b/base/aaa/user.go @@ -80,8 +80,9 @@ func UserRole(m *ice.Message, username interface{}) (role string) { func UserLogin(m *ice.Message, username, password string) bool { if _user_login(m, username, password) { m.Option(ice.MSG_USERNAME, username) + m.Option(ice.MSG_USERNICK, UserNick(m, username)) m.Option(ice.MSG_USERROLE, UserRole(m, username)) - m.Log_AUTH(USERROLE, m.Option(ice.MSG_USERROLE), USERNAME, m.Option(ice.MSG_USERNAME), PASSWORD, strings.Repeat("*", len(password))) + m.Log_AUTH(USERROLE, m.Option(ice.MSG_USERROLE), USERNICK, m.Option(ice.MSG_USERNICK), USERNAME, m.Option(ice.MSG_USERNAME), PASSWORD, strings.Repeat("*", len(password))) return true } return false @@ -89,6 +90,14 @@ func UserLogin(m *ice.Message, username, password string) bool { const ( AVATAR = "avatar" + GENDER = "gender" + MOBILE = "mobile" + EMAIL = "email" + + CITY = "city" + COUNTRY = "country" + PROVINCE = "province" + LANGUAGE = "language" USER_CREATE = "user.create" ) diff --git a/base/web/serve.go b/base/web/serve.go index 039a4114..e6acd152 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -55,14 +55,24 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool { if r.URL.Path == "/" && r.FormValue(SHARE) != "" { m.W = w - s := m.Cmd(SHARE, mdb.SELECT, kit.MDB_HASH, r.FormValue(SHARE)) - if s.Append(kit.MDB_TYPE) == "login" { - Render(m, COOKIE, aaa.SessCreate(m, s.Append(aaa.USERNAME), s.Append(aaa.USERROLE))) - http.Redirect(w, r, kit.MergeURL(r.URL.String(), SHARE, ""), http.StatusTemporaryRedirect) - m.W = nil - return false + defer func() { m.W = nil }() + + if s := m.Cmd(SHARE, mdb.SELECT, kit.MDB_HASH, r.FormValue(SHARE)); s.Append(kit.MDB_TYPE) == "login" { + defer func() { http.Redirect(w, r, kit.MergeURL(r.URL.String(), SHARE, ""), http.StatusTemporaryRedirect) }() + + msg := m.Spawn() + if c, e := r.Cookie(ice.MSG_SESSID); e == nil && c.Value != "" { + if aaa.SessCheck(msg, c.Value); msg.Option(ice.MSG_USERNAME) != "" { + return false // 复用会话 + } + } + + msg.Option(ice.MSG_USERUA, r.Header.Get("User-Agent")) + msg.Option(ice.MSG_USERIP, r.Header.Get(ice.MSG_USERIP)) + Render(msg, COOKIE, aaa.SessCreate(msg, s.Append(aaa.USERNAME), s.Append(aaa.USERROLE))) + return false // 新建会话 } - m.W = nil + return true } diff --git a/base/web/share.go b/base/web/share.go index 3d6cd57c..5f501788 100644 --- a/base/web/share.go +++ b/base/web/share.go @@ -90,7 +90,7 @@ func init() { kit.MDB_TIME, m.Time(m.Conf(SHARE, "meta.expire")), arg) }}, mdb.SELECT: {Name: "select hash", Help: "查询", Hand: func(m *ice.Message, arg ...string) { - m.Option(mdb.FIELDS, "time,hash,userrole,username,river,storm,type,name,text") + m.Option(mdb.FIELDS, "time,userrole,username,river,storm,type,name,text") m.Cmdy(mdb.SELECT, SHARE, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) }}, mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { @@ -99,7 +99,7 @@ func init() { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Option(mdb.FIELDS, kit.Select("time,hash,userrole,username,river,storm,type,name,text", mdb.DETAIL, len(arg) > 0)) m.Cmdy(mdb.SELECT, SHARE, "", mdb.HASH, kit.MDB_HASH, arg) - m.PushAction("删除") + m.PushAction(mdb.REMOVE) }}, "/share/": {Name: "/share/", Help: "共享链", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Option(mdb.FIELDS, kit.Select("time,hash,userrole,username,river,storm,type,name,text")) diff --git a/base/web/spide.go b/base/web/spide.go index ae6b812c..1efcf5b0 100644 --- a/base/web/spide.go +++ b/base/web/spide.go @@ -302,8 +302,10 @@ func init() { var data interface{} m.Assert(json.NewDecoder(res.Body).Decode(&data)) + m.Optionv("content_data", data) + data = kit.KeyValue(map[string]interface{}{}, "", data) - m.Info("res: %s", kit.Format(data)) + m.Debug("res: %s", kit.Formats(data)) m.Push("", data) } }) diff --git a/core/chat/header.go b/core/chat/header.go index c8d4c026..9ad1cfb8 100644 --- a/core/chat/header.go +++ b/core/chat/header.go @@ -39,6 +39,9 @@ func init() { "pack": {Name: "pack", Help: "打包", Hand: func(m *ice.Message, arg ...string) { m.Cmdy("web.code.webpack", "create") }}, + "wx": {Name: "wx", Help: "微信", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy("web.chat.wx.access", "config") + }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Echo(m.Conf(HEADER, TITLE)) }}, diff --git a/core/chat/location.go b/core/chat/location.go index 9bbda6c8..e9768cc9 100644 --- a/core/chat/location.go +++ b/core/chat/location.go @@ -6,7 +6,6 @@ import ( kit "github.com/shylinux/toolkits" "math" - "net/url" ) func distance(lat1, long1, lat2, long2 float64) float64 { @@ -35,8 +34,8 @@ func init() { LOCATION: {Name: LOCATION, Help: "地理位置", Value: kit.Data(kit.MDB_SHORT, kit.MDB_TEXT)}, }, Commands: map[string]*ice.Command{ - LOCATION: {Name: "location text auto create@location", Help: "地理位置", Action: map[string]*ice.Action{ - mdb.CREATE: {Name: "insert type=text name address latitude longitude", Help: "添加", Hand: func(m *ice.Message, arg ...string) { + LOCATION: {Name: "location text auto create@getLocation", Help: "地理位置", Action: map[string]*ice.Action{ + mdb.CREATE: {Name: "create type=text name address latitude longitude", Help: "添加", Hand: func(m *ice.Message, arg ...string) { _trans(arg, map[string]string{"address": "text"}) m.Cmdy(mdb.INSERT, LOCATION, "", mdb.HASH, arg) }}, @@ -44,7 +43,7 @@ func init() { m.Cmdy(mdb.MODIFY, LOCATION, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH), arg) }}, mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.DELETE, LOCATION, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) + m.Cmdy(mdb.DELETE, LOCATION, "", mdb.HASH, kit.MDB_TEXT, m.Option(kit.MDB_TEXT)) }}, mdb.EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(mdb.EXPORT, LOCATION, "", mdb.HASH) @@ -58,13 +57,7 @@ func init() { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Option(mdb.FIELDS, kit.Select("time,type,name,text,longitude,latitude", mdb.DETAIL, len(arg) > 0)) m.Cmdy(mdb.SELECT, LOCATION, "", mdb.HASH, kit.MDB_TEXT, arg) - m.Table(func(index int, value map[string]string, head []string) { - m.PushRender(kit.MDB_LINK, "a", "百度地图", kit.Format( - "https://map.baidu.com/search/%s/@12958750.085,4825785.55,16z?querytype=s&da_src=shareurl&wd=%s", - url.QueryEscape(kit.Format(value[kit.MDB_TEXT])), url.QueryEscape(kit.Format(value[kit.MDB_TEXT])), - )) - }) - m.PushAction(mdb.REMOVE) + m.PushAction("openLocation", mdb.REMOVE) }}, }, }, nil) diff --git a/core/chat/river.go b/core/chat/river.go index 337da393..adc7f6fb 100644 --- a/core/chat/river.go +++ b/core/chat/river.go @@ -256,7 +256,7 @@ func init() { m.Richs(USER, nil, value[aaa.USERNAME], func(key string, val map[string]interface{}) { val = kit.GetMeta(val) m.Push(aaa.USERNICK, val[aaa.USERNICK]) - m.PushRender(aaa.AVATAR, "img", kit.Format(val["avatar_url"]), kit.Select("60", "240", m.Option(mdb.FIELDS) == mdb.DETAIL)) + m.PushRender(aaa.AVATAR, "img", kit.Format(val[aaa.AVATAR]), kit.Select("60", "240", m.Option(mdb.FIELDS) == mdb.DETAIL)) }) }) diff --git a/core/chat/scan.go b/core/chat/scan.go index adf664e3..e102f484 100644 --- a/core/chat/scan.go +++ b/core/chat/scan.go @@ -15,8 +15,8 @@ func init() { SCAN: {Name: SCAN, Help: "扫码", Value: kit.Data(kit.MDB_SHORT, kit.MDB_TEXT)}, }, Commands: map[string]*ice.Command{ - SCAN: {Name: "scan hash auto create@scan", Help: "扫码", Action: map[string]*ice.Action{ - mdb.CREATE: {Name: "create type=text name=hi text:textarea=hi", Help: "添加", Hand: func(m *ice.Message, arg ...string) { + SCAN: {Name: "scan hash auto create@scanQRCode scanQRCode0=应用扫码", Help: "扫码", Action: map[string]*ice.Action{ + mdb.CREATE: {Name: "create type=text name=hi text:textarea=hi", Help: "扫码", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(mdb.INSERT, SCAN, "", mdb.HASH, arg) }}, mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { diff --git a/core/wiki/feel.go b/core/wiki/feel.go index d418815f..56e0cb4e 100644 --- a/core/wiki/feel.go +++ b/core/wiki/feel.go @@ -16,9 +16,12 @@ func init() { )}, }, Commands: map[string]*ice.Command{ - FEEL: {Name: "feel path auto upload 上一页 下一页 下载 参数", Help: "影音媒体", Meta: kit.Dict( + FEEL: {Name: "feel path auto choose@chooseImage upload 上一页 下一页 下载 参数", Help: "影音媒体", Meta: kit.Dict( "display", "/plugin/local/wiki/feel.js", ), Action: map[string]*ice.Action{ + "choose": {Name: "choose", Help: "本机照片", Hand: func(m *ice.Message, arg ...string) { + _wiki_upload(m, FEEL, m.Option(kit.MDB_PATH)) + }}, web.UPLOAD: {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) { _wiki_upload(m, FEEL, m.Option(kit.MDB_PATH)) }}, diff --git a/meta.go b/meta.go index 4e7e99e4..c3525f87 100644 --- a/meta.go +++ b/meta.go @@ -94,8 +94,12 @@ func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Messa } fallthrough default: - if v = kit.Value(value, k); v == nil { - v = kit.Value(val, k) + if v = value[k]; v == nil { + if v = kit.Value(value, k); v == nil { + if v = val[k]; v == nil { + v = kit.Value(val, k) + } + } } } diff --git a/misc.go b/misc.go index 971d7a87..d4278a06 100644 --- a/misc.go +++ b/misc.go @@ -66,7 +66,6 @@ func (m *Message) PushRender(key, view, name string, arg ...string) *Message { if m.Option(MSG_USERUA) == "" { return m } - if strings.Contains(m.Option(MSG_USERUA), "curl") { return m } diff --git a/misc/alpha/alpha.go b/misc/alpha/alpha.go index 290692f1..3a9b805f 100644 --- a/misc/alpha/alpha.go +++ b/misc/alpha/alpha.go @@ -35,7 +35,7 @@ func _alpha_find(m *ice.Message, method, word string) *ice.Message { } func _alpha_load(m *ice.Message, file, name string) { // 清空数据 - meta := m.Confm(ALPHA, "meta") + meta := m.Confm(ALPHA, kit.MDB_META) m.Assert(os.RemoveAll(path.Join(kit.Format(meta[kit.MDB_STORE]), name))) m.Conf(ALPHA, name, "") @@ -47,8 +47,7 @@ func _alpha_load(m *ice.Message, file, name string) { kit.MDB_LEAST, meta[kit.MDB_LEAST], )) - m.Cmd(mdb.IMPORT, ALPHA, name, kit.MDB_LIST, - m.Cmd(web.CACHE, "catch", "csv", file+".csv").Append(kit.MDB_FILE)) + m.Cmd(mdb.IMPORT, ALPHA, name, kit.MDB_LIST, file) // 保存词库 m.Conf(ALPHA, kit.Keys(name, "meta.limit"), 0) @@ -67,28 +66,16 @@ var Index = &ice.Context{Name: ALPHA, Help: "英汉词典", )}, }, Commands: map[string]*ice.Command{ + ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() }}, + ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save() }}, + ALPHA: {Name: "alpha method=word,line word auto", Help: "英汉", Action: map[string]*ice.Action{ mdb.IMPORT: {Name: "import file=usr/word-dict/ecdict name", Help: "加载词库", Hand: func(m *ice.Message, arg ...string) { _alpha_load(m, m.Option(kit.MDB_FILE), kit.Select(path.Base(m.Option(kit.MDB_FILE)), m.Option(kit.MDB_NAME))) }}, - mdb.SEARCH: {Name: "search", Help: "搜索", Hand: func(m *ice.Message, arg ...string) { - _alpha_find(m.Spawn(), "word", arg[1]).Table(func(index int, value map[string]string, head []string) { - m.Push("file", "") - m.Push("line", arg[1]) - m.Push("text", value["definition"]+"\n"+value["translation"]) - }) - }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { _alpha_find(m, arg[0], arg[1]) }}, - - ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Load() - m.Cmd(mdb.SEARCH, mdb.CREATE, ALPHA, ALPHA, c.Cap(ice.CTX_FOLLOW)) - }}, - ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Save() - }}, }, } diff --git a/misc/input/input.go b/misc/input/input.go index 99d7d114..844fa708 100644 --- a/misc/input/input.go +++ b/misc/input/input.go @@ -139,6 +139,7 @@ func _input_load(m *ice.Message, file string, libs ...string) { } const ( + ZONE = "zone" FILE = "file" CODE = "code" TEXT = "text" @@ -163,17 +164,17 @@ var Index = &ice.Context{Name: INPUT, Help: "输入法", }, Commands: map[string]*ice.Command{ ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() }}, - ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save(INPUT) }}, + ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save() }}, - WUBI: {Name: "wubi method=word,line code= auto", Help: "五笔", Action: map[string]*ice.Action{ - mdb.INSERT: {Name: "insert zone=person text= code= weight=", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - _input_push(m, kit.Select("person", m.Option("zone")), m.Option("text"), m.Option("code"), m.Option("weight")) + WUBI: {Name: "wubi method=word,line code auto", Help: "五笔", Action: map[string]*ice.Action{ + mdb.INSERT: {Name: "insert zone=person text code weight", Help: "添加", Hand: func(m *ice.Message, arg ...string) { + _input_push(m, kit.Select("person", m.Option(ZONE)), m.Option(TEXT), m.Option(CODE), m.Option(WEIGHT)) }}, mdb.EXPORT: {Name: "export file=usr/wubi-dict/person zone=person", Help: "导出", Hand: func(m *ice.Message, arg ...string) { // _input_save(m, kit.Select("usr/wubi-dict/person", m.Option("file")), m.Option("zone")) }}, mdb.IMPORT: {Name: "import file=usr/wubi-dict/person zone=", Help: "导入", Hand: func(m *ice.Message, arg ...string) { - _input_load(m, kit.Select("usr/wubi-dict/person", m.Option("file")), m.Option("zone")) + _input_load(m, kit.Select("usr/wubi-dict/person", m.Option(FILE)), m.Option(ZONE)) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { _input_find(m, arg[0], arg[1], m.Option("cache.limit")) diff --git a/misc/lark/lark.go b/misc/lark/lark.go index 9ca5797e..a2ca2bbd 100644 --- a/misc/lark/lark.go +++ b/misc/lark/lark.go @@ -7,6 +7,7 @@ import ( "github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/web" "github.com/shylinux/icebergs/core/chat" + "github.com/shylinux/icebergs/core/wiki" "github.com/shylinux/toolkits" "encoding/json" @@ -16,19 +17,15 @@ import ( "time" ) -func raw(m *ice.Message, url string, arg ...interface{}) interface{} { - m.Option("header", "Authorization", "Bearer "+m.Cmdx(APP, "token", "bot"), "Content-Type", "application/json") - data := kit.UnMarshal(m.Cmdx(web.SPIDE, LARK, "raw", http.MethodGet, url, arg)) - m.Debug(kit.Formats(data)) - return data +func _lark_get(m *ice.Message, bot string, arg ...interface{}) *ice.Message { + m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, bot), web.ContentType, web.ContentJSON) + return m.Cmd(web.SPIDE, LARK, http.MethodGet, arg) } -func post(m *ice.Message, bot string, arg ...interface{}) { - m.Richs(APP, nil, bot, func(key string, value map[string]interface{}) { - m.Option("header", "Authorization", "Bearer "+m.Cmdx(APP, "token", bot), "Content-Type", "application/json") - m.Cmdy(web.SPIDE, LARK, arg) - }) +func _lark_post(m *ice.Message, bot string, arg ...interface{}) *ice.Message { + m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, bot), web.ContentType, web.ContentJSON) + return m.Cmd(web.SPIDE, LARK, arg) } -func parse(m *ice.Message) { +func _lark_parse(m *ice.Message) { data := m.Optionv("content_data") if data == nil { json.NewDecoder(m.R.Body).Decode(&data) @@ -40,153 +37,143 @@ func parse(m *ice.Message) { switch d := v.(type) { case map[string]interface{}: for k, v := range d { - m.Add("option", k, kit.Format(v)) + m.Add(ice.MSG_OPTION, k, kit.Format(v)) } default: for _, v := range kit.Simple(v) { - m.Add("option", "msg."+k, kit.Format(v)) + m.Add(ice.MSG_OPTION, "msg."+k, kit.Format(v)) } } } } } - m.Info("msg: %v", kit.Formats(data)) + m.Debug("msg: %v", kit.Format(data)) } const ( - ADD_BOT = "add_bot" P2P_CHAT_CREATE = "p2p_chat_create" + ADD_BOT = "add_bot" ) const ( SHIP_ID = "ship_id" OPEN_ID = "open_id" CHAT_ID = "chat_id" - USER_OPEN_ID = "user_open_id" OPEN_CHAT_ID = "open_chat_id" + USER_OPEN_ID = "user_open_id" ) const ( - APP = "app" - SHIP = "ship" - USERS = "users" - GROUP = "group" + LOGIN = "login" + APPID = "appid" + APPMM = "appmm" + TOKEN = "token" + EXPIRE = "expire" +) +const ( + APP = "app" + COMPANY = "company" + EMPLOYEE = "employee" + GROUP = "group" SEND = "send" - FORM = "form" DUTY = "duty" + HOME = "home" + FORM = "form" TALK = "talk" RAND = "rand" - HOME = "home" - - DATE = "date" - META = "meta" - WORD = "word" - - LARK = "lark" ) -var Index = &ice.Context{Name: "lark", Help: "机器人", +const LARK = "lark" + +var Index = &ice.Context{Name: LARK, Help: "机器人", Configs: map[string]*ice.Config{ APP: {Name: APP, Help: "服务配置", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME, - LARK, "https://open.feishu.cn", DUTY, "", "welcome", kit.Dict( + LARK, "https://open.feishu.cn", DUTY, "", "template", kit.Dict( ADD_BOT, "我来也~", P2P_CHAT_CREATE, "让我们做好朋友吧~", ), )}, - SHIP: {Name: SHIP, Help: "组织配置", Value: kit.Data(kit.MDB_SHORT, SHIP_ID)}, - USERS: {Name: USERS, Help: "用户配置", Value: kit.Data(kit.MDB_SHORT, OPEN_ID)}, - HOME: {Name: HOME, Help: "卡片配置", Value: kit.Data(kit.MDB_SHORT, OPEN_ID)}, - META: {Name: META, Help: "卡片配置", Value: kit.Data( - kit.MDB_SHORT, "url", - )}, + COMPANY: {Name: COMPANY, Help: "组织配置", Value: kit.Data(kit.MDB_SHORT, SHIP_ID)}, + EMPLOYEE: {Name: EMPLOYEE, Help: "用户配置", Value: kit.Data(kit.MDB_SHORT, OPEN_ID)}, }, Commands: map[string]*ice.Command{ ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() - m.Cmd(web.SPIDE, mdb.CREATE, LARK, m.Conf(APP, "meta.lark")) + m.Cmd(web.SPIDE, mdb.CREATE, LARK, m.Conf(APP, kit.Keys(kit.MDB_META, LARK))) m.Cmd(DUTY, "boot", m.Conf(cli.RUNTIME, "boot.hostname"), m.Time()) }}, ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Save(APP, SHIP, USERS, META) + m.Save() }}, - APP: {Name: "app [name] auto", Help: "应用", Action: map[string]*ice.Action{ - "login": {Name: "login name id mm", Hand: func(m *ice.Message, arg ...string) { - m.Rich(APP, nil, kit.Dict("name", arg[0], "id", arg[1], "mm", arg[2])) + APP: {Name: "app name auto token login", Help: "应用", Action: map[string]*ice.Action{ + LOGIN: {Name: "login name appid appmm", Help: "登录", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(mdb.INSERT, m.Prefix(APP), "", mdb.HASH, arg) }}, - "token": {Name: "token name", Hand: func(m *ice.Message, arg ...string) { - m.Richs(APP, nil, arg[0], func(key string, value map[string]interface{}) { - if now := time.Now().Unix(); kit.Format(value["token"]) == "" || kit.Int64(value["expire"]) < now { - m.Cmdy(web.SPIDE, LARK, "/open-apis/auth/v3/tenant_access_token/internal/", "app_id", value["id"], "app_secret", value["mm"]) - value["expire"] = kit.Int64(m.Append("expire")) + now - value["token"] = m.Append("tenant_access_token") - m.Set(ice.MSG_RESULT) - } - m.Echo("%s", value["token"]) - }) - }}, - }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - m.Richs(APP, nil, kit.Select(kit.MDB_FOREACH, arg, 0), func(key string, value map[string]interface{}) { - if len(arg) == 0 || arg[0] == "" { - m.Push(key, value, []string{"time", "name", "id", "expire"}) - return + TOKEN: {Name: "token name", Help: "令牌", Hand: func(m *ice.Message, arg ...string) { + m.Option(mdb.FIELDS, "time,appid,appmm,token,expire") + msg := m.Cmd(mdb.SELECT, m.Prefix(APP), "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME)) + if now := time.Now().Unix(); msg.Append(TOKEN) == "" || now > kit.Int64(msg.Append(EXPIRE)) { + sub := m.Cmd(web.SPIDE, LARK, "/open-apis/auth/v3/tenant_access_token/internal/", + "app_id", msg.Append(APPID), "app_secret", msg.Append(APPMM)) + + m.Cmd(mdb.MODIFY, m.Prefix(APP), "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME), + TOKEN, msg.Append(TOKEN, sub.Append("tenant_access_token")), EXPIRE, now+kit.Int64(sub.Append(EXPIRE))) } - m.Push("detail", value) - }) + m.Echo(msg.Append(TOKEN)) + }}, + }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { + m.Option(mdb.FIELDS, kit.Select("time,name,appid,token,expire", mdb.DETAIL, len(arg) > 0)) + m.Cmdy(mdb.SELECT, m.Prefix(APP), "", mdb.HASH, kit.MDB_NAME, arg) }}, - SHIP: {Name: "ship ship_id open_id text", Help: "组织", Action: map[string]*ice.Action{ + COMPANY: {Name: "company ship_id open_id text auto", Help: "组织", Action: map[string]*ice.Action{ "info": {Name: "info ship_id", Hand: func(m *ice.Message, arg ...string) { - m.Richs(APP, nil, "bot", func(key string, value map[string]interface{}) { - data := raw(m, "/open-apis/contact/v1/department/detail/batch_get", - "department_ids", arg[0]) - - kit.Fetch(kit.Value(data, "data.department_infos"), func(index int, value map[string]interface{}) { - m.Push("name", value) - }) + msg := _lark_get(m, "bot", "/open-apis/contact/v1/department/detail/batch_get", "department_ids", m.Option(SHIP_ID)) + kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.department_infos"), func(index int, value map[string]interface{}) { + m.Push("", value) }) }}, - "users": {Name: "users ship_id", Hand: func(m *ice.Message, arg ...string) { - m.Richs(APP, nil, "bot", func(key string, value map[string]interface{}) { - data := raw(m, "/open-apis/contact/v1/department/user/list", - "department_id", arg[0], "page_size", "100", "fetch_child", "true") + "list": {Name: "list ship_id", Hand: func(m *ice.Message, arg ...string) { + msg := _lark_get(m, "bot", "/open-apis/contact/v1/department/user/list", + "department_id", m.Option(SHIP_ID), "page_size", "100", "fetch_child", "true") - kit.Fetch(kit.Value(data, "data.user_list"), func(index int, value map[string]interface{}) { - msg := m.Cmd(USERS, value[OPEN_ID]) - // m.Push("avatar", m.Cmdx(mdb.RENDER, web.RENDER.IMG, msg.Append("avatar_72"))) - m.Push("gender", kit.Select("男", "女", msg.Append("gender") == "2")) - m.Push(kit.MDB_NAME, msg.Append(kit.MDB_NAME)) - m.Push("description", msg.Append("description")) - m.Push(OPEN_ID, msg.Append(OPEN_ID)) - }) + kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.user_list"), func(index int, value map[string]interface{}) { + msg := m.Cmd(EMPLOYEE, value[OPEN_ID]) + m.PushRender(aaa.AVATAR, "img", msg.Append("avatar_72")) + m.Push(aaa.GENDER, kit.Select("女", "男", msg.Append(aaa.GENDER) == "1")) + m.Push(kit.MDB_NAME, msg.Append(kit.MDB_NAME)) + m.Push(kit.MDB_TEXT, msg.Append("description")) + m.Push(OPEN_ID, msg.Append(OPEN_ID)) }) }}, }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - if len(arg) == 0 { - // 组织列表 - data := raw(m, "/open-apis/contact/v1/scope/get/") - kit.Fetch(kit.Value(data, "data.authed_departments"), func(index int, value string) { + if len(arg) == 0 { // 组织列表 + msg := _lark_get(m, "bot", "/open-apis/contact/v1/scope/get/") + kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.authed_departments"), func(index int, value string) { m.Push(SHIP_ID, value) - msg := m.Cmd(m.Prefix(SHIP), "info", value) + msg := m.Cmd(m.Prefix(COMPANY), "info", value) m.Push(kit.MDB_NAME, msg.Append(kit.MDB_NAME)) - m.Push("member_count", msg.Append("member_count")) + m.Push(kit.MDB_COUNT, msg.Append("member_count")) m.Push(CHAT_ID, msg.Append(CHAT_ID)) }) m.Sort(kit.MDB_NAME) - return + + } else if len(arg) == 1 { // 员工列表 + m.Cmdy(m.Prefix(COMPANY), "list", arg[0]) + + } else if len(arg) == 2 { // 员工详情 + m.Cmdy(EMPLOYEE, arg[1]) + + } else { // 员工通知 + m.Cmdy(m.Prefix(SEND), OPEN_ID, arg[1], arg[2:]) } - if len(arg) == 1 { - // 用户列表 - m.Cmdy(m.Prefix(SHIP), USERS, arg[0]) - return - } - // 用户通知 - m.Cmdy(m.Prefix(SEND), OPEN_ID, arg[1], arg[2:]) }}, - USERS: {Name: "users open_id|mobile|email", Help: "用户", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { + EMPLOYEE: {Name: "employee open_id|mobile|email auto", Help: "员工", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { + if len(arg) == 0 { + return + } if strings.HasPrefix(arg[0], "ou_") { - m.Richs(APP, nil, "bot", func(key string, value map[string]interface{}) { - data := raw(m, "/open-apis/contact/v1/user/batch_get", "open_ids", arg[0]) - kit.Fetch(kit.Value(data, "data.user_infos"), func(index int, value map[string]interface{}) { - m.Push("name", value) - }) + msg := _lark_get(m, "bot", "/open-apis/contact/v1/user/batch_get", "open_ids", arg[0]) + kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.user_infos"), func(index int, value map[string]interface{}) { + m.Push(mdb.DETAIL, value) }) return } @@ -195,55 +182,49 @@ var Index = &ice.Context{Name: "lark", Help: "机器人", for i := 0; i < len(arg); i++ { us = append(us, kit.Select("mobiles", "emails", strings.Contains(arg[i], "@")), arg[i]) } - post(m, "bot", http.MethodGet, "/open-apis/user/v1/batch_get_id", us) + + _lark_get(m, "bot", "/open-apis/user/v1/batch_get_id", us) for i := 0; i < len(arg); i++ { m.Echo(m.Append(kit.Keys("data.mobile_users", arg[i], "0.open_id"))) } }}, - GROUP: {Name: "group chat_id open_id text", Help: "群组", Action: map[string]*ice.Action{ - "users": {Name: "users id", Hand: func(m *ice.Message, arg ...string) { - m.Richs(APP, nil, "bot", func(key string, value map[string]interface{}) { - data := raw(m, "/open-apis/chat/v4/info", "chat_id", arg[0]) - - kit.Fetch(kit.Value(data, "data.members"), func(index int, value map[string]interface{}) { - msg := m.Cmd(USERS, value[OPEN_ID]) - // m.Push("avatar", m.Cmdx(mdb.RENDER, web.RENDER.IMG, msg.Append("avatar_72"))) - m.Push("gender", kit.Select("男", "女", msg.Append("gender") == "2")) - m.Push(kit.MDB_NAME, msg.Append(kit.MDB_NAME)) - m.Push("description", msg.Append("description")) - m.Push(OPEN_ID, msg.Append(OPEN_ID)) - }) + GROUP: {Name: "group chat_id open_id text auto", Help: "群组", Action: map[string]*ice.Action{ + "list": {Name: "list chat_id", Hand: func(m *ice.Message, arg ...string) { + msg := _lark_get(m, "bot", "/open-apis/chat/v4/info", "chat_id", m.Option(CHAT_ID)) + kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.members"), func(index int, value map[string]interface{}) { + msg := m.Cmd(EMPLOYEE, value[OPEN_ID]) + m.PushRender(aaa.AVATAR, "img", msg.Append("avatar_72")) + m.Push(aaa.GENDER, kit.Select("女", "男", msg.Append(aaa.GENDER) == "1")) + m.Push(kit.MDB_NAME, msg.Append(kit.MDB_NAME)) + m.Push(kit.MDB_TEXT, msg.Append("description")) + m.Push(OPEN_ID, msg.Append(OPEN_ID)) }) }}, }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - if len(arg) == 0 { - // 群组列表 - m.Richs(APP, nil, "bot", func(key string, value map[string]interface{}) { - m.Option("header", "Authorization", "Bearer "+m.Cmdx(APP, "token", "bot"), "Content-Type", "application/json") - data := raw(m, "/open-apis/chat/v4/list") - kit.Fetch(kit.Value(data, "data.groups"), func(index int, value map[string]interface{}) { - m.Push(CHAT_ID, value[CHAT_ID]) - // m.Push("avatar", m.Cmdx(mdb.RENDER, web.RENDER.IMG, value["avatar"])) - m.Push(kit.MDB_NAME, value[kit.MDB_NAME]) - m.Push("description", value["description"]) - m.Push(OPEN_ID, value["owner_open_id"]) - }) + if len(arg) == 0 { // 群组列表 + msg := _lark_get(m, "bot", "/open-apis/chat/v4/list") + kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.groups"), func(index int, value map[string]interface{}) { + m.Push(CHAT_ID, value[CHAT_ID]) + m.PushRender(aaa.AVATAR, "img", kit.Format(value[aaa.AVATAR]), "72") + m.Push(kit.MDB_NAME, value[kit.MDB_NAME]) + m.Push(kit.MDB_TEXT, value["description"]) + m.Push(OPEN_ID, value["owner_open_id"]) }) m.Sort(kit.MDB_NAME) - return + + } else if len(arg) == 1 { // 组员列表 + m.Cmdy(m.Prefix(GROUP), "list", arg[0]) + + } else if len(arg) == 2 { // 组员详情 + m.Cmdy(EMPLOYEE, arg[1]) + + } else { // 组员通知 + m.Cmdy(m.Prefix(SEND), CHAT_ID, arg[0], arg[2:]) } - if len(arg) == 1 { - // 用户列表 - m.Cmdy(m.Prefix(GROUP), USERS, arg[0]) - return - } - // 用户通知 - m.Cmdy(m.Prefix(SEND), CHAT_ID, arg[0], arg[2:]) }}, - SEND: {Name: "send [chat_id|open_id|user_id|email] user [title] text", Help: "消息", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { + SEND: {Name: "send [chat_id|open_id|user_id|email] target [title] text", Help: "消息", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { var form = kit.Dict("content", kit.Dict()) - switch arg[0] { case CHAT_ID, OPEN_ID, "user_id", "email": form[arg[0]], arg = arg[1], arg[2:] @@ -270,108 +251,48 @@ var Index = &ice.Context{Name: "lark", Help: "机器人", content, line = append(content, line), []interface{}{} continue } - line = append(line, map[string]interface{}{ - "tag": "text", "text": v + " ", - }) + line = append(line, map[string]interface{}{"tag": "text", "text": v + " "}) } content = append(content, line) kit.Value(form, "msg_type", "post") kit.Value(form, "content.post", map[string]interface{}{ - "zh_cn": map[string]interface{}{ - "title": arg[0], - "content": content, - }, + "zh_cn": map[string]interface{}{"title": arg[0], "content": content}, }) } - post(m, "bot", "/open-apis/message/v4/send/", "data", kit.Formats(form)) - }}, - TALK: {Name: "talk text", Help: "聊天", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - // 用户权限 - m.Option(ice.MSG_USERZONE, LARK) - m.Option(ice.MSG_USERNAME, m.Option(OPEN_ID)) - m.Option(ice.MSG_USERNICK, aaa.UserNick(m, m.Option(ice.MSG_USERNAME))) - m.Option(ice.MSG_USERROLE, aaa.UserRole(m, m.Option(ice.MSG_USERNAME))) - m.Info("%s: %s", m.Option(ice.MSG_USERROLE), m.Option(ice.MSG_USERNAME)) - - cmd := kit.Split(arg[0]) - if !m.Right(cmd) { - // 群组权限 - m.Option(ice.MSG_USERNAME, m.Option(OPEN_CHAT_ID)) - m.Option(ice.MSG_USERROLE, aaa.UserRole(m, m.Option(ice.MSG_USERNAME))) - m.Info("%s: %s", m.Option(ice.MSG_USERROLE), m.Option(ice.MSG_USERNAME)) - - if !m.Right(cmd) { - // 没有权限 - m.Cmd(DUTY, m.Option(OPEN_CHAT_ID), m.Option("text_without_at_bot")) - m.Cmd(HOME) - return - } - } - if len(cmd) == 0 { - m.Cmd(HOME) - return - } - - // 执行命令 - msg := m.Cmd(cmd) - if m.Hand = false; !msg.Hand { - msg = m.Cmd(cli.SYSTEM, cmd) - } - if m.Hand = true; msg.Result() == "" { - msg.Table() - } - m.Echo(msg.Result()) + _lark_post(m, "bot", "/open-apis/message/v4/send/", web.SPIDE_DATA, kit.Format(form)) }}, DUTY: {Name: "duty [title] text", Help: "通告", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { m.Cmdy(SEND, m.Conf(APP, "meta.duty"), arg) }}, - RAND: {Name: "rand", Help: "随机", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - msg := m.Cmd(GROUP, USERS, m.Option(OPEN_CHAT_ID)) - list := msg.Appendv("name") - if strings.Contains(m.Option("content"), "誰") { - m.Echo(strings.Replace(m.Option("content"), "誰", list[rand.Intn(len(list))], 1)) - return - } - m.Echo(list[rand.Intn(len(list))]) - }}, - HOME: {Name: "home", Help: "首页", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - list := []string{} + HOME: {Name: "home river storm title", Help: "首页", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { name := kit.Select(m.Option(ice.MSG_USERNAME), m.Option(ice.MSG_USERNICK)) if len(name) > 10 { name = name[:10] } - name += "的应用列表" - link := "https://shylinux.com" + name += "的" + kit.Select("应用列表", arg, 2) text := "" + + link, list := m.Conf(web.SHARE, "meta.domain"), []string{} if len(arg) == 0 { - m.Option("_source", ".") m.Cmd("web.chat./river").Table(func(index int, val map[string]string, head []string) { - m.Option(ice.MSG_RIVER, val["key"]) - m.Cmd("web.chat./storm").Table(func(index int, value map[string]string, head []string) { - list = append(list, val["name"]+"."+value["name"], "cmd", "home "+val["key"]+" "+value["key"]) + m.Cmd("web.chat./river", val[kit.MDB_HASH], chat.TOOL).Table(func(index int, value map[string]string, head []string) { + list = append(list, kit.Keys(val[kit.MDB_NAME], value[kit.MDB_NAME]), + kit.SSH_CMD, kit.Format([]string{"home", val[kit.MDB_HASH], value[kit.MDB_HASH], val[kit.MDB_NAME] + "." + value[kit.MDB_NAME]})) }) }) } else { m.Option(ice.MSG_RIVER, arg[0]) m.Option(ice.MSG_STORM, arg[1]) - m.Richs(chat.RIVER, nil, arg[0], func(key string, val map[string]interface{}) { - m.Richs(chat.RIVER, kit.Keys(kit.MDB_HASH, arg[0], chat.TOOL), arg[1], func(key string, value map[string]interface{}) { - text = kit.Keys(kit.Value(val, "meta.name"), kit.Value(value, "meta.name")) - }) + link = kit.MergeURL(link, chat.RIVER, arg[0], chat.STORM, arg[1]) + m.Cmd("web.chat./river", arg[0], chat.TOOL, arg[1]).Table(func(index int, value map[string]string, head []string) { + list = append(list, value[kit.SSH_CMD], kit.SSH_CMD, kit.Keys(value[kit.SSH_CTX], value[kit.SSH_CMD])) }) - - m.Cmd("web.chat./action").Table(func(index int, value map[string]string, head []string) { - list = append(list, value["name"], "cmd", kit.Keys(value["group"], value["index"])) - }) - link = "https://shylinux.com?river=" + arg[0] + "&storm=" + arg[1] } - m.Cmd(FORM, CHAT_ID, m.Option(OPEN_CHAT_ID), name, text, - "网页应用", "url", link, list, - ) + m.Cmd(FORM, CHAT_ID, m.Option(OPEN_CHAT_ID), name, text, "打开网页", "url", link, list) }}, - FORM: {Name: "form chat_id|open_id|user_id|email user title [text [confirm|value|url arg...]]...", Help: "消息", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { + FORM: {Name: "form chat_id|open_id|user_id|email target title text [confirm|value|url arg...]...", Help: "消息", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { var form = map[string]interface{}{"content": map[string]interface{}{}} switch arg[0] { case CHAT_ID, OPEN_ID, "user_id", "email": @@ -390,10 +311,9 @@ var Index = &ice.Context{Name: "lark", Help: "机器人", actions := []interface{}{} for i := 2; i < len(arg); i++ { button := map[string]interface{}{ - "tag": "button", "text": map[string]interface{}{ + "type": "default", "tag": "button", "text": map[string]interface{}{ "tag": "plain_text", "content": arg[i], }, - "type": "default", } content := arg[i] @@ -404,9 +324,7 @@ var Index = &ice.Context{Name: "lark", Help: "机器人", "text": map[string]interface{}{"tag": "lark_md", "content": arg[i+3]}, }, i+3 case "value": - button[arg[i+1]], i = map[string]interface{}{ - arg[i+2]: arg[i+3], - }, i+3 + button[arg[i+1]], i = map[string]interface{}{arg[i+2]: arg[i+3]}, i+3 case "url": button[arg[i+1]], i = arg[i+2], i+2 default: @@ -423,66 +341,70 @@ var Index = &ice.Context{Name: "lark", Help: "机器人", actions = append(actions, button) } - elements = append(elements, map[string]interface{}{ - "tag": "action", "actions": actions, - }) + elements = append(elements, map[string]interface{}{"tag": "action", "actions": actions}) kit.Value(form, "msg_type", "interactive") kit.Value(form, "card", map[string]interface{}{ - "config": map[string]interface{}{ - "wide_screen_mode": true, - }, + "config": map[string]interface{}{"wide_screen_mode": true}, "header": map[string]interface{}{ - "title": map[string]interface{}{ - "tag": "lark_md", "content": arg[0], - }, + "title": map[string]interface{}{"tag": "lark_md", "content": arg[0]}, }, "elements": elements, }) - post(m, "bot", "/open-apis/message/v4/send/", "data", kit.Formats(form)) + _lark_post(m, "bot", "/open-apis/message/v4/send/", web.SPIDE_DATA, kit.Formats(form)) + }}, + TALK: {Name: "talk text", Help: "聊天", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { + m.Option(ice.MSG_USERZONE, LARK) + + cmds := kit.Split(strings.Join(arg, " ")) + if aaa.UserLogin(m, m.Option(OPEN_ID), ""); !m.Right(cmds) { + if aaa.UserLogin(m, m.Option(OPEN_CHAT_ID), ""); !m.Right(cmds) { + m.Cmd(DUTY, m.Option(OPEN_CHAT_ID), m.Option("text_without_at_bot")) + m.Cmd(HOME) + return // 没有权限 + } + } + + if cmds[0] == HOME { + m.Cmd(HOME, cmds[1:]) + return // 没有命令 + } + + // 执行命令 + if msg := m.Cmd(cmds); msg.Hand == true { + if m.Copy(msg); len(m.Resultv()) == 0 { + m.Table() + } + } else { + m.Cmdy(cli.SYSTEM, cmds) + } + }}, + RAND: {Name: "rand", Help: "随机", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { + msg := m.Cmd(GROUP, EMPLOYEE, m.Option(OPEN_CHAT_ID)) + list := msg.Appendv("name") + if strings.Contains(m.Option("content"), "誰") { + m.Echo(strings.Replace(m.Option("content"), "誰", list[rand.Intn(len(list))], 1)) + return + } + m.Echo(list[rand.Intn(len(list))]) }}, - // DATE: {Name: "date id", Help: "日历", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - // m.Richs(APP, nil, "bot", func(key string, value map[string]interface{}) { - // if len(arg) == 0 { - // data := raw(m, "/open-apis/calendar/v3/calendar_list") - // kit.Fetch(kit.Value(data, "data"), func(index int, value map[string]interface{}) { - // m.Push("", value) - // }) - // return - // } - // data := raw(m, "/open-apis/calendar/v3/calendars/"+arg[0]+"/events") - // kit.Fetch(kit.Value(data, "data"), func(index int, value map[string]interface{}) { - // m.Push("", value) - // }) - // }) - // }}, - // META: {Name: "meta", Help: "日历", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - // m.Richs(META, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) { - // m.Push("image", m.Cmdx(mdb.RENDER, web.RENDER.IMG, value["url"])) - // }) - // }}, web.LOGIN: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, "/msg": {Name: "/msg", Help: "聊天消息", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { data := m.Optionv(ice.MSG_USERDATA) if kit.Value(data, "action") != nil { - m.Option(ice.MSG_USERUA, "MicroMessenger") + m.Option(ice.MSG_USERUA, "") + kit.Fetch(kit.Value(data, "action.value"), func(key string, value string) { m.Option(key, value) }) - kit.Fetch(kit.Value(data, "action.value"), func(key string, value string) { - m.Option(key, value) - }) - - m.Cmdy(TALK, m.Option("cmd")) - m.Cmd(SEND, CHAT_ID, m.Option(OPEN_CHAT_ID), m.Result()) + m.Cmdy(TALK, kit.Parse(nil, "", kit.Split(m.Option(kit.SSH_CMD))...)) + m.Cmd(SEND, CHAT_ID, m.Option(OPEN_CHAT_ID), m.Option(wiki.TITLE)+" "+m.Option(kit.SSH_CMD), m.Result()) return } - switch parse(m); m.Option("msg.type") { - case "url_verification": - // 绑定验证 - m.Option(ice.MSG_OUTPUT, ice.RENDER_RESULT) - m.Echo(kit.Format(map[string]interface{}{"challenge": m.Option("msg.challenge")})) + switch _lark_parse(m); m.Option("msg.type") { + case "url_verification": // 绑定验证 + m.Render(ice.RENDER_RESULT, kit.Format(kit.Dict("challenge", m.Option("msg.challenge")))) case "event_callback": switch m.Option("type") { @@ -491,24 +413,24 @@ var Index = &ice.Context{Name: "lark", Help: "机器人", case P2P_CHAT_CREATE, ADD_BOT: // 创建对话 if m.Options(OPEN_CHAT_ID) { - m.Cmdy(SEND, m.Option(OPEN_CHAT_ID), m.Conf(APP, kit.Dict(kit.MDB_META, "welcome", m.Option("type")))) + m.Cmdy(SEND, m.Option(OPEN_CHAT_ID), m.Conf(APP, kit.Keys(kit.MDB_META, "template", m.Option("type")))) } default: switch m.Option("msg_type") { case "location": case "image": - m.Rich(META, nil, kit.Dict( - "url", m.Option("image_url"), - "width", m.Option("image_width"), - "height", m.Option("image_height"), - )) + // m.Rich(META, nil, kit.Dict( + // "url", m.Option("image_url"), + // "width", m.Option("image_width"), + // "height", m.Option("image_height"), + // )) default: if m.Options(OPEN_CHAT_ID) { if m.Cmdy(TALK, strings.TrimSpace(m.Option("text_without_at_bot"))); len(m.Resultv()) > 0 { m.Cmd(SEND, m.Option(OPEN_CHAT_ID), m.Result()) } } else { - m.Cmd(DUTY, m.Option("msg.type"), kit.Formats(data)) + m.Cmd(DUTY, m.Option("type"), kit.Formats(data)) } } } @@ -518,33 +440,27 @@ var Index = &ice.Context{Name: "lark", Help: "机器人", }}, "/sso": {Name: "/sso", Help: "网页", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { if m.Options("code") { - m.Richs(APP, nil, "bot", func(key string, value map[string]interface{}) { - data := kit.UnMarshal(m.Cmdx(web.SPIDE, LARK, "raw", "/open-apis/authen/v1/access_token", - "code", m.Option("code"), "grant_type", "authorization_code", - "app_access_token", m.Cmdx(APP, "token", "bot"), - )) + msg := m.Cmd(web.SPIDE, LARK, "/open-apis/authen/v1/access_token", "grant_type", "authorization_code", + "code", m.Option("code"), "app_access_token", m.Cmdx(APP, "token", "bot")) - m.Option(aaa.USERZONE, LARK) - m.Option(ice.MSG_USERROLE, aaa.ROOT) - user := kit.Format(kit.Value(data, "data.open_id")) - web.RenderCookie(m, aaa.SessCreate(m, user, aaa.UserRole(m, user))) - m.Render("redirect", m.Conf(web.SHARE, "meta.domain")) + m.Option(aaa.USERZONE, LARK) + user := msg.Append("data.open_id") + web.RenderCookie(m, aaa.SessCreate(m, user, aaa.UserRole(m, user))) + m.Render("redirect", m.Conf(web.SHARE, "meta.domain")) - m.Option(aaa.USERNAME, user) - msg := m.Cmd(USERS, user) - m.Cmd(aaa.USER, mdb.MODIFY, aaa.USERZONE, LARK, aaa.USERNICK, msg.Append("name"), - "mobile", msg.Append("mobile"), "avatar_url", msg.Append("avatar_url"), - "gender", kit.Select("女", "男", msg.Append("gender") == "1"), - "country", msg.Append("country"), "city", msg.Append("city"), - ) - }) + msg = m.Cmd(EMPLOYEE, m.Option(aaa.USERNAME, user)) + m.Cmd(aaa.USER, mdb.MODIFY, aaa.USERZONE, LARK, aaa.USERNICK, msg.Append(kit.MDB_NAME), + aaa.AVATAR, msg.Append("avatar_url"), aaa.GENDER, kit.Select("女", "男", msg.Append(aaa.GENDER) == "1"), + aaa.COUNTRY, msg.Append(aaa.COUNTRY), aaa.CITY, msg.Append(aaa.CITY), + aaa.MOBILE, msg.Append(aaa.MOBILE), + ) return } - m.Richs(APP, nil, "bot", func(key string, value map[string]interface{}) { - m.Render("redirect", kit.MergeURL2(m.Conf(APP, "meta.lark"), "/open-apis/authen/v1/index"), - "app_id", value["id"], "redirect_uri", kit.MergeURL2(m.Conf(web.SHARE, "meta.domain"), "/chat/lark/sso"), - // "app_id", value["id"], "redirect_uri", "https://shylinux.com/chat/lark/sso", + m.Option(mdb.FIELDS, "time,appid,appmm,token,expire") + m.Cmd(mdb.SELECT, m.Prefix(APP), "", mdb.HASH, kit.MDB_NAME, "bot").Table(func(index int, value map[string]string, head []string) { + m.Render("redirect", kit.MergeURL2(m.Conf(APP, kit.Keys(kit.MDB_META, LARK)), "/open-apis/authen/v1/index"), + "app_id", value[APPID], "redirect_uri", kit.MergeURL2(m.Conf(web.SHARE, "meta.domain"), "/chat/lark/sso"), ) }) }}, diff --git a/misc/lark/lark.shy b/misc/lark/lark.shy index 7c6d2acf..979e2fbe 100644 --- a/misc/lark/lark.shy +++ b/misc/lark/lark.shy @@ -1,19 +1,25 @@ title "飞书机器人" refer "官网" ` 官网 https://www.feishu.cn/ -应用管理 https://open.feishu.cn/app -后台管理 https://www.feishu.cn/admin 文档 https://open.feishu.cn/document/uQjL04CN/ucDOz4yN4MjL3gzM 源码 https://github.com/shylinux/icebergs/blob/master/misc/lark/lark.go +后台管理 https://www.feishu.cn/admin +应用管理 https://open.feishu.cn/app ` image qrcode `https://www.feishu.cn/` chapter "应用" -field "ship" web.chat.lark.ship +field "app" web.chat.lark.app +field "company" web.chat.lark.company +# field "employee" web.chat.lark.employee field "group" web.chat.lark.group +# field "send" web.chat.lark.send +# field "duty" web.chat.lark.duty + +chapter "权限" +field user aaa.user +field sess aaa.sess chapter "项目" -section "icebergs" -field "icebergs_统计" web.code.git.trend args `[ icebergs ]` action `{ height 200 speed 20 }` -field "icebergs_源码" web.code.inner args `[ usr/icebergs misc/lark/lark.go 74 ]` - +field "icebergs" web.code.git.trend args `icebergs` +field "icebergs" web.code.inner args `usr/icebergs/ misc/lark/lark.go 1` diff --git a/misc/mp/mp.go b/misc/mp/mp.go index f054a650..236346f4 100644 --- a/misc/mp/mp.go +++ b/misc/mp/mp.go @@ -10,51 +10,60 @@ import ( ) const ( - LOGIN = "login" + LOGIN = "login" + APPID = "appid" + APPMM = "appmm" + ACCESS = "access" + OPENID = "openid" + WEIXIN = "weixin" ) const MP = "mp" var Index = &ice.Context{Name: MP, Help: "小程序", Configs: map[string]*ice.Config{ LOGIN: {Name: LOGIN, Help: "认证", Value: kit.Data( - "auth", "/sns/jscode2session?grant_type=authorization_code", - "weixin", "https://api.weixin.qq.com", - "appid", "", "appmm", "", "token", "", + WEIXIN, "https://api.weixin.qq.com", APPID, "", APPMM, "", )}, }, Commands: map[string]*ice.Command{ ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() - m.Cmd(web.SPIDE, mdb.CREATE, "weixin", m.Conf(LOGIN, "meta.weixin")) + m.Cmd(web.SPIDE, mdb.CREATE, WEIXIN, m.Conf(LOGIN, kit.Keys(kit.MDB_META, WEIXIN))) }}, ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save() }}, + ACCESS: {Name: "access appid auto login", Help: "认证", Action: map[string]*ice.Action{ + LOGIN: {Name: "login appid appmm", Help: "登录", Hand: func(m *ice.Message, arg ...string) { + m.Conf(LOGIN, kit.Keys(kit.MDB_META, APPID), m.Option(APPID)) + m.Conf(LOGIN, kit.Keys(kit.MDB_META, APPMM), m.Option(APPMM)) + }}, + }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Push(APPID, m.Conf(LOGIN, kit.Keys(kit.MDB_META, APPID))) + }}, - "/login/": {Name: "/login/", Help: "登录", Action: map[string]*ice.Action{ - "code": {Name: "code", Help: "登录", Hand: func(m *ice.Message, arg ...string) { - msg := m.Cmd(web.SPIDE, "weixin", web.SPIDE_GET, m.Conf(LOGIN, "meta.auth"), "js_code", m.Option("code"), - "appid", m.Conf(LOGIN, "meta.appid"), "secret", m.Conf(LOGIN, "meta.appmm")) + "/login/": {Name: "/login/", Help: "认证", Action: map[string]*ice.Action{ + aaa.SESS: {Name: "sess code", Help: "会话", Hand: func(m *ice.Message, arg ...string) { + msg := m.Cmd(web.SPIDE, WEIXIN, web.SPIDE_GET, "/sns/jscode2session?grant_type=authorization_code", "js_code", m.Option("code"), + APPID, m.Conf(LOGIN, kit.Keys(kit.MDB_META, APPID)), "secret", m.Conf(LOGIN, kit.Keys(kit.MDB_META, APPMM))) // 用户登录 m.Option(ice.MSG_USERZONE, MP) - m.Echo(aaa.SessCreate(msg, msg.Append("openid"), aaa.UserRole(msg, msg.Append("openid")))) + m.Echo(aaa.SessCreate(msg, msg.Append(OPENID), aaa.UserRole(msg, msg.Append(OPENID)))) }}, - "info": {Name: "info", Help: "信息", Hand: func(m *ice.Message, arg ...string) { + aaa.USER: {Name: "user", Help: "用户", Hand: func(m *ice.Message, arg ...string) { m.Option(aaa.USERNAME, m.Option(ice.MSG_USERNAME)) m.Cmd(aaa.USER, mdb.MODIFY, aaa.USERZONE, MP, aaa.USERNICK, m.Option("nickName"), - "avatar_url", m.Option("avatarUrl"), - "gender", kit.Select("女", "男", m.Option("gender") == "1"), - "country", m.Option("country"), "city", m.Option("city"), - "language", m.Option("language"), - "province", m.Option("province"), + aaa.AVATAR, m.Option("avatarUrl"), aaa.GENDER, kit.Select("女", "男", m.Option(aaa.GENDER) == "1"), + aaa.COUNTRY, m.Option(aaa.COUNTRY), aaa.LANGUAGE, m.Option(aaa.LANGUAGE), + aaa.CITY, m.Option(aaa.CITY), aaa.PROVINCE, m.Option(aaa.PROVINCE), ) }}, - "scan": {Name: "scan", Help: "scan", Hand: func(m *ice.Message, arg ...string) { - if m.Option(web.SHARE) != "" { - if m.Option(chat.RIVER) != "" { - m.Cmdy(chat.AUTH, mdb.INSERT) - } + chat.SCAN: {Name: "scan", Help: "扫码", Hand: func(m *ice.Message, arg ...string) { + if m.Option(web.SHARE) != "" && m.Option(chat.RIVER) != "" { + m.Cmdy(chat.AUTH, mdb.INSERT) + } else { + m.Cmdy(chat.SCAN) } }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { diff --git a/misc/mp/mp.shy b/misc/mp/mp.shy index 6c4c9d05..57118e74 100644 --- a/misc/mp/mp.shy +++ b/misc/mp/mp.shy @@ -6,13 +6,19 @@ refer "" ` 源码 https://github.com/shylinux/icebergs/blob/master/misc/mp/mp.go ` image qrcode `https://weixin.qq.com` +spark chapter "应用" -field "asset" web.mall.asset args `[ ]` -field "task" web.team.task args `[ ]` +field location web.chat.location +field paste web.chat.paste +field scan web.chat.scan +field feel web.chat.feel + +chapter "权限" +field access web.chat.mp.access +field user aaa.user +field sess aaa.sess chapter "项目" -section "icebergs" -field "icebergs_统计" web.code.git.trend args `[ icebergs ]` action `{ height 200 speed 20 }` -field "icebergs_源码" web.code.inner args `[ usr/icebergs misc/mp/mp.go 1 ]` - +field "icebergs" web.code.git.trend args `icebergs` +field "icebergs" web.code.inner args `usr/icebergs/ misc/mp/mp.go 1` diff --git a/misc/wx/wx.go b/misc/wx/wx.go index 74e8aaf0..ed86a6e8 100644 --- a/misc/wx/wx.go +++ b/misc/wx/wx.go @@ -7,55 +7,70 @@ import ( "github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/web" "github.com/shylinux/icebergs/core/chat" + "github.com/shylinux/icebergs/core/wiki" "github.com/shylinux/toolkits" "crypto/sha1" "encoding/hex" "encoding/xml" - "sort" + "fmt" "strings" + "time" ) -func parse(m *ice.Message) { +func _wx_sign(m *ice.Message, nonce, stamp string) string { + b := sha1.Sum([]byte(strings.Join(kit.Sort([]string{ + fmt.Sprintf("noncestr=%s", nonce), + fmt.Sprintf("timestamp=%s", stamp), + fmt.Sprintf("url=%s", m.Option(ice.MSG_USERWEB)), + fmt.Sprintf("jsapi_ticket=%s", m.Cmdx(ACCESS, TICKET)), + }), "&"))) + return hex.EncodeToString(b[:]) +} +func _wx_config(m *ice.Message, nonce string) { + m.Option(APPID, m.Conf(LOGIN, kit.Keys(kit.MDB_META, APPID))) + m.Option("signature", _wx_sign(m, m.Option("noncestr", nonce), m.Option("timestamp", kit.Format(time.Now().Unix())))) +} +func _wx_parse(m *ice.Message) { data := struct { - ToUserName string FromUserName string - CreateTime int + ToUserName string + CreateTime int64 MsgId int64 MsgType string Content string + Event string }{} xml.NewDecoder(m.R.Body).Decode(&data) - m.Option("ToUserName", data.ToUserName) + m.Debug("data: %#v", data) + m.Option("FromUserName", data.FromUserName) + m.Option("ToUserName", data.ToUserName) m.Option("CreateTime", data.CreateTime) + m.Option("MsgId", data.MsgId) m.Option("MsgType", data.MsgType) m.Option("Content", data.Content) + m.Option("Event", data.Event) } - -func reply(m *ice.Message) { - m.Render(m.Conf("login", "meta.template.text")) +func _wx_reply(m *ice.Message, tmpl string) { + m.Render(m.Conf(LOGIN, kit.Keys("meta.template", tmpl))) } -func action(m *ice.Message) { +func _wx_action(m *ice.Message) { m.Option(ice.MSG_OUTPUT, ice.RENDER_RESULT) m.Echo(` - + %s - -`, m.Option("FromUserName"), m.Option("ToUserName"), m.Option("CreateTime")) + +`, m.Option("ToUserName"), m.Option("FromUserName"), m.Option("CreateTime"), "news") count := 0 - m.Table(func(index int, value map[string]string, head []string) { - count++ - }) - m.Echo(`%d -`, count) + m.Table(func(index int, value map[string]string, head []string) { count++ }) + m.Echo(`%d`, count) - m.Echo(` -`) + m.Echo(``) m.Table(func(index int, value map[string]string, head []string) { m.Echo(` <![CDATA[%s]]> @@ -63,99 +78,148 @@ func action(m *ice.Message) { -`, value["name"], value["text"], value["view"], value["link"]) +`, value[wiki.TITLE], value[wiki.SPARK], value[wiki.IMAGE], value[wiki.REFER]) }) + m.Echo(``) + m.Echo(``) - m.Echo(` -`) - m.Echo(` -`) - m.Info("what %v", m.Result()) + m.Debug("echo: %v", m.Result()) } +const ( + LOGIN = "login" + APPID = "appid" + APPMM = "appmm" + TOKEN = "token" + TICKET = "ticket" + ACCESS = "access" + CONFIG = "config" + WEIXIN = "weixin" +) const WX = "wx" -var Index = &ice.Context{Name: "wx", Help: "公众号", - Caches: map[string]*ice.Cache{}, +var Index = &ice.Context{Name: WX, Help: "公众号", Configs: map[string]*ice.Config{ - "login": {Name: "login", Help: "认证", Value: kit.Data( - "auth", "/sns/jscode2session?grant_type=authorization_code", - "weixin", "https://api.weixin.qq.com", - "appid", "", "appmm", "", "token", "", - "template", kit.Dict( - "text", ` - + LOGIN: {Name: LOGIN, Help: "认证", Value: kit.Data( + WEIXIN, "https://api.weixin.qq.com", APPID, "", APPMM, "", TOKEN, "", + "template", kit.Dict("text", ` + {{.Option "CreateTime"}} - - `, - ), + + `), "menu", []interface{}{ - kit.Dict("name", "home", "text", "主页", "view", "https://shylinux.com/static/volcanos/favicon.ico", "link", "https://shylinux.com"), - kit.Dict("name", "sub", "text", "工具", "view", "https://shylinux.com/static/volcanos/favicon.ico", "link", "https://shylinux.com"), + kit.Dict(wiki.TITLE, "主页", wiki.SPARK, "点击进入", wiki.IMAGE, "https://shylinux.com/static/volcanos/favicon.ico", wiki.REFER, "https://shylinux.com"), + kit.Dict(wiki.TITLE, "产品", wiki.SPARK, "工具", wiki.IMAGE, "https://shylinux.com/static/volcanos/favicon.ico", wiki.REFER, "https://shylinux.com?river=product"), + kit.Dict(wiki.TITLE, "研发", wiki.SPARK, "工具", wiki.IMAGE, "https://shylinux.com/static/volcanos/favicon.ico", wiki.REFER, "https://shylinux.com?river=project"), }, )}, }, Commands: map[string]*ice.Command{ ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Load("login") - m.Cmd(web.SPIDE, mdb.CREATE, "weixin", m.Conf("login", "meta.weixin")) + m.Load() + m.Cmd(web.SPIDE, mdb.CREATE, WEIXIN, m.Conf(LOGIN, kit.Keys(kit.MDB_META, WEIXIN))) }}, ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Save("login") + m.Save() + }}, + ACCESS: {Name: "access appid auto ticket token login", Help: "认证", Action: map[string]*ice.Action{ + LOGIN: {Name: "login appid appmm token", Help: "登录", Hand: func(m *ice.Message, arg ...string) { + m.Conf(LOGIN, kit.Keys(kit.MDB_META, APPID), m.Option(APPID)) + m.Conf(LOGIN, kit.Keys(kit.MDB_META, APPMM), m.Option(APPMM)) + m.Conf(LOGIN, kit.Keys(kit.MDB_META, TOKEN), m.Option(TOKEN)) + }}, + TOKEN: {Name: "token", Help: "令牌", Hand: func(m *ice.Message, arg ...string) { + if now := time.Now().Unix(); m.Conf(LOGIN, "meta.access.token") == "" || now > kit.Int64(m.Conf(LOGIN, "meta.access.expire")) { + msg := m.Cmd(web.SPIDE, "weixin", web.SPIDE_GET, "/cgi-bin/token?grant_type=client_credential", + APPID, m.Conf(LOGIN, kit.Keys(kit.MDB_META, APPID)), "secret", m.Conf(LOGIN, kit.Keys(kit.MDB_META, APPMM))) + + m.Conf(LOGIN, "meta.access.token", msg.Append("access_token")) + m.Conf(LOGIN, "meta.access.expire", now+kit.Int64(msg.Append("expires_in"))) + } + m.Echo(m.Conf(LOGIN, "meta.access.token")) + }}, + TICKET: {Name: "ticket", Help: "票据", Hand: func(m *ice.Message, arg ...string) { + if now := time.Now().Unix(); m.Conf(LOGIN, "meta.access.ticket") == "" || now > kit.Int64(m.Conf(LOGIN, "meta.access.expires")) { + msg := m.Cmd(web.SPIDE, "weixin", web.SPIDE_GET, "/cgi-bin/ticket/getticket?type=jsapi", + "access_token", m.Cmdx(ACCESS, TOKEN)) + + m.Conf(LOGIN, "meta.access.ticket", msg.Append(TICKET)) + m.Conf(LOGIN, "meta.access.expires", now+kit.Int64(msg.Append("expires_in"))) + } + m.Echo(m.Conf(LOGIN, "meta.access.ticket")) + }}, + CONFIG: {Name: "config", Help: "配置", Hand: func(m *ice.Message, arg ...string) { + _wx_config(m, "some") + }}, + }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Push(APPID, m.Conf(LOGIN, kit.Keys(kit.MDB_META, APPID))) + }}, + + "menu": {Name: "menu name auto", Help: "菜单", Action: map[string]*ice.Action{ + mdb.CREATE: {Name: "create", Help: "添加", Hand: func(m *ice.Message, arg ...string) { + share := m.Cmdx(web.SHARE, mdb.CREATE, kit.MDB_TYPE, "login") + kit.Fetch(m.Confv(LOGIN, "meta.menu"), func(index int, value map[string]interface{}) { + m.Push("", value, kit.Split("title,spark,image")) + m.Push(wiki.REFER, kit.MergeURL(kit.Format(value[wiki.REFER]), web.SHARE, share)) + }) + }}, + }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + kit.Fetch(m.Confv(LOGIN, "meta.menu"), func(index int, value map[string]interface{}) { + m.Push("", value, kit.Split("title,spark,image,refer")) + }) }}, "/login/": {Name: "/login/", Help: "认证", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - check := []string{m.Conf("login", "meta.token"), m.Option("timestamp"), m.Option("nonce")} - sort.Strings(check) - if b := sha1.Sum([]byte(strings.Join(check, ""))); m.Warn(m.Option("signature") != hex.EncodeToString(b[:]), "signature error") { - // 验证失败 - return + check := kit.Sort([]string{m.Conf(LOGIN, "meta.token"), m.Option("timestamp"), m.Option("nonce")}) + if b := sha1.Sum([]byte(strings.Join(check, ""))); m.Warn(m.Option("signature") != hex.EncodeToString(b[:]), ice.ErrNotAuth) { + return // 验证失败 } - if m.Option("echostr") != "" { // 绑定验证 - m.Render(m.Option("echostr")) - return + if m.Option("echostr") != "" { + m.Render(ice.RENDER_RESULT, m.Option("echostr")) + return // 绑定验证 } // 解析数据 - parse(m) + _wx_parse(m) // 用户登录 m.Option(ice.MSG_USERZONE, WX) - m.Option(ice.MSG_SESSID, aaa.SessCreate(m, m.Append("FromUserName"), aaa.UserRole(m, m.Append("FromUserName")))) + aaa.UserLogin(m, m.Append("FromUserName"), "") switch m.Option("MsgType") { + case "event": + switch m.Option("Event") { + case "subscribe": + // 应用列表 + _wx_action(m.Cmdy("menu", mdb.CREATE)) + case "unsubscribe": + } + case "text": - if cmds := kit.Split(m.Option("Content")); !m.Right(cmds) { - action(m.Cmdy("menu")) + if cmds := kit.Split(m.Option("Content")); m.Warn(!m.Right(cmds), ice.ErrNotAuth) { + _wx_action(m.Cmdy("menu", mdb.CREATE)) + break // 没有权限 } else { switch cmds[0] { case "menu": - action(m.Cmdy("menu")) + // 应用列表 + _wx_action(m.Cmdy("menu", mdb.CREATE)) + default: // 执行命令 - msg := m.Cmd(cmds) - if m.Hand = false; !msg.Hand { - msg = m.Cmd(cli.SYSTEM, cmds) - } - if msg.Result() == "" { - msg.Table() + if m.Cmdy(cmds); len(m.Appendv(ice.MSG_APPEND)) == 0 && len(m.Resultv()) == 0 { + m.Cmdy(cli.SYSTEM, cmds) + } else if len(m.Resultv()) == 0 { + m.Table() } // 返回结果 - reply(m.Push("reply", msg.Result())) + _wx_reply(m, "text") } } } - - }}, - - "menu": {Name: "menu", Help: "菜单", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - kit.Fetch(m.Confv("login", "meta.menu"), func(index int, value map[string]interface{}) { - m.Push("", value, []string{"name", "text", "view"}) - m.Push("link", kit.MergeURL(kit.Format(value["link"]), ice.MSG_SESSID, m.Option(ice.MSG_SESSID))) - }) }}, }, } diff --git a/misc/wx/wx.shy b/misc/wx/wx.shy index d457efd2..738befd7 100644 --- a/misc/wx/wx.shy +++ b/misc/wx/wx.shy @@ -6,24 +6,22 @@ refer "" ` 源码 https://github.com/shylinux/icebergs/blob/master/misc/wx/wx.go ` image qrcode `https://weixin.qq.com` +spark chapter "应用" +field location web.chat.location +field paste web.chat.paste +field scan web.chat.scan +field feel web.chat.feel -field "阅读器" web.code.inner args `[ src/ main.shy ]` -field "编辑器" web.code.vimer args `[ src/ main.go ]` - -field "资料库" web.chat.meet.miss args `[ ]` -field "粘贴板" web.chat.paste.paste args `[ ]` -field "相册集" web.wiki.feel args `[ ]` -field "思维导图" web.wiki.draw.draw args `[ src/ main.svg ]` - -field "任务" web.team.task args `[ ]` -field "任务" web.team.plan args `[ ]` - -field "资产" web.mall.asset args `[ ]` +chapter "权限" +field access web.chat.wx.access +field menu web.chat.wx.menu +field share web.share +field user aaa.user +field sess aaa.sess chapter "项目" -section "icebergs" -field "icebergs 统计" web.code.git.trend args `[ icebergs ]` action `{ height 200 speed 20 }` -field "icebergs 源码" web.code.inner args `[ usr/icebergs misc/wx/wx.go 1 ]` +field "icebergs" web.code.git.trend args `icebergs` +field "icebergs" web.code.inner args `usr/icebergs/ misc/wx/wx.go 1`