1
0
mirror of https://shylinux.com/x/icebergs synced 2025-05-01 03:09:21 +08:00
This commit is contained in:
shylinux 2021-07-24 11:22:20 +08:00
parent a3734b31b0
commit f6d6fabb1c
20 changed files with 692 additions and 461 deletions

View File

@ -12,7 +12,6 @@ import (
)
const (
REDIRECT = "redirect"
REFRESH = "refresh"
STATUS = "status"
COOKIE = "cookie"
@ -24,7 +23,7 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) {
}
switch arg := kit.Simple(args...); cmd {
case REDIRECT: // url [arg...]
case ice.RENDER_REDIRECT: // url [arg...]
http.Redirect(msg.W, msg.R, kit.MergeURL(arg[0], arg[1:]), 307)
case REFRESH: // [delay [text]]

View File

@ -181,10 +181,10 @@ func init() {
switch msg.Append(kit.MDB_TYPE) {
case LOGIN, RIVER:
m.Render(REDIRECT, "/", list)
m.RenderRedirect("/", list)
case STORM:
m.Render(REDIRECT, "/page/share.html", SHARE, m.Option(SHARE))
m.RenderRedirect("/page/share.html", SHARE, m.Option(SHARE))
}
}},

View File

@ -126,8 +126,9 @@ const ( // RENDER
RENDER_VIDEOS = "_videos"
RENDER_QRCODE = "_qrcode"
RENDER_SCRIPT = "_script"
RENDER_DOWNLOAD = "_download"
RENDER_TEMPLATE = "_template"
RENDER_DOWNLOAD = "_download"
RENDER_REDIRECT = "_redirect"
)
const ( // PROCESS
PROCESS_REFRESH = "_refresh"

View File

@ -257,9 +257,7 @@ func (m *Message) Render(cmd string, args ...interface{}) *Message {
if len(args) == 1 {
args = append(args, m)
}
m.Debug("what %v", args)
if res, err := kit.Render(args[0].(string), args[1]); m.Assert(err) {
m.Debug("what")
m.Echo(string(res))
}
}
@ -274,6 +272,12 @@ func (m *Message) RenderTemplate(args ...interface{}) *Message {
func (m *Message) RenderDownload(args ...interface{}) *Message {
return m.Render(RENDER_DOWNLOAD, args...)
}
func (m *Message) RenderRedirect(args ...interface{}) *Message {
return m.Render(RENDER_REDIRECT, args...)
}
func (m *Message) RenderIndex(serve, repos string) *Message {
return m.RenderDownload(path.Join(m.Conf(serve, kit.Keym(repos, kit.SSH_PATH)), m.Conf(serve, kit.Keym(repos, kit.SSH_INDEX))))
}
type Sort struct {
Fields string

55
misc/lark/app.go Normal file
View File

@ -0,0 +1,55 @@
package lark
import (
"time"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/web"
kit "github.com/shylinux/toolkits"
)
const (
LOGIN = "login"
APPID = "appid"
APPMM = "appmm"
TOKEN = "token"
EXPIRE = "expire"
)
const APP = "app"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
APP: {Name: APP, Help: "服务配置", Value: kit.Data(
kit.MDB_SHORT, APPID, kit.MDB_FIELD, "time,appid,appmm,duty,token,expire",
LARK, "https://open.feishu.cn/",
)},
},
Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(web.SPIDE, mdb.CREATE, LARK, m.Conf(APP, kit.Keym(LARK)))
}},
APP: {Name: "app appid auto token login", Help: "应用", Action: map[string]*ice.Action{
LOGIN: {Name: "login appid appmm duty", Help: "登录", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.INSERT, m.Prefix(APP), "", mdb.HASH, arg)
}},
TOKEN: {Name: "token appid", Help: "令牌", Hand: func(m *ice.Message, arg ...string) {
msg := m.Cmd(APP, m.Option(APPID))
if now := time.Now().Unix(); msg.Append(TOKEN) == "" || now > kit.Int64(msg.Append(EXPIRE)) {
sub := m.Cmd(web.SPIDE, LARK, web.SPIDE_POST, "/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, m.OptionSimple(APPID),
TOKEN, sub.Append("tenant_access_token"), EXPIRE, now+kit.Int64(sub.Append(EXPIRE)))
msg.Append(TOKEN, sub.Append("tenant_access_token"))
}
m.Echo(msg.Append(TOKEN))
}},
}, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
m.Fields(len(arg) == 0, m.Conf(APP, kit.META_FIELD))
m.Cmdy(mdb.SELECT, m.Prefix(APP), "", mdb.HASH, APPID, arg)
}},
},
})
}

