wework

package module
v0.0.0-...-55dfa3a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 1, 2023 License: Apache-2.0 Imports: 11 Imported by: 0

README

Go WeWork

Go Reference Go Report Card

This library provides unofficial Go clients for WeWork API. We support:

  • internal corp API
  • open corp API (SaaS)
  • encrypt/decrypt wework event messages

Installation

go get github.com/jasonwwl/go-wework

Currently, go-wework requires Go version 1.18 or greater.

Usage

InternalCorpAPI example usage
package main

func main() {
    cfg, err := wework.NewConfigBuilder().InternalCorp(wework.InternalCorp{
        CorpID:  "your corpid",
        Secret:  "your app secret",
        AgentID: "your app agentid"
    }).Build()

    if err != nil {
        fmt.Printf("InternalCorp config build error: %v\n", err)
        return
    }

    client := wework.NewClient(cfg)

    resp, err := client.GetExternalContactList("zhangsan")
    if err != nil {
        fmt.Printf("GetExternalContactList error: %v\n", err)
        return
    }

    fmt.Printf("GetExternalContactList result: %v\n", resp)
}
OpenCorpAPI example usage
package main

func main() {
    cfg, err := wework.NewConfigBuilder().OpenCorp(wework.OpenCorp{
        ProviderCorpID:   "WEWORK_PROVIDER_CORP_ID",
        ProviderSecret:   "WEWORK_PROVIDER_SECRET",
        SuiteID:          "WEWORK_SUITE_ID",
        SuiteSecret:      "WEWORK_SUITE_SECRET",
        SuiteToken:       "WEWORK_SUITE_TOKEN",
        SuiteEncodingAES: "WEWORK_SUITE_AES_KEY",
        AuthCorpID:       "WEWORK_AUTH_CORP_ID",
    }).Build()

    if err != nil {
        fmt.Printf("OpenCorp config build error: %v\n", err)
        return
    }

    client := wework.NewClient(cfg)

    resp, err := client.GetAuthInfo()
    if err != nil {
        fmt.Printf("GetAuthInfo error: %v\n", err)
        return
    }

    fmt.Printf("GetAuthInfo result: %v\n", resp)
}
Use custom storage to store token
package main

type CustomRedisStore struct {
}

func (crs *CustomRedisStore) GetToken(c *wework.Client, ctx context.Context, tokenType wework.TokenType) (string, error) {
    // redis get token
    return "token...", nil
}

func (crs *CustomRedisStore) SetToken(c *wework.Client, ctx context.Context, tokenType wework.TokenType, token string, expiresIn int64) (string, error) {
    // redis set token
    return nil
}

func main() {
    cfg, err := wework.NewConfigBuilder().OpenCorp(wework.OpenCorp{
        ProviderCorpID:   "WEWORK_PROVIDER_CORP_ID",
        ProviderSecret:   "WEWORK_PROVIDER_SECRET",
        SuiteID:          "WEWORK_SUITE_ID",
        SuiteSecret:      "WEWORK_SUITE_SECRET",
        SuiteToken:       "WEWORK_SUITE_TOKEN",
        SuiteEncodingAES: "WEWORK_SUITE_AES_KEY",
        AuthCorpID:       "WEWORK_AUTH_CORP_ID",
    }).TokenStore(&CustomRedisStore{}).Build()

    if err != nil {
        fmt.Printf("OpenCorp config build error: %v\n", err)
        return
    }

    client := wework.NewClient(cfg)

    resp, err := client.GetAuthInfo()
    if err != nil {
        fmt.Printf("GetAuthInfo error: %v\n", err)
        return
    }

    fmt.Printf("GetAuthInfo result: %v\n", resp)
}

Documentation

Index

Constants

View Source
const (
	WeWorkAPIURL = "https://qyapi.weixin.qq.com/cgi-bin"
	Timeout      = time.Second * 30
)

Variables

View Source
var (
	AccessToken         = &TokenDescriptor{TokenType: "AccessToken", ParamValue: "access_token"}
	ProviderToken       = &TokenDescriptor{TokenType: "ProviderAccessToken", ParamValue: "provider_access_token"}
	SuiteToken          = &TokenDescriptor{TokenType: "SuiteAccessToken", ParamValue: "suite_access_token"}
	AuthCorpAccessToken = &TokenDescriptor{TokenType: "AuthCorpAccessToken", ParamValue: "access_token"} // 注意这里的区别
	SuiteTicket         = &TokenDescriptor{TokenType: "SuiteTicket", ParamValue: "suite_ticket"}
	PermanentCode       = &TokenDescriptor{TokenType: "PermanentCode", ParamValue: "permanent_code"}
)
View Source
var ErrInvalidInternalCorp = errors.New("invalid internal corp config")
View Source
var ErrInvalidOpenCorp = errors.New("invalid open corp config")
View Source
var ErrNilStoreToken = errors.New("store token is nil or expired")

Functions

func BuildKey

func BuildKey(client *Client, tokenType TokenType) (string, error)

