Giter Site home page Giter Site logo

openscrm / api-server Goto Github PK

View Code? Open in Web Editor NEW
1.4K 70.0 216.0 116.93 MB

OpenSCRM是一套基于Go和React的高质量企业微信私域流量管理系统 。遵守Apache2.0协议,全网唯一免费商用。企业微信、私域流量、SCRM。

License: Apache License 2.0

Go 99.99% Batchfile 0.01%
scrm wework wecom wechat weixin go golang react antd openscrm apache2

api-server's Introduction

logo

安全,强大,易开发的企业微信SCRM

项目简介

OpenSCRM是一套基于GoReact高质量企业微信私域流量管理系统

快速开始(docker-compose)

我们已经在docker-compose.yaml文件中配置好所有依赖,修改应用配置信息即可启动。

修改配置文件

  • conf/config.example.yaml -> conf/config.yaml
  • 修改DB.Host节点。api-server在容器中跑时,DB.Host需要改成宿主机的IP(host.docker.internal/局域网IP)。api-server在本地跑时,DB.Host填localhost即可。
  • 修改配置文件的App.SuperAdmin节点,此项为企业微信中的管理员ID
  • 修改配置文件的WeWork节点
  • 如果你修改了docker-compose.yaml文件,不要忘记docker-compose down,docker-compose up重建容器让配置生效

启动docker-compose

cd /project-home-dir/
openssl genpkey -algorithm RSA -out conf/private.key
chmod +x bin/api-server bin/msg-arch-server
docker-compose up

访问站点

http://dashboard.dev.openscrm.cn:9000/

搭建开发环境(可选)

安装go语言环境

https://go.dev/doc/install

安装swag

go install github.com/swaggo/swag/cmd/swag@latest

启动程序

go run main.go

访问站点

http://dashboard.dev.openscrm.cn:9000/

子项目

会话存档服务 管理面板 企业微信H5侧边栏

项目特点

  • 安全性高:企业微信控制了企业所有员工和客户的敏感数据,如电话号码,职位,客户标签,联系方式等,如果发生泄露, 对企业的打击将是致命的。我们团队有丰富的Web安全经验保证项目安全性。

  • 高性能,高稳定性:得益于Go出色的工程能力,简单有效的并发控制能力,OpenSCRM具备比肩头部Saas厂商的高性能和高稳定

  • 代码可读性优先:我们深刻认同Google对于代码管理的看法,项目开发完成只是项目的开始,更多的工作在于维护和迭代, 唯有易读的代码才能保证后期迭代的高质量,高效率,这也是Go语言的设计目标。我们有非常完善的代码注释,所有代码力求清晰易读。

  • 易开发:作为开源项目,我们为了让更多的人可以受益于此项目,我们做了大量工作力求项目简单易上手。 我们只做必要抽象(MVC),避免引入新慨念。我们坚持尽量少的中间件依赖,仅依赖Mysql和Redis, 比如延迟队列我们基于Redis实现, 没有引入Kafka;比如全文检索基于Mysql8全文检索实现,没有引入ES。

Python,PHP,NodeJS开发者可以放心使用本项目,本项目做了大量工作力求简单,非常容易上手。

项目截图

技术栈

后端技术栈

前端技术栈

目录结构

├─app
│  ├─callback 企业微信事件回调处理
│  │  ├─customer_event
│  │  ├─department_event
│  │  ├─group_chat_event
│  │  ├─msg_arch_event
│  │  ├─staff_event
│  │  └─tag_event
│  ├─constants 常量定义
│  ├─consumers 队列消费
│  ├─controller 控制器
│  ├─entities 消息实体,主要定义参数,请求,响应结构体
│  ├─middleware gin请求中间件
│  ├─models 数据库模型
│  ├─requests 请求定义
│  ├─responses 响应定义
│  ├─services 服务
│  ├─tasks 定时任务
├─bin 二进制文件
├─common 共同库
│  ├─app 基于Gin封装的常用请求响应处理函数
│  ├─delay_queue 基于Redis延迟队列
│  ├─ecode 错误码
│  ├─id_generator uuid生成
│  ├─log 日志
│  ├─redis redis操作库
│  ├─session session会话
│  ├─storage 存储
│  ├─util 常用工具函数
│  └─validator 请求验证
├─conf 配置文件
├─docker
│  ├─data
│  │  ├─dashboard
│  │  │  └─dist 管理后台构建的前端静态文件
│  │  ├─mysql
│  │  │  ├─conf mysql容器配置文件
│  │  │  └─db mysql容器数据文件
│  │  ├─nginx
│  │  │  ├─conf nginx容器配置文件
│  │  │  │  └─conf.d 
│  │  │  └─logs
│  │  ├─redis 
│  │  │  └─db redis容器数据文件
│  │  └─sidebar
│  │      └─dist 侧边栏构建的前端静态文件
│  └─lib 企业微信提供的会话存档动态链库
├─docs 文档
├─pkg 三方库
│  └─easywework 企业微信Api调用库
│      ├─errcodes 企业微信Api错误码
├─routers Gin路由
├─scripts 脚本
└─test 测试代码