61
misc/lark/company.go Normal file
View File

@ -0,0 +1,61 @@
package lark
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
kit "github.com/shylinux/toolkits"
)
func _company_list(m *ice.Message, appid string) {
_, data := _lark_get(m, appid, "/open-apis/contact/v1/scope/get/")
kit.Fetch(kit.Value(data, "data.authed_departments"), func(index int, ship_id string) {
_, data := _lark_get(m, appid, "/open-apis/contact/v1/department/detail/batch_get", "department_ids", ship_id)
kit.Fetch(kit.Value(data, "data.department_infos"), func(index int, value map[string]interface{}) {
m.Push(SHIP_ID, ship_id)
m.Push(kit.MDB_NAME, value[kit.MDB_NAME])
m.Push(kit.MDB_COUNT, value["member_count"])
m.Push(CHAT_ID, value[CHAT_ID])
})
})
m.Sort(kit.MDB_NAME)
}
func _company_members(m *ice.Message, appid string, ship_id string) {
_, data := _lark_get(m, appid, "/open-apis/contact/v1/department/user/list",
"department_id", 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(EMPLOYEE, appid, value[OPEN_ID])
m.PushImages(aaa.AVATAR, 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))
})
m.Sort(kit.MDB_NAME)
}
const COMPANY = "company"
func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
COMPANY: {Name: "company appid ship_id open_id text auto", Help: "组织", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
switch len(arg) {
case 0: // 应用列表
m.Cmdy(APP)
case 1: // 组织列表
_company_list(m, arg[0])
case 2: // 员工列表
_company_members(m, arg[0], arg[1])
case 3: // 员工详情
m.Cmdy(EMPLOYEE, arg[0], arg[2])
default: // 员工通知
m.Cmdy(SEND, arg[0], OPEN_ID, arg[2], arg[3:])
}
}},
}})
}

21
misc/lark/duty.go Normal file
View File

@ -0,0 +1,21 @@
package lark
import (
ice "github.com/shylinux/icebergs"
)
const DUTY = "duty"
func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
DUTY: {Name: "duty appid [title] text auto", Help: "通告", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
if len(arg) < 2 {
m.Cmdy(APP)
return
}
duty := m.Cmd(APP, arg[0]).Append(DUTY)
m.Cmdy(SEND, arg[0], duty, arg[1:])
}},
}})
}

46
misc/lark/employee.go Normal file
View File

@ -0,0 +1,46 @@
package lark
import (
"strings"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits"
)
func _employee_info(m *ice.Message, appid string, arg ...string) {
for _, id := range arg {
_, data := _lark_get(m, appid, "/open-apis/contact/v1/user/batch_get", "open_ids", id)
kit.Fetch(kit.Value(data, "data.user_infos"), func(index int, value map[string]interface{}) {
m.Push(mdb.DETAIL, value)
})
}
}
func _employee_openid(m *ice.Message, appid string, arg ...string) {
us := []string{}
for i := 0; i < len(arg); i++ {
us = append(us, kit.Select("mobiles", "emails", strings.Contains(arg[i], "@")), arg[i])
}
_lark_get(m, appid, "/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")))
}
}
const EMPLOYEE = "employee"
func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
EMPLOYEE: {Name: "employee appid open_id|mobile|email auto", Help: "员工", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
if len(arg) < 2 {
return
}
if strings.HasPrefix(arg[1], "ou_") {
_employee_info(m, arg[0], arg[1:]...)
} else {
_employee_openid(m, arg[0], arg[1:]...)
}
}},
}})
}

