Golang中如何调用Google Apps Script
Golang中如何调用Google Apps Script 我有以下Google Apps脚本:
function doGet(request) {
var events = CalendarApp.getEvents(
new Date(Number(request.parameters.start) * 1000),
new Date(Number(request.parameters.end) * 1000));
var result = {
available: events.length == 0
};
return ContentService.createTextOutput(JSON.stringify(result))
.setMimeType(ContentService.MimeType.JSON);
}
当我在浏览器中打开以下URL时:
https://script.google.com/macros/s/AKfycbwNGgAO-p4TrbKLdGj_blwm5nI9nD5i_0EtlnS42-PuVsrxrM3Ovvwfdw/exec?end=1325439000&start=1325437200
我得到了正确的响应:
{"available":true}
我尝试通过Go语言进行调用,代码如下:
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
)
func main() {
site := "https://script.google.com/macros/s/AKfycbwNGgAO-p4TrbKLdGj_blwm5nI9nD5i_0EtlnS42-PuVsrxrM3Ovvwfdw/exec"
base, err := url.Parse(site)
if err != nil {
return
}
// Path params
// base.Path += "this will get automatically encoded"
// Query params
params := url.Values{}
params.Add("start", "1325437200")
params.Add("end", "1325439000")
base.RawQuery = params.Encode()
fmt.Printf("Encoded URL is %q\n", base.String())
// make a sample HTTP GET request
res, err := http.Get(base.String())
// check for response error
if err != nil {
log.Fatal(err)
}
// read all response body
data, _ := ioutil.ReadAll(res.Body)
// close response body
res.Body.Close()
// print `data` as a string
fmt.Printf("%s\n", data)
}
但我没有得到相同的输出,而是得到了一个非常长的文本,看起来像是提取了包含多种语言的Google登录界面(无论输出是什么,都不是预期的结果)。我期望的输出与我在浏览器中得到的相同,即:
{"available":true}
更多关于Golang中如何调用Google Apps Script的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我发现错误出在Web应用的发布设置上。通过将Execute as和Who has access的设置分别从Me和Anyone with Google account更改为Me和Anyone,问题得以解决。
此解决方案归功于stackoverflow上的Tanaike。
更多关于Golang中如何调用Google Apps Script的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中调用Google Apps Script时,需要处理重定向和Cookies。Google Apps Script的Web应用在未授权访问时会重定向到登录页面。以下是修正后的代码:
package main
import (
"fmt"
"io"
"log"
"net/http"
"net/http/cookiejar"
"net/url"
"time"
)
func main() {
// 创建带Cookie的HTTP客户端
jar, err := cookiejar.New(nil)
if err != nil {
log.Fatal(err)
}
client := &http.Client{
Jar: jar,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
// 允许重定向
return nil
},
Timeout: 30 * time.Second,
}
// 构建URL
baseURL := "https://script.google.com/macros/s/AKfycbwNGgAO-p4TrbKLdGj_blwm5nI9nD5i_0EtlnS42-PuVsrxrM3Ovvwfdw/exec"
params := url.Values{}
params.Add("start", "1325437200")
params.Add("end", "1325439000")
fullURL := baseURL + "?" + params.Encode()
fmt.Printf("请求URL: %s\n", fullURL)
// 创建请求
req, err := http.NewRequest("GET", fullURL, nil)
if err != nil {
log.Fatal(err)
}
// 设置User-Agent头,模拟浏览器
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
// 发送请求
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// 读取响应
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("状态码: %d\n", resp.StatusCode)
fmt.Printf("响应体: %s\n", body)
}
如果Web应用需要授权,需要先获取OAuth2令牌。以下是使用OAuth2的示例:
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"os"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
)
func main() {
ctx := context.Background()
// 从JSON文件加载凭据
b, err := os.ReadFile("credentials.json")
if err != nil {
log.Fatal(err)
}
config, err := google.ConfigFromJSON(b, "https://www.googleapis.com/auth/calendar.readonly")
if err != nil {
log.Fatal(err)
}
// 获取令牌(需要先完成OAuth2流程)
tok, err := getTokenFromFile("token.json")
if err != nil {
log.Fatal(err)
}
client := config.Client(ctx, tok)
// 调用Google Apps Script
baseURL := "https://script.google.com/macros/s/AKfycbwNGgAO-p4TrbKLdGj_blwm5nI9nD5i_0EtlnS42-PuVsrxrM3Ovvwfdw/exec"
params := url.Values{}
params.Add("start", "1325437200")
params.Add("end", "1325439000")
fullURL := baseURL + "?" + params.Encode()
resp, err := client.Get(fullURL)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
var result map[string]bool
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
log.Fatal(err)
}
fmt.Printf("响应: %v\n", result)
}
func getTokenFromFile(file string) (*oauth2.Token, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
defer f.Close()
tok := &oauth2.Token{}
err = json.NewDecoder(f).Decode(tok)
return tok, err
}
对于不需要认证的公开Web应用,确保在Google Apps Script部署设置中设置为"Anyone, even anonymous"。如果仍然遇到问题,可以尝试使用http.Client的Transport来禁用重定向:
client := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse // 停止重定向
},
}
resp, err := client.Get(fullURL)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// 检查是否是重定向
if resp.StatusCode >= 300 && resp.StatusCode < 400 {
location, err := resp.Location()
if err == nil {
fmt.Printf("重定向到: %s\n", location.String())
}
}