func NewConfigBuilder

func NewConfigBuilder() *configBuilder

func WithFile

func WithFile(data *FileUpload) func(*requestOptions)

func WithJSONData

func WithJSONData(data any) func(*requestOptions)

func WithQuery

func WithQuery(query netURL.Values) func(*requestOptions)

func WithToken

func WithToken(token *TokenDescriptor) func(*requestOptions)

Types

type APIBaseResponse

type APIBaseResponse struct {
	ErrCode int    `json:"errcode"`
	ErrMsg  string `json:"errmsg"`
}

type AuthCorpAccessTokenResponse

type AuthCorpAccessTokenResponse struct {
	APIBaseResponse
	AccessToken string `json:"access_token"`
	ExpiresIn   int64  `json:"expires_in"`
}

type Client

type Client struct {
	// contains filtered or unexported fields
}

func NewClient

func NewClient(config *ClientConfig) *Client

func (*Client) FetchAccessTokenIfNeeded

func (c *Client) FetchAccessTokenIfNeeded(ctx context.Context) (tk string, err error)

从缓存中获取AccessToken(内部应用),如果缓存中没有,则从企微API获取

func (*Client) FetchAuthCorpAccessTokenIfNeeded

func (c *Client) FetchAuthCorpAccessTokenIfNeeded(ctx context.Context) (tk string, err error)

从缓存中获取AccessToken(第三方授权应用),如果缓存中没有,则从企微API获取

func (*Client) FetchProviderTokenIfNeeded

func (c *Client) FetchProviderTokenIfNeeded(ctx context.Context) (tk string, err error)

获取服务商凭证,如果缓存中没有,则从企微API获取

func (*Client) FetchSuiteTokenIfNeeded

func (c *Client) FetchSuiteTokenIfNeeded(ctx context.Context) (tk string, err error)

获取第三方应用凭证,如果缓存中没有,则从企微API获取

func (*Client) GetAccessToken

func (c *Client) GetAccessToken(ctx context.Context, corpid string, corpSecret string) (response GetTokenResponse, err error)

内部应用获取access_token

IMPORTANT: 此方法不会缓存获取到的凭证,需要自行缓存!建议使用GetToken或FetchAccessTokenIfNeeded方法进行获取

获取access_token是调用企业微信API接口的第一步,相当于创建了一个登录凭证,其它的业务API接口,都需要依赖于access_token来鉴权调用者身份。 因此开发者,在使用业务接口前,要明确access_token的颁发来源,使用正确的access_token。

文档地址: https://developer.work.weixin.qq.com/document/path/91039

func (*Client) GetAuthCorpAccessToken

func (c *Client) GetAuthCorpAccessToken(ctx context.Context, authCorpid, permanentCode string) (response AuthCorpAccessTokenResponse, err error)

第三方服务商获取授权企业的access_token

IMPORTANT: 此方法不会缓存获取到的凭证,需要自行缓存!建议使用GetToken或FetchAuthCorpAccessTokenIfNeeded方法进行获取

第三方服务商在取得企业的永久授权码后,通过此接口可以获取到企业的access_token。 获取后可通过通讯录、应用、消息等企业接口来运营这些应用。

文档地址: https://developer.work.weixin.qq.com/document/path/90605

  • 此处获得的企业access_token与企业获取access_token拿到的token,本质上是一样的,只不过获取方式不同。获取之后,就跟普通企业一样使用token调用API接口

func (*Client) GetConfig

func (c *Client) GetConfig() *ClientConfig

func (*Client) GetInternalCorpConfig

func (c *Client) GetInternalCorpConfig() *InternalCorp

func (*Client) GetOpenCorpConfig

func (c *Client) GetOpenCorpConfig() *OpenCorp

func (*Client) GetProviderToken

func (c *Client) GetProviderToken(ctx context.Context, corpid string, providerSecret string) (response GetProviderTokenResponse, err error)

获取服务商凭证

IMPORTANT: 此方法不会缓存获取到的凭证,需要自行缓存!建议使用GetToken或FetchProviderTokenIfNeeded方法进行获取

该API用于获取服务商凭证,该凭证用于服务商调用企业微信开放接口。

文档地址: https://developer.work.weixin.qq.com/document/path/91200

func (*Client) GetStore

func (c *Client) GetStore() Store

func (*Client) GetSuiteToken

func (c *Client) GetSuiteToken(ctx context.Context, suiteId, suiteSecret, suiteTicket string) (response SuiteTokenResponse, err error)

获取第三方应用凭证

IMPORTANT: 此方法不会缓存获取到的凭证,需要自行缓存!建议使用GetToken或FetchSuiteTokenIfNeeded方法进行获取

该API用于获取第三方应用凭证(suite_access_token)。