38
misc/lark/event.go Normal file
View File

@ -0,0 +1,38 @@
package lark
import (
ice "github.com/shylinux/icebergs"
kit "github.com/shylinux/toolkits"
)
const (
P2P_CHAT_CREATE = "p2p_chat_create"
MESSAGE_READ = "message_read"
CHAT_DISBAND = "chat_disband"
ADD_BOT = "add_bot"
MSG_TYPE = "msg_type"
)
const EVENT = "event"
func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
EVENT: {Name: "event", Help: "事件", Action: map[string]*ice.Action{
P2P_CHAT_CREATE: {Name: "", Help: "", Hand: func(m *ice.Message, arg ...string) {
if m.Options(OPEN_CHAT_ID) {
m.Cmdy(SEND, m.Option(APP_ID), m.Option(OPEN_CHAT_ID), m.Conf(APP, kit.Keym(kit.MDB_TEMPLATE, m.Option(kit.MDB_TYPE))))
}
}},
MESSAGE_READ: {Name: "", Help: "", Hand: func(m *ice.Message, arg ...string) {
}},
CHAT_DISBAND: {Name: "", Help: "", Hand: func(m *ice.Message, arg ...string) {
}},
ADD_BOT: {Name: "", Help: "", Hand: func(m *ice.Message, arg ...string) {
if m.Options(OPEN_CHAT_ID) {
m.Cmdy(SEND, m.Option(APP_ID), m.Option(OPEN_CHAT_ID), m.Conf(APP, kit.Keym(kit.MDB_TEMPLATE, m.Option(kit.MDB_TYPE))))
}
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmdy(MSG, m.Option(MSG_TYPE))
}},
}})
}

78
misc/lark/form.go Normal file
View File

@ -0,0 +1,78 @@
package lark
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/web"
kit "github.com/shylinux/toolkits"
)
const FORM = "form"
func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
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 = kit.Dict(CONTENT, kit.Dict())
switch arg[0] {
case CHAT_ID, OPEN_ID, USER_ID, aaa.EMAIL:
form[arg[0]], arg = arg[1], arg[2:]
default:
form[CHAT_ID], arg = arg[0], arg[1:]
}
elements := []interface{}{}
elements = append(elements, kit.Dict(
"tag", "div", "text", kit.Dict(
"tag", "plain_text", CONTENT, kit.Select(" ", arg[1]),
),
))
actions := []interface{}{}
for i := 2; i < len(arg); i++ {
button := kit.Dict(
"tag", "button", "type", "default", "text", kit.Dict(
"tag", "plain_text", CONTENT, kit.Select(" ", arg[i]),
),
)
content := arg[i]
switch arg[i+1] {
case "confirm":
button[arg[i+1]], i = kit.Dict(
"title", kit.Dict("tag", "lark_md", CONTENT, arg[i+2]),
"text", kit.Dict("tag", "lark_md", CONTENT, arg[i+3]),
), i+3
case "value":
button[arg[i+1]], i = kit.Dict(arg[i+2], arg[i+3]), i+3
case "url":
button[arg[i+1]], i = arg[i+2], i+2
default:
button["value"], i = kit.Dict(
ice.MSG_RIVER, m.Option(ice.MSG_RIVER),
ice.MSG_STORM, m.Option(ice.MSG_STORM),
arg[i+1], arg[i+2],
), i+2
}
kit.Value(button, "value.content", content)
kit.Value(button, "value.open_chat_id", m.Option(OPEN_CHAT_ID))
kit.Value(button, "value.description", arg[1])
kit.Value(button, "value.title", arg[0])
actions = append(actions, button)
}
elements = append(elements, kit.Dict("tag", "action", "actions", actions))
kit.Value(form, "msg_type", "interactive")
kit.Value(form, "card", kit.Dict(
"config", kit.Dict("wide_screen_mode", true),
"header", kit.Dict(
"title", kit.Dict("tag", "lark_md", CONTENT, arg[0]),
),
"elements", elements,
))
msg := _lark_post(m, m.Option(APP_ID), "/open-apis/message/v4/send/", web.SPIDE_DATA, kit.Formats(form))
m.Debug("%v", msg.Optionv(web.SPIDE_RES))
}},
}})
}