安装教程

https://github.com/openscrm/api-server/wiki/%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B

Api调试

docs目录包含postman导出文件,可方便调试api

版权声明

OpenSCRM遵循Apache2.0协议,可免费商用

api-server's People

Contributors

gargantuax avatar putyy avatar sersoong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

api-server's Issues

会话记录为空的时候会显示NULL转int64错误

staff.go单元,这段代码增加IFNULL处理

    err = DB.Model(&GroupChat{}).Where("ext_corp_id = ?", extCorpID).
	Pluck("IFNULL(sum(today_join_member_num),0) as today_groups_increase", &cs.TodayGroupsIncrease).Error
if err != nil {
	err = errors.WithStack(err)
	return
}

err = DB.Model(&GroupChat{}).Where("ext_corp_id = ?", extCorpID).
	Pluck("IFNULL(sum(today_quit_member_num),0) as today_groups_decrease", &cs.TodayGroupsDecrease).Error
if err != nil {
	err = errors.WithStack(err)
	return
}

dashboard和sidebar同时使用如何部署呢?

目前遇到一个问题, 回调域名设置dashboard的域名, 后台能正常使用, 不过配置了sidebar的域名后, 在聊天侧边栏打开会提示redirect_url不是可信域名, 但是应用的回调域名只能设置一个, 如果新建一个侧边栏应用的话, 项目里也不支持多应用, 请问一下 这个是怎么配置的呢

获取员工外部客户ID方法只返回3个ID怎么解决?

// BatchFetchCustomers
// Description: 并发获取员工的外部客户ID
// Detail: 不用将员工与客户id数组对应
func (o CustomerService) BatchFetchCustomers(extStaff []*workwx.UserInfo) (totalExtCustomerIDs []string, err error)

哪位大佬知道怎么解决的啊。

model类型修改建议

model目录下的mass_msg_staff.go文件的struct,建议将MassMsgId属性的gorm:"index;type:bigint"改为gorm:"index;type:varchar(64)",由于QueryExtStaffids方法中第一个where语句的mysql的in函数需要字段类型与in中类型匹配,前端MassMsgId是string类型,而mysql中是bigint类型,会导致搜索不匹配,后续不判空会报index [0] out of range 错误。
同理,file_size字段也是bigint,调用parse-url接口时前端填写的fileSize是空字符串”“,与数据库字段不匹配,素材库页面解析网页功能不可用,要么在前端改类型。
客户详情age字段前端没有限定num类型和长度,数据库是tinyint(3) ,修改基本信息时字段不匹配也会报错。

招募项目维护者

我没有时间维护这个项目,且没有使用场景。
有兴趣维护这个项目的同学可以一起来维护,成为contributor。

这个项目如何在k8s上跑起来?

将这个项目部署在 k8s 上,分配 3 个副本,如何保证只有 1 个副本在刷新 access_token ?
看了下源代码,是直接开一个协程在刷新 access_token,但是项目部署在 3 个副本时,每个副本都会启动刷新 access_token 的协程,那就意味着每个副本都在刷新 access_token?

func (t *Token) tokenRefresher(ctx context.Context) {
    // refresh per 30m
    const refreshTimeWindow = (2*60 - 30) * time.Minute
    const minRefreshDuration = 5 * time.Second

    var nextRefreshDuration time.Duration = 0
    for {
        select {
        case <-time.After(nextRefreshDuration):
            retryer := backoff.WithContext(backoff.NewExponentialBackOff(), ctx)
            if err := backoff.Retry(t.syncToken, retryer); err != nil {
                log.Println("retry getting access token failed", "err", err)
                _ = err
            }

            nextRefreshDuration = t.LastRefresh.Add(t.ExpiresIn - refreshTimeWindow).Sub(t.LastRefresh)
            if nextRefreshDuration < minRefreshDuration {
                nextRefreshDuration = minRefreshDuration
            }
        case <-ctx.Done():
            return
        }
    }
}

为啥二维码出不来

微信图片_20240116184857
微信截图_20240116184735

为啥这个二维码出不来,login接口总是报502错误呢?还是需要配置白名单?

是我配置信息少填了的原因吗? 而且现在客户联系Secret 好像无法直接获取了 get all departments from wx failed,纳闷...

get all depar, Msg: "api forbidden for contact assistant

