wechat icon indicating copy to clipboard operation
wechat copied to clipboard

[咨询] 公众号接口如何接入 serverless

Open xiabee opened this issue 2 years ago • 0 comments

问题描述

在示例代码中,公众号接口通过 server := officialAccount.GetServer(req, rw) 实现,传统服务器需要构建一个监听函数:

func handleRequest(rw http.ResponseWriter, req *http.Request)

现在想把该接口转移到 AWS Lambda 中,Lambda 服务没有状态信息,不能构建监听,需要通过 APIGateway 传入 events.APIGatewayProxyRequest,并给 APIGateway 返回 events.APIGatewayProxyResponse。

func handleRequest(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error)

在文档中没有找到 server 的请求 / 返回数据包相关描述......手动将构建接口将 events.APIGatewayProxyRequest 转换为 *http.Request,将 http.ResponseWriter 转换为 events.APIGatewayProxyResponse,所有的中间校验过程的代码都没有修改,搭建服务后一直返回 “请求校验失败”。

所以想请教一下 server 实例中校验 / 消息收发过程中,数据包如何构建、传输的,如何获取到相关请求、响应包,看看我在转换过程中有没有遗漏🙏

转换代码

func ConvertAPIGatewayRequestToHTTPRequest(r events.APIGatewayProxyRequest) (*http.Request, error) {
	httpReq, err := http.NewRequest(r.HTTPMethod, r.Path, strings.NewReader(r.Body))
	if err != nil {
		return nil, err
	}
	for key, value := range r.Headers {
		httpReq.Header.Add(key, value)
	}
	return httpReq, nil
}

// 创建一个结构体,实现http.ResponseWriter接口
type responseWriter struct {
	http.ResponseWriter
	response *events.APIGatewayProxyResponse
}

// 实现Write方法
func (rw *responseWriter) Write(b []byte) (int, error) {
	rw.response.Body = string(b)
	return len(b), nil
}

// WriteHeader 实现WriteHeader方法
func (rw *responseWriter) WriteHeader(statusCode int) {
	rw.response.StatusCode = statusCode
}

func handleRequest(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	...
	officialAccount := wc.GetOfficialAccount(cfg)

	resp := events.APIGatewayProxyResponse{}
	// 创建一个 responseWriter 结构体
	rw := &responseWriter{ResponseWriter: nil, response: &resp}

	req, err := ConvertAPIGatewayRequestToHTTPRequest(request)

	// 传入request和responseWriter
	server := officialAccount.GetServer(req, rw)
	...
	err = server.Serve()
	resp.Body = string(server.ResponseRawXMLMsg)

	// 发送回复的消息
	err = server.Send()
	resp.Body = string(server.ResponseRawXMLMsg)

	return resp, nil
}

xiabee avatar Mar 12 '23 06:03 xiabee