56
misc/lark/group.go Normal file
View File

@ -0,0 +1,56 @@
package lark
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
kit "github.com/shylinux/toolkits"
)
func _group_list(m *ice.Message, appid string) {
_, data := _lark_get(m, appid, "/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.PushImages(aaa.AVATAR, 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)
}
func _group_members(m *ice.Message, appid string, chat_id string) {
_, data := _lark_get(m, appid, "/open-apis/chat/v4/info", "chat_id", chat_id)
kit.Fetch(kit.Value(data, "data.members"), func(index int, value map[string]interface{}) {
msg := m.Cmd(EMPLOYEE, appid, value[OPEN_ID])
m.PushImages(aaa.AVATAR, 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))
})
m.Sort(kit.MDB_NAME)
}
const GROUP = "group"
func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
GROUP: {Name: "group appid chat_id open_id text auto", Help: "群组", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
switch len(arg) {
case 0: // 应用列表
m.Cmdy(APP)
case 1: // 群组列表
_group_list(m, arg[0])
case 2: // 组员列表
_group_members(m, arg[0], arg[1])
case 3: // 组员详情
m.Cmdy(EMPLOYEE, arg[0], arg[2])
default: // 组员通知
m.Cmdy(SEND, arg[0], OPEN_ID, arg[2], arg[3:])
}
}},
}})
}

40
misc/lark/home.go Normal file
View File

@ -0,0 +1,40 @@
package lark
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/web"
"github.com/shylinux/icebergs/core/chat"
kit "github.com/shylinux/toolkits"
)
const HOME = "home"
func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
HOME: {Name: "home river storm title content", 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 += "的" + kit.Select("应用列表", arg, 2)
text, link, list := kit.Select("", arg, 3), kit.MergeURL2(m.Conf(web.SHARE, kit.Keym(kit.MDB_DOMAIN)), "/chat/lark/sso"), []string{}
if len(arg) == 0 {
m.Cmd("web.chat./river").Table(func(index int, val map[string]string, head []string) {
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])
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(FORM, CHAT_ID, m.Option(OPEN_CHAT_ID), name, text, "打开网页", "url", link, list)
}},
}})
}

View File