文档地址: https://developer.work.weixin.qq.com/document/path/90600

  • 由于第三方服务商可能托管了大量的企业,其安全问题造成的影响会更加严重,故API中除了合法来源IP校验之外,还额外增加了suite_ticket作为安全凭证。
  • 获取suite_access_token时,需要suite_ticket参数。suite_ticket由企业微信后台定时推送给“指令回调URL”,每十分钟更新一次,见推送suite_ticket
  • suite_ticket实际有效期为30分钟,可以容错连续两次获取suite_ticket失败的情况,但是请永远使用最新接收到的suite_ticket。通过本接口获取的suite_access_token有效期为2小时,开发者需要进行缓存,不可频繁获取。

func (*Client) GetToken

func (c *Client) GetToken(ctx context.Context, token *TokenDescriptor) (tk string, err error)

GetToken 获取指定类型的 Token

func (*Client) InitStoreData

func (c *Client) InitStoreData(data []StoreData, ctx context.Context) error

func (*Client) NewRequest

func (c *Client) NewRequest(ctx context.Context, method string, url string, setters ...requestOption) (req *http.Request, err error)

func (*Client) Request

func (c *Client) Request(ctx context.Context, method string, url string, v interface{}, setters ...requestOption) error

func (*Client) SendRequest

func (c *Client) SendRequest(req *http.Request, v interface{}) error

func (*Client) SetAccessToken

func (c *Client) SetAccessToken(ctx context.Context, accessToken string, expiresIn time.Duration) (err error)

func (*Client) SetAuthCorpAccessToken

func (c *Client) SetAuthCorpAccessToken(ctx context.Context, authCorpAccessToken string, expiresIn time.Duration) (err error)

func (*Client) SetAuthCorpID

func (c *Client) SetAuthCorpID(authCorpID string)

func (*Client) SetPermanentCode

func (c *Client) SetPermanentCode(ctx context.Context, permanentCode string) (err error)

func (*Client) SetProviderAccessToken

func (c *Client) SetProviderAccessToken(ctx context.Context, providerAccessToken string, expiresIn time.Duration) (err error)

func (*Client) SetSuiteTicket

func (c *Client) SetSuiteTicket(ctx context.Context, suiteTicket string) (err error)

func (*Client) SetSuiteToken

func (c *Client) SetSuiteToken(ctx context.Context, suiteAccessToken string, expiresIn time.Duration) (err error)

type ClientConfig

type ClientConfig struct {
	Options      *Options
	InternalCorp *InternalCorp
	OpenCorp     *OpenCorp
	HTTPClient   *http.Client
	DebugMode    bool
}

type FileUpload

type FileUpload struct {
	FileName  string
	Reader    io.Reader
	FieldName string
}

type GetProviderTokenResponse

type GetProviderTokenResponse struct {
	APIBaseResponse
	ProviderAccessToken string `json:"provider_access_token"`
	ExpiresIn           int64  `json:"expires_in"`
}

type GetTokenResponse

type GetTokenResponse struct {
	APIBaseResponse
	AccessToken string `json:"access_token"`
	ExpiresIn   int64  `json:"expires_in"`
}

type H

type H map[string]any

H is a shortcut for map[string]any

type InternalCorp

type InternalCorp struct {
	CorpID  string
	Secret  string
	AgentID string
}

type MemoryStore

type MemoryStore struct {
	// contains filtered or unexported fields
}

func NewMemoryStore

func NewMemoryStore() *MemoryStore

func (*MemoryStore) GetToken

func (m *MemoryStore) GetToken(client *Client, ctx context.Context, tokenType TokenType) (string, error)

func (*MemoryStore) SetToken

func (m *MemoryStore) SetToken(client *Client, ctx context.Context, tokenType TokenType, token string, expiresIn time.Duration) error

type OpenCorp

type OpenCorp struct {
	ProviderCorpID   string
	ProviderSecret   string
	SuiteID          string
	SuiteSecret      string
	SuiteToken       string
	SuiteEncodingAES string
	AuthCorpID       string
}

type Options

type Options struct {
	Timeout    time.Duration
	TokenStore Store
	BaseURL    string
}

type Store

type Store interface {
	GetToken(client *Client, ctx context.Context, tokenType TokenType) (string, error)
	SetToken(client *Client, ctx context.Context, tokenType TokenType, token string, expiresIn time.Duration) error
}

func InitMemoryStore

func InitMemoryStore() Store

type StoreData

type StoreData struct {
	TokenDescriptor *TokenDescriptor
	Token           string
}

type SuiteTokenResponse

type SuiteTokenResponse struct {
	APIBaseResponse
	SuiteAccessToken string `json:"suite_access_token"`
	ExpiresIn        int64  `json:"expires_in"`
}

type TokenDescriptor

type TokenDescriptor struct {
	TokenType  TokenType
	ParamValue string
}

type TokenInfo

type TokenInfo struct {
	// contains filtered or unexported fields
}

func MakeTokenInfo

func MakeTokenInfo(token string, expiresIn time.Duration) *TokenInfo

type TokenType

type TokenType string

Directories

Path Synopsis
api
basic
Package basic 提供了企业微信API中"基础"相关的接口。
Package basic 提供了企业微信API中"基础"相关的接口。
oa
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL