forked from x/icebergs
opt chat
This commit is contained in:
parent
750ca5e19c
commit
5cc142e009
@ -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"
|
||||
)
|
||||
|
@ -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 // 复用会话
|
||||
}
|
||||
m.W = nil
|
||||
}
|
||||
|
||||
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 // 新建会话
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -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"))
|
||||
|
@ -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)
|
||||
}
|
||||
})
|
||||
|
@ -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))
|
||||
}},
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
})
|
||||
|
||||
})
|
||||
|
@ -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) {
|
||||
|
@ -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))
|
||||
}},
|
||||
|
4
meta.go
4
meta.go
@ -94,10 +94,14 @@ func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Messa
|
||||
}
|
||||
fallthrough
|
||||
default:
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 追加数据
|
||||
switch v := kit.Format(v); key {
|
||||
|
1
misc.go
1
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
|
||||
}
|
||||
|
@ -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()
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -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"))
|
||||
|
@ -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 (
|
||||
LOGIN = "login"
|
||||
APPID = "appid"
|
||||
APPMM = "appmm"
|
||||
TOKEN = "token"
|
||||
EXPIRE = "expire"
|
||||
)
|
||||
const (
|
||||
APP = "app"
|
||||
SHIP = "ship"
|
||||
USERS = "users"
|
||||
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)
|
||||
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.Echo("%s", value["token"])
|
||||
})
|
||||
m.Echo(msg.Append(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
|
||||
}
|
||||
m.Push("detail", value)
|
||||
})
|
||||
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"))
|
||||
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("description", msg.Append("description"))
|
||||
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
|
||||
}
|
||||
if len(arg) == 1 {
|
||||
// 用户列表
|
||||
m.Cmdy(m.Prefix(SHIP), USERS, arg[0])
|
||||
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:])
|
||||
}
|
||||
}},
|
||||
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"))
|
||||
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("description", msg.Append("description"))
|
||||
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{}) {
|
||||
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.Push("avatar", m.Cmdx(mdb.RENDER, web.RENDER.IMG, value["avatar"]))
|
||||
m.PushRender(aaa.AVATAR, "img", kit.Format(value[aaa.AVATAR]), "72")
|
||||
m.Push(kit.MDB_NAME, value[kit.MDB_NAME])
|
||||
m.Push("description", value["description"])
|
||||
m.Push(kit.MDB_TEXT, value["description"])
|
||||
m.Push(OPEN_ID, value["owner_open_id"])
|
||||
})
|
||||
})
|
||||
m.Sort(kit.MDB_NAME)
|
||||
return
|
||||
}
|
||||
if len(arg) == 1 {
|
||||
// 用户列表
|
||||
m.Cmdy(m.Prefix(GROUP), USERS, arg[0])
|
||||
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:])
|
||||
}
|
||||
}},
|
||||
|
||||
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"))
|
||||
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"),
|
||||
)
|
||||
})
|
||||
}},
|
||||
|
@ -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`
|
||||
|
@ -11,50 +11,59 @@ import (
|
||||
|
||||
const (
|
||||
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) != "" {
|
||||
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) {
|
||||
|
@ -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`
|
||||
|
204
misc/wx/wx.go
204
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(`<xml>
|
||||
<ToUserName><![CDATA[%s]]></ToUserName>
|
||||
<FromUserName><![CDATA[%s]]></FromUserName>
|
||||
<ToUserName><![CDATA[%s]]></ToUserName>
|
||||
<CreateTime>%s</CreateTime>
|
||||
<MsgType><![CDATA[news]]></MsgType>
|
||||
`, m.Option("FromUserName"), m.Option("ToUserName"), m.Option("CreateTime"))
|
||||
<MsgType><![CDATA[%s]]></MsgType>
|
||||
`, 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(`<ArticleCount>%d</ArticleCount>
|
||||
`, count)
|
||||
m.Table(func(index int, value map[string]string, head []string) { count++ })
|
||||
m.Echo(`<ArticleCount>%d</ArticleCount>`, count)
|
||||
|
||||
m.Echo(`<Articles>
|
||||
`)
|
||||
m.Echo(`<Articles>`)
|
||||
m.Table(func(index int, value map[string]string, head []string) {
|
||||
m.Echo(`<item>
|
||||
<Title><![CDATA[%s]]></Title>
|
||||
@ -63,99 +78,148 @@ func action(m *ice.Message) {
|
||||
<PicUrl><![CDATA[%s]]></PicUrl>
|
||||
<Url><![CDATA[%s]]></Url>
|
||||
</item>
|
||||
`, value["name"], value["text"], value["view"], value["link"])
|
||||
`, value[wiki.TITLE], value[wiki.SPARK], value[wiki.IMAGE], value[wiki.REFER])
|
||||
})
|
||||
m.Echo(`</Articles>`)
|
||||
m.Echo(`</xml>`)
|
||||
|
||||
m.Echo(`</Articles>
|
||||
`)
|
||||
m.Echo(`</xml>
|
||||
`)
|
||||
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", `<xml>
|
||||
<ToUserName><![CDATA[{{.Option "FromUserName"}}]]></ToUserName>
|
||||
LOGIN: {Name: LOGIN, Help: "认证", Value: kit.Data(
|
||||
WEIXIN, "https://api.weixin.qq.com", APPID, "", APPMM, "", TOKEN, "",
|
||||
"template", kit.Dict("text", `<xml>
|
||||
<FromUserName><![CDATA[{{.Option "ToUserName"}}]]></FromUserName>
|
||||
<ToUserName><![CDATA[{{.Option "FromUserName"}}]]></ToUserName>
|
||||
<CreateTime>{{.Option "CreateTime"}}</CreateTime>
|
||||
<MsgType><![CDATA[text]]></MsgType>
|
||||
<Content><![CDATA[{{.Append "reply"}}]]></Content>
|
||||
</xml>`,
|
||||
),
|
||||
<Content><![CDATA[{{.Result}}]]></Content>
|
||||
</xml>`),
|
||||
"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)))
|
||||
})
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
@ -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`
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user