@ -2,468 +2,20 @@ package lark
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/web"
"github.com/shylinux/icebergs/core/chat"
"github.com/shylinux/icebergs/core/wiki"
kit "github.com/shylinux/toolkits"
"encoding/json"
"math/rand"
"net/http"
"strings"
"time"
)
func _lark_get(m *ice.Message, bot string, arg ...interface{}) (*ice.Message, interface{}) {
m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, bot), web.ContentType, web.ContentJSON)
msg := m.Cmd(web.SPIDE, LARK, http.MethodGet, arg)
return msg, msg.Optionv(web.SPIDE_RES)
}
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 _lark_parse(m *ice.Message) {
data := m.Optionv(ice.MSG_USERDATA)
if data == nil {
json.NewDecoder(m.R.Body).Decode(&data)
m.Optionv(ice.MSG_USERDATA, data)
switch d := data.(type) {
case map[string]interface{}:
for k, v := range d {
switch d := v.(type) {
case map[string]interface{}:
for k, v := range d {
m.Add(ice.MSG_OPTION, k, kit.Format(v))
}
default:
for _, v := range kit.Simple(v) {
m.Add(ice.MSG_OPTION, kit.Keys("msg", k), kit.Format(v))
}
}
}
}
}
m.Debug("msg: %v", kit.Format(data))
}
const (
P2P_CHAT_CREATE = "p2p_chat_create"
ADD_BOT = "add_bot"
)
const (
SHIP_ID = "ship_id"
OPEN_ID = "open_id"
CHAT_ID = "chat_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"
COMPANY = "company"
EMPLOYEE = "employee"
GROUP = "group"
SEND = "send"
DUTY = "duty"
HOME = "home"
FORM = "form"
TALK = "talk"
RAND = "rand"
)
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, "", kit.MDB_TEMPLATE, kit.Dict(
ADD_BOT, "我来也~", P2P_CHAT_CREATE, "让我们做好朋友吧~",
),
)},
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, kit.Keym(LARK)))
}},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save()
}},
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", 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(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)
}},
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) {
_, data := _lark_get(m, "bot", "/open-apis/contact/v1/department/detail/batch_get", "department_ids", m.Option(SHIP_ID))
kit.Fetch(kit.Value(data, "data.department_infos"), func(index int, value map[string]interface{}) {
m.Push("", value)
})
}},
"list": {Name: "list ship_id", Hand: func(m *ice.Message, arg ...string) {
_, data := _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(EMPLOYEE, value[OPEN_ID])
m.PushImages(aaa.AVATAR, 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 := _lark_get(m, "bot", "/open-apis/contact/v1/scope/get/")
kit.Fetch(kit.Value(data, "data.authed_departments"), func(index int, value string) {
m.Push(SHIP_ID, value)
msg := m.Cmd(COMPANY, "info", value)
m.Push(kit.MDB_NAME, msg.Append(kit.MDB_NAME))
m.Push(kit.MDB_COUNT, msg.Append("member_count"))
m.Push(CHAT_ID, msg.Append(CHAT_ID))
})
m.Sort(kit.MDB_NAME)
} else if len(arg) == 1 { // 员工列表
m.Cmdy(COMPANY, "list", arg[0])
} else if len(arg) == 2 { // 员工详情
m.Cmdy(EMPLOYEE, arg[1])
} else { // 员工通知
m.Cmdy(SEND, OPEN_ID, arg[1], arg[2:])
}
}},
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_") {
_, data := _lark_get(m, "bot", "/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(mdb.DETAIL, value)
})
return
}
us := []string{}
for i := 0; i < len(arg); i++ {
us = append(us, kit.Select("mobiles", "emails", strings.Contains(arg[i], "@")), arg[i])
}
_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 auto", Help: "群组", Action: map[string]*ice.Action{
"list": {Name: "list chat_id", Hand: func(m *ice.Message, arg ...string) {
_, data := _lark_get(m, "bot", "/open-apis/chat/v4/info", "chat_id", m.Option(CHAT_ID))
kit.Fetch(kit.Value(data, "data.members"), func(index int, value map[string]interface{}) {
msg := m.Cmd(EMPLOYEE, value[OPEN_ID])
m.PushImages(aaa.AVATAR, 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 := _lark_get(m, "bot", "/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.PushImages(aaa.AVATAR, 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)
} else if len(arg) == 1 { // 组员列表
m.Cmdy(GROUP, "list", arg[0])
} else if len(arg) == 2 { // 组员详情
m.Cmdy(EMPLOYEE, arg[1])
} else { // 组员通知
m.Cmdy(SEND, CHAT_ID, arg[0], arg[2:])
}
}},
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:]
default:
form[CHAT_ID], arg = arg[0], arg[1:]
}
switch len(arg) {
case 0:
case 1:
kit.Value(form, "msg_type", "text")
kit.Value(form, "content.text", arg[0])
if strings.TrimSpace(arg[0]) == "" {
return
}
default:
if len(arg) == 2 && strings.TrimSpace(arg[1]) == "" {
return
}
content := []interface{}{}
line := []interface{}{}
for _, v := range arg[1:] {
if v == "\n" {
content, line = append(content, line), []interface{}{}
continue
}
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},
})
}
m.Copy(_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, kit.Keym(DUTY)), arg)
}},
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 += "的" + kit.Select("应用列表", arg, 2)
text := ""
link, list := m.Conf(web.SHARE, "meta.domain"), []string{}
if len(arg) == 0 {
m.Cmd("web.chat./river").Table(func(index int, val map[string]string, head []string) {
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])
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(FORM, CHAT_ID, m.Option(OPEN_CHAT_ID), name, text, "打开网页", "url", link, list)
}},
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":
form[arg[0]], arg = arg[1], arg[2:]
default:
form[CHAT_ID], arg = arg[0], arg[1:]
}
elements := []interface{}{}
elements = append(elements, map[string]interface{}{
"tag": "div", "text": map[string]interface{}{
"tag": "plain_text", "content": arg[1],
},
})
actions := []interface{}{}
for i := 2; i < len(arg); i++ {
button := map[string]interface{}{
"type": "default", "tag": "button", "text": map[string]interface{}{
"tag": "plain_text", "content": arg[i],
},
}
content := arg[i]
switch arg[i+1] {
case "confirm":
button[arg[i+1]], i = map[string]interface{}{
"title": map[string]interface{}{"tag": "lark_md", "content": arg[i+2]},
"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
case "url":
button[arg[i+1]], i = arg[i+2], i+2
default:
button["value"], i = map[string]interface{}{
arg[i+1]: arg[i+2],
ice.MSG_RIVER: m.Option(ice.MSG_RIVER),
ice.MSG_STORM: m.Option(ice.MSG_STORM),
}, i+2
}
kit.Value(button, "value.content", content)
kit.Value(button, "value.open_chat_id", m.Option(OPEN_CHAT_ID))
kit.Value(button, "value.description", arg[1])
kit.Value(button, "value.title", arg[0])
actions = append(actions, button)
}
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},
"header": map[string]interface{}{
"title": map[string]interface{}{"tag": "lark_md", "content": arg[0]},
},
"elements": elements,
})
_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); len(msg.Appendv(ice.MSG_APPEND)) > 0 || len(msg.Resultv()) > 0 {
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))])
}},
web.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, "")
kit.Fetch(kit.Value(data, "action.value"), func(key string, value string) { m.Option(key, value) })
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 _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") {
case "message_read":
case "chat_disband":
case P2P_CHAT_CREATE, ADD_BOT:
// 创建对话
if m.Options(OPEN_CHAT_ID) {
m.Cmdy(SEND, m.Option(OPEN_CHAT_ID), m.Conf(APP, kit.Keym(kit.MDB_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"),
// ))
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("type"), kit.Formats(data))
}
}
}
default:
m.Cmd(DUTY, m.Option("msg.type"), kit.Formats(data))
}
}},
"/sso": {Name: "/sso", Help: "网页", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
if m.Options("code") {
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)
user := msg.Append("data.open_id")
web.RenderCookie(m, aaa.SessCreate(m, user))
m.Render("redirect", m.Conf(web.SHARE, "meta.domain"))
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.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.Keym(LARK)), "/open-apis/authen/v1/index"),
"app_id", value[APPID], "redirect_uri", kit.MergeURL2(m.Conf(web.SHARE, kit.Keym(kit.MDB_DOMAIN)), "/chat/lark/sso"),
)
})
}},
},
}