image
2024-03-05T22:30:12.053+0800 ERROR services/department.go:37 get all depar, Msg: "api forbidden for contact assistant, hint: [1709649011424270725404086], from work.weixin.qq.com/devtool/query?e=48009" }
openscrm/app/services.Department.Sync
D:/Porduct/GO/api-server/app/services/department.go:37
openscrm/app/services.Syncs
D:/Porduct/GO/api-server/app/services/init.go:19
main.init.0
D:/Porduct/GO/api-server/main.go:59
runtime.doInit
C:/Users/gaode/sdk/go1.19.10/src/runtime/proc.go:6330
runtime.main
C:/Users/gaode/sdk/go1.19.10/src/runtime/proc.go:233
panic: ClientError { Code: 48009, Msg: "api forbidden for contact assistant, hint: [1.127, more info at https://open.work.weixin.qq.com/devtool/query?e=48009" }

goroutine 1 [running]:
openscrm/app/services.Syncs()
D:/Porduct/GO/api-server/app/services/init.go:21 +0x30e
main.init.0()
D:/Porduct/GO/api-server/main.go:59 +0x485

核心问题是两个:
get all depar, Msg: "api forbidden for contact assistant, hint: [1709649011424270725404086], from work.weixin.qq.com/devtool/query?e=48009" }
panic: ClientError { Code: 48009, Msg: "api forbidden for contact assistant, hint: [1.127, more info at https://open.work.weixin.qq.com/devtool/query?e=48009" }
请问怎么解决?

会话存档没法显示,我看后台有报错 Unknown column 'ext_staff_id' in 'where clause'


api_1      |
api_1      | 2022/01/06 11:00:00 /root/scrm/scrm/app/models/mass_msg_staff.go:121
api_1      | [4.555ms] [rows:0] SELECT mass_msg.ext_msg_id as ext_msg_id, mass_msg_staff.ext_staff_id as ext_staff_id, mass_msg_staff.id as id FROM `mass_msg` join mass_msg_staff on  mass_msg_staff.mass_msg_id = mass_msg.id WHERE (mass_msg.ext_corp_id = 'ww17efc9574291cc91') AND is_sent = 0
api_1      |
api_1      | 2022/01/06 11:00:00 /root/scrm/scrm/app/models/staff.go:351 Error 1054: Unknown column 'ext_staff_id' in 'where clause'
api_1      | [0.745ms] [rows:0] UPDATE `staff` SET `enable_msg_arch`='1',`updated_at`='2022-01-06 11:00:00.563' WHERE ext_corp_id = 'ww17efc9574291cc91' and  ext_staff_id in ('HuBoYu_zero')
api_1      | 2022-01-06T11:00:00.563+0800       ERROR   tasks/message_arch.go:28        UpdateStaffMsgArchStatus failed {"err": "Error 1054: Unknown column 'ext_staff_id' in 'where clause'", "errVerbose": "Error 1054: Unknown column 'ext_staff_id' in 'where clause'\nopenscrm/app/services.StaffService.doUpdateMsgArchStatus\n\t/root/scrm/scrm/app/services/staff.go:696\nopenscrm/app/services.StaffService.UpdateStaffMsgArchStatus\n\t/root/scrm/scrm/app/services/staff.go:679\nopenscrm/app/tasks.Staff.UpdateMsgArchStatus\n\t/root/scrm/scrm/app/tasks/message_arch.go:26\ngithub.com/gogf/gf/os/gcron.(*Entry).check\n\t/root/.asdf/installs/golang/1.17.5/packages/pkg/mod/github.com/gogf/[email protected]/os/gcron/gcron_entry.go:146\ngithub.com/gogf/gf/os/gtimer.(*Entry).Run.func1\n\t/root/.asdf/installs/golang/1.17.5/packages/pkg/mod/github.com/gogf/[email protected]/os/gtimer/gtimer_entry.go:59\nruntime.goexit\n\t/root/.asdf/installs/golang/1.17.5/go/src/runtime/asm_amd64.s:1581\nopenscrm/app/services.StaffService.UpdateStaffMsgArchStatus\n\t/root/scrm/scrm/app/services/staff.go:681\nopenscrm/app/tasks.Staff.UpdateMsgArchStatus\n\t/root/scrm/scrm/app/tasks/message_arch.go:26\ngithub.com/gogf/gf/os/gcron.(*Entry).check\n\t/root/.asdf/installs/golang/1.17.5/packages/pkg/mod/github.com/gogf/[email protected]/os/gcron/gcron_entry.go:146\ngithub.com/gogf/gf/os/gtimer.(*Entry).Run.func1\n\t/root/.asdf/installs/golang/1.17.5/packages/pkg/mod/github.com/gogf/[email protected]/os/gtimer/gtimer_entry.go:59\nruntime.goexit\n\t/root/.asdf/installs/golang/1.17.5/go/src/runtime/asm_amd64.s:1581"}
api_1      | openscrm/app/tasks.Staff.UpdateMsgArchStatus

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.