View File

@ -1,5 +1,6 @@
title "飞书机器人"
refer "官网" `
官网 https://shylinux.com/chat/lark/sso
官网 https://www.feishu.cn/
文档 https://open.feishu.cn/document/uQjL04CN/ucDOz4yN4MjL3gzM
源码 https://github.com/shylinux/icebergs/blob/master/misc/lark/lark.go
@ -12,6 +13,7 @@ chapter "应用"
field "app" web.chat.lark.app
field "group" web.chat.lark.group
field "company" web.chat.lark.company
field "duty" web.chat.lark.duty
chapter "权限"
field sess aaa.sess

106
misc/lark/msg.go Normal file
View File

@ -0,0 +1,106 @@
package lark
import (
"encoding/json"
"net/http"
"strings"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/web"
"github.com/shylinux/icebergs/core/wiki"
kit "github.com/shylinux/toolkits"
)
func _lark_get(m *ice.Message, appid string, arg ...interface{}) (*ice.Message, interface{}) {
m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, appid), web.ContentType, web.ContentJSON)
msg := m.Cmd(web.SPIDE, LARK, http.MethodGet, arg)
return msg, msg.Optionv(web.SPIDE_RES)
}
func _lark_post(m *ice.Message, appid string, arg ...interface{}) *ice.Message {
m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, appid), web.ContentType, web.ContentJSON)
return m.Cmd(web.SPIDE, LARK, arg)
}
func _lark_parse(m *ice.Message) {
data := m.Optionv(ice.MSG_USERDATA)
if data == nil {
json.NewDecoder(m.R.Body).Decode(&data)
m.Optionv(ice.MSG_USERDATA, data)
switch d := data.(type) {
case map[string]interface{}:
for k, v := range d {
switch d := v.(type) {
case map[string]interface{}:
for k, v := range d {
m.Add(ice.MSG_OPTION, k, kit.Format(v))
}
default:
for _, v := range kit.Simple(v) {
m.Add(ice.MSG_OPTION, kit.Keys(MSG, k), kit.Format(v))
}
}
}
}
}
m.Debug("msg: %v", kit.Format(data))
}
const (
APP_ID = "app_id"
SHIP_ID = "ship_id"
OPEN_ID = "open_id"
CHAT_ID = "chat_id"
USER_ID = "user_id"
OPEN_CHAT_ID = "open_chat_id"
USER_OPEN_ID = "user_open_id"
)
const MSG = "msg"
func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
web.WEB_LOGIN: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(ice.MSG_USERZONE, LARK)
}},
"/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.Cmd(MSG, "card")
return
}
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": // 事件回调
m.Cmd(EVENT, m.Option(kit.MDB_TYPE))
default: // 未知消息
m.Cmd(DUTY, m.Option("msg.type"), kit.Formats(data))
}
}},
MSG: {Name: "msg", Help: "聊天消息", Action: map[string]*ice.Action{
"location": {Name: "", Help: "", Hand: func(m *ice.Message, arg ...string) {
}},
"image": {Name: "", Help: "", Hand: func(m *ice.Message, arg ...string) {
}},
"card": {Name: "", Help: "", Hand: func(m *ice.Message, arg ...string) {
data := m.Optionv(ice.MSG_USERDATA)
kit.Fetch(kit.Value(data, "action.value"), func(key string, value string) { m.Option(key, value) })
m.Cmdy(TALK, kit.Parse(nil, "", kit.Split(m.Option(kit.SSH_CMD))...))
m.Cmd(SEND, m.Option(APP_ID), CHAT_ID, m.Option(OPEN_CHAT_ID),
m.Option(wiki.TITLE)+" "+m.Option(kit.SSH_CMD), m.Result())
}},
}, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
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(APP_ID), m.Option(OPEN_CHAT_ID), m.Result())
}
} else {
m.Cmd(DUTY, m.Option(APP_ID), m.Option(kit.MDB_TYPE), kit.Formats(m.Optionv(ice.MSG_USERDATA)))
}
}},
}})
}

25
misc/lark/rand.go Normal file
View File

@ -0,0 +1,25 @@
package lark
import (
"math/rand"
"strings"
ice "github.com/shylinux/icebergs"
kit "github.com/shylinux/toolkits"
)
const RAND = "rand"
func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
RAND: {Name: "rand", Help: "随机", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
msg := m.Cmd(GROUP, m.Option(APP_ID), EMPLOYEE, m.Option(OPEN_CHAT_ID))
list := msg.Appendv(kit.MDB_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))])
}},
}})
}

68
misc/lark/send.go Normal file
View File

@ -0,0 +1,68 @@
package lark
import (
"strings"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/web"
kit "github.com/shylinux/toolkits"
)
func _send_text(m *ice.Message, form map[string]interface{}, arg ...string) bool {
switch len(arg) {
case 0:
case 1:
kit.Value(form, "msg_type", "text")
kit.Value(form, "content.text", arg[0])
if strings.TrimSpace(arg[0]) == "" {
return false
}
default:
if len(arg) == 2 && strings.TrimSpace(arg[1]) == "" {
return false
}
content := []interface{}{}
line := []interface{}{}
for _, v := range arg[1:] {
if v == "\n" {
content, line = append(content, line), []interface{}{}
continue
}
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},
})
}
return true
}
const (
CONTENT = "content"
)
const SEND = "send"
func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
SEND: {Name: "send appid [chat_id|open_id|user_id|email] target [title] text", Help: "消息", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
form := kit.Dict(CONTENT, kit.Dict())
appid, arg := arg[0], arg[1:]
switch arg[0] {
case CHAT_ID, OPEN_ID, USER_ID, aaa.EMAIL:
form[arg[0]], arg = arg[1], arg[2:]
default:
form[CHAT_ID], arg = arg[0], arg[1:]
}
if _send_text(m, form, arg...) {
msg := _lark_post(m, appid, "/open-apis/message/v4/send/", web.SPIDE_DATA, kit.Format(form))
m.Push("time", m.Time())
m.Push("message_id", msg.Append("data.message_id"))
}
}},
}})
}

49
misc/lark/sso.go Normal file
View File

@ -0,0 +1,49 @@
package lark
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/web"
kit "github.com/shylinux/toolkits"
)
const SSO = "sso"
func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
"/sso": {Name: "/sso", Help: "网页", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
if m.Option(ice.MSG_USERNAME) != "" { // 默认主页
m.RenderIndex(web.SERVE, ice.VOLCANOS)
return
}
home := kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/chat/lark/sso")
if m.Option(kit.MDB_CODE) != "" { // 登录成功
msg := m.Cmd(web.SPIDE, LARK, "/open-apis/authen/v1/access_token", "grant_type", "authorization_code",
kit.MDB_CODE, m.Option(kit.MDB_CODE), "app_access_token", m.Cmdx(APP, TOKEN, m.Cmd(APP).Append(APPID)))
// 创建会话
m.Option(aaa.USERNAME, msg.Append("data.open_id"))
web.RenderCookie(m, aaa.SessCreate(m, m.Option(aaa.USERNAME)))
m.RenderRedirect(kit.Select(home, m.Option(kit.MDB_BACK)))
// 更新用户
msg = m.Cmd(EMPLOYEE, m.Option(aaa.USERNAME))
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
}
if back := m.R.Header.Get("Referer"); back != "" {
home = kit.MergeURL(home, kit.MDB_BACK, back)
}
// 登录页面
m.RenderRedirect(kit.MergeURL2(m.Conf(APP, kit.Keym(LARK)), "/open-apis/authen/v1/index"),
"redirect_uri", home, APP_ID, m.Cmd(APP).Append(APPID))
}},
}})
}

29
misc/lark/talk.go Normal file
View File

@ -0,0 +1,29 @@
package lark
import (
"strings"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
kit "github.com/shylinux/toolkits"
)
const TALK = "talk"
func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
TALK: {Name: "talk text", Help: "聊天", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
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(APP_ID), m.Option(OPEN_CHAT_ID), m.Option("text_without_at_bot"))
m.Cmd(HOME)
return // 没有权限
}
}
// 执行命令
m.Cmdy(cmds)
}},
}})
}

View File

@ -718,8 +718,9 @@ func (m *Message) cmd(arg ...interface{}) *Message {
return m
}
ok := false
run := func(msg *Message, ctx *Context, cmd *Command, key string, arg ...string) {
if cbs != nil {
if ok = true; cbs != nil {
msg.Option(list[0]+".cb", cbs)
}
for k, v := range opts {
@ -744,8 +745,8 @@ func (m *Message) cmd(arg ...interface{}) *Message {
}
// 系统命令
if m.Warn(!m.Hand, ErrNotFound, list) {
return m.Set(MSG_RESULT).Cmd("cli.system", list)
if m.Warn(!ok, ErrNotFound, list) {
return m.Set(MSG_RESULT).Cmdy("cli.system", list)
}
return m
}