Go Recivie Email

前言 电子邮件是现代办公和通信中不可或缺的工具,它广泛应用于数据交换和工作沟通。为了更高效地处理邮件内容,我们可以借助程序来实现自动化处理。本文将详细介绍如何使用 Go 语言来接收和处理电子邮件。 通过查阅资料,了解到可以通过 IMAP 协议来接收电子邮件,IMAP 协议是电子邮件接收协议,它允许客户端通过网络连接到邮件服务器,并从服务器上下载邮件。除了 IMAP 协议,还有 POP3 协议,POP3 协议与 IMAP 协议类似,但它在在客户端上对邮件的操作不会反馈到邮件服务器上,也就是说,在客户端的操作不会影响服务器上的邮件。当你需要从多个邮件客户端访问邮件时,IMAP 协议是一个更好的选择。 go-imap 通过对比不同的库,最后选择了 go-imap 库,它是一个基于 IMAP 协议的 Go 语言库,可以通过它构建客户端或者服务端。 安装 可以通过以下命令安装: go get github.com/emersion/go-imap 使用 我们将通过官方的例子进行切入: 先通过 DialTLS 连接对应的电子邮箱 IMAP 服务器,然后通过登录邮箱,获取所有的邮箱文件夹,最后选择收件箱,获取收件箱中最新的4封邮件,并打印没封邮件的主题。 运行代码: 2024/11/23 16:16:11 Connecting to server... 2024/11/23 16:16:11 Connected 2024/11/23 16:16:12 Logged in 2024/11/23 16:16:12 Mailboxes: 2024/11/23 16:16:13 * 其他文件夹 2024/11/23 16:16:13 * Drafts 2024/11/23 16:16:13 * Deleted Messages 2024/11/23 16:16:13 * Sent Messages 2024/11/23 16:16:13 * Junk 2024/11/23 16:16:13 * INBOX 2024/11/23 16:16:13 Flags for INBOX: [\Answered \Flagged \Deleted \Draft \Seen] 2024/11/23 16:16:13 Last 4 messages: 2024/11/23 16:16:13 * =?GBK?B?xx?= 2024/11/23 16:16:13 * =?GBK?B?xxx?= 2024/11/23 16:16:13 * =?GBK?B?xx==?= 2024/11/23 16:16:13 * =?GBK?B?xx+k=?= 2024/11/23 16:16:13 Done! 可以看到打印出来的邮件主题是乱码,通过查询资料,了解到邮件的字段是采用特殊编码的,需要进行解码。可以通过https://github.com/emersion/go-message 这个库进行解码。 ...

十一月 23, 2024 · overstarry

go humanize介绍

前言 今天在 Github 查看一些开源项目时,发现了一个"人性化"的项目 go-humanize,此项目可以将一些常见的容量、时间、千分位转换为人们可以理解的形式,例如一个文件大小是 2000000 bytes,我们不能很好的理解,但如果告诉你是 2mb,我们就能很好的理解了。 go-humanize 就是方便的将一些不太能快速理解的数字转换为人们可以理解的形式。 安装 使用以下命令安装: go get github.com/dustin/go-humanize 使用 接下来分别介绍一些常见的功能。 容量转换 现在我们有一个文件大小是 52854982 bytes,我们使用 humanize 包的 Bytes 方法将其转换为人们可以理解的形式 53MB,也可以使用IBytes方法转换为MIB单位的值。也可以使用ParseBytes方法将可以理解的形式转换为bytes单位的值。 fmt.Printf("That file is %s.\n", humanize.IBytes(52854982)) fmt.Printf("That file is %s.", humanize.Bytes(52854982)) 时间转换 时间转换与容量转换类型,使用方法十分类似,使用方法如下: t := time.Now().Add(time.Hour * -7) fmt.Printf("This was touched %s.", humanize.Time(t)) //This was touched 7 hours ago. Time 根据相对时间转换为人们可以理解的形式,例如: xx天之前、xx小时之后等形式。 千分位转换 如果我们想在数字中添加逗号,就可以使用 Comma 方法,例如在处理金额时,我们通常会使用逗号将数字分隔开,例如 1,000,000,000 fmt.Printf("num is %s.", humanize.Comma(1000000000)) 还可以使用 Commaf 方法将浮点数转换为千分位形式。 位序 在日常使用中,我们有时需要表示位序例如 1st、2nd、3rd、4th 等,humanize 包也提供了相应的功能。 fmt.Printf("num is %s.", humanize.Ordinal(1000000000)) 简单看了下源码,发现函数十分简单: func Ordinal(x int) string { suffix := "th" switch x % 10 { case 1: if x%100 != 11 { suffix = "st" } case 2: if x%100 != 12 { suffix = "nd" } case 3: if x%100 != 13 { suffix = "rd" } } return strconv.Itoa(x) + suffix } 小结 本文介绍了 go-humanize 包的一些使用方法,可以方便的将一些数字转换为人们可以理解的形式。go-humanize 还有一些格式化的函数,感兴趣的读者可以自行查看源码。 ...

八月 10, 2024 · overstarry

katana 新一代的爬虫工具

katana 介绍 katana是一款强大的新一代的网络爬虫工具,通过使用 katana ,用户能够快速的进行互联网资源的爬取和渗透测试阶段的收集任务。 特点 katana 有以下特点: 快速及高可配置的网络爬虫 标准及无头模式 主动和被动模式 JavaScript 脚本爬取解析 定制的表单内容自动填充 爬取范围控制 可自定义设置输出字段 输入数据 支持标准输入(STDIN),URL和列表(LIST) 输出数据 支持STDOUT、文件和JSON格式 安装 接下来介绍如何安装 katana katana 的安装需要 go1.18版本以上,可以执行以下命令或下载Github 仓库的发布版本。 go install github.com/projectdiscovery/katana/cmd/katana@latest windows 在安装中可能会遇到以下报错: github.com/smacker/go-tree-sitter/javascript: build constraints exclude all Go files in C:\Users\overstarry\go\pkg\mod\github.com\smacker\[email protected]\javascript # github.com/smacker/go-tree-sitter go\pkg\mod\github.com\smacker\[email protected]\iter.go:17:18: undefined: Node go\pkg\mod\github.com\smacker\[email protected]\iter.go:21:21: undefined: Node go\pkg\mod\github.com\smacker\[email protected]\iter.go:25:20: undefined: Node go\pkg\mod\github.com\smacker\[email protected]\iter.go:30:26: undefined: Node go\pkg\mod\github.com\smacker\[email protected]\iter.go:34:20: undefined: Node go\pkg\mod\github.com\smacker\[email protected]\iter.go:38:32: undefined: Node go\pkg\mod\github.com\smacker\[email protected]\iter.go:43:9: undefined: Node go\pkg\mod\github.com\smacker\[email protected]\iter.go:46:18: undefined: Node go\pkg\mod\github.com\smacker\[email protected]\iter.go:68:40: undefined: Node 可以使用以下命令解决: ...

六月 29, 2024 · overstarry

Go 刷新 cdn

前言 cdn 刷新是 cdn 使用过程中的一项重要的功能,通过刷新功能,您可以删除CDN节点上已经缓存的资源,并强制CDN节点回源站获取最新资源,适用于源站资源更新和发布、违规资源清理、域名配置变更等。 接下来将分别讲述 阿里云CDN、AWS cloudfront 、Cloudflare cdn 使用 go 语言进行 cdn 的刷新操作的。 阿里云刷新 cdn 如何刷新 阿里云 cdn 的缓存呢? 只需使用 阿里云 openapi 的 go sdk 即可,通过查阅文档,我们只需使用 RefreshObjectCaches API即可刷新阿里云 cdn 的缓存,RefreshObjectCaches 有以下参数: ObjectPath: 刷新的url ,多个 url 使用换行符进行分隔 ObjectType: 刷新任务的类型,有以下类型 File(默认值):文件刷新。 Directory:目录刷新。 Regex:正则刷新。 IgnoreParams:去参数刷新。去参数指的是去除请求 URL 中?及?之后的参数,去参数刷新指的是用户先通过接口提交去参数后的 URL,然后用户提交的待刷新 URL 将会与已缓存资源的 URL 进行去参数匹配,如果已缓存资源的 URL 去参数以后与待刷新 URL 匹配,那么 CDN 节点将对缓存资源执行刷新处理。 Force: 当回源内容和源站资源对比后不一致时,是否刷新对应目录下的资源。默认为 false。 下面是一个例子: package main import ( cdn20180510 "github.com/alibabacloud-go/cdn-20180510/v4/client" openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client" util "github.com/alibabacloud-go/tea-utils/v2/service" "github.com/alibabacloud-go/tea/tea" "os" ) func CreateClient(accessKeyId *string, accessKeySecret *string) (result *cdn20180510.Client, err error) { config := &openapi.Config{ AccessKeyId: accessKeyId, AccessKeySecret: accessKeySecret, } config.Endpoint = tea.String("cdn.ap-southeast-1.aliyuncs.com") result = &cdn20180510.Client{} result, err = cdn20180510.NewClient(config) return result, err } func main() { client, err := CreateClient(tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")), tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))) if err != nil { return } refreshObjectCachesRequest := &cdn20180510.RefreshObjectCachesRequest{ ObjectPath: tea.String("http://example.com/image/1.png\\\n\t\thttp://aliyundoc.com/image/2.png"), } runtime := &util.RuntimeOptions{} _, err = client.RefreshObjectCachesWithOptions(refreshObjectCachesRequest, runtime) if err != nil { return } return } aws cloudfront 接下来讲解 aws cloudfront 如何刷新 cdn,cloudfront 刷新缓存的操作叫使文件失效,通过查阅 cloudfront 的API文档,发现可以使用 CreateInvalidation 来创建失效。可以使用 aws go sdk 来进行操作。 ...

一月 19, 2024 · overstarry

go 汉字转拼音 go-pinyin

前言 本文介绍一个 go 汉字转拼音的库 go-pinyin,可以从名字看出这个库的功能就是将汉字转换为相应的拼音。接下来就由我来简单的介绍 go-pinyin 。 安装 使用此命令安装: go get github.com/mozillazg/go-pinyin cli 安装 如果你的 go 版本在 1.17 以下使用此命令安装: go get -u github.com/mozillazg/go-pinyin/cli/pinyin。1.17及以上版本使用此命令安装:go install github.com/mozillazg/go-pinyin/cli/pinyin@latest。 使用 接下来将分别介绍 cli 的使用和 API 的使用。 cli 使用 安装完在终端输入 pinyin,可以看到使用的方法,尝试一个汉字,可以看到相应的拼音,但也可以看出对多音字的支持有问题。 $ pinyin 中国 zhōng guó $ pinyin 重庆 zhòng qìng 接下来介绍 API 的使用。 api 使用 通过查看文档,可以看出主要是2个方法 pinyin.NewArgs 和 pinyin.Pinyin 。 pinyin.NewArgs 创建包含默认配置的 Args, 可以通过修改 Args 的成员来使用不同的模式。 type Args struct { Style int // 拼音风格(默认: Normal) Heteronym bool // 是否启用多音字模式(默认:禁用) Separator string // Slug 中使用的分隔符(默认:-) // 处理没有拼音的字符(默认忽略没有拼音的字符) // 函数返回的 slice 的长度为0 则表示忽略这个字符 Fallback func(r rune, a Args) []string } pinyin.Pinyin 就是将汉字转为拼音。 ...

十二月 23, 2023 · overstarry

mergo 介绍

前言 今天介绍一个 go 库 - mergo, mergo 用来方便的合并 struct 和 map ,可以将结构体的字段赋值到map中,可以将map的值赋值给结构体的字段. Mergo 通过在零值字段中设置默认值来合并同类型的struct 和 map。Mergo 不会合并未导出(私有)字段。它会递归合并任何已导出的字段。它也不会合并map中的结构体(因为它们无法使用 Go 反射寻址)。 Mergo 在很多知名项目中被使用,如 containerd、k8s、loki等。 安装 使用以下命令安装 mergo : go get -u dario.cat/mergo 使用 接下来介绍 mergo 的基础使用和高级用法。 基础使用 mergo 提供了2个主要函数: Merge和Map, Mergo 用来合并2个相同结构的 struct 和 map, Map 用来在结构和map之间赋值。 例子: package main import ( "fmt" "log" "github.com/imdario/mergo" ) type redisConfig struct { Address string Port int DB int UserName string PassWord string } var defaultConfig = redisConfig{ Address: "127.0.0.1", Port: 6379, DB: 1, UserName: "123", PassWord: "123", } func main() { var config redisConfig if err := mergo.Merge(&config, defaultConfig); err != nil { log.Fatal(err) } fmt.Println("redis address: ", config.Address) fmt.Println("redis port: ", config.Port) fmt.Println("redis db: ", config.DB) fmt.Println("redis username: ", config.UserName) fmt.Println("redis password: ", config.PassWord) var m = make(map[string]interface{}) if err := mergo.Map(&m, defaultConfig); err != nil { log.Fatal(err) } fmt.Println(m) } 接下来介绍一些高级用法: ...

十二月 16, 2023 · overstarry

conc 一个更好的go并发库

前言 本文介绍 conc - 一个更好的 go 并发库, sourcegraph 在日常开发中使用go原生并发出现了问题,由此开发了 conc ,相比标准并发代码更优雅,代码更少,下面展示一个例子,可以看出代码减少了许多. type propagatedPanic struct { val any stack []byte } func main() { done := make(chan *propagatedPanic) go func() { defer func() { if v := recover(); v != nil { done <- &propagatedPanic{ val: v, stack: debug.Stack(), } } else { done <- nil } }() doSomethingThatMightPanic() }() if val := <-done; val != nil { panic(val) } } // conc func main() { var wg conc.WaitGroup wg.Go(doSomethingThatMightPanic) // panics with a nice stacktrace wg.Wait() } 安装 使用以下命令进行安装: go get github.com/sourcegraph/conc ...

十二月 9, 2023 · overstarry

Go 漏洞管理工具 govulncheck

前言 在7月份 go 团队正式推出了官方的漏洞检测工具 - govulncheck, govulncheck 默认向 https://vuln.go.dev/ 漏洞数据库请求, 对数据库的请求不包含代码只有使用的包,你也可以使用 -db 来指导所使用的漏洞数据库,所使用的数据库必须实现相应的规范。 govulncheck 具有以下限制: Govulncheck在分析函数指针和接口调用时采用保守的方法,这可能导致一些情况下的误报或不准确的调用堆栈。 使用reflect进行的函数调用对于静态分析是不可见的。仅通过这些调用才能访问的易受攻击的代码将不会被报告。使用unsafe包可能导致漏报。 由于Go二进制文件不包含详细的调用信息,govulncheck无法显示检测到的漏洞的调用图。对于二进制文件中但无法访问的代码,它可能还会报告误报。 目前还不支持 silencing 漏洞发现。请参阅https://go.dev/issue/61211 。 Govulncheck只能读取使用Go 1.18及更高版本编译的二进制文件。 对于无法提取符号信息的二进制文件,govulncheck会报告二进制文件所依赖的所有模块的漏洞。 govulncheck 架构图 govulncheck 还提供了一个可用的 API govulncheck,使开发者能够方便的将 govulncheck 集成到各种工具之中。 安装 通过以下命令安装 govulncheck: go install golang.org/x/vuln/cmd/govulncheck@latest 使用 安装完 govulncheck 后,我们就可以使用了,进入项目路径中,执行 govulncheck ./... 。 以下是我的一个项目的输出: Scanning your code and 508 packages across 71 dependent modules for known vulnerabilities... Vulnerability #1: GO-2023-2102 HTTP/2 rapid reset can cause excessive work in net/http More info: https://pkg.go.dev/vuln/GO-2023-2102 Standard library Found in: net/[email protected] Fixed in: net/[email protected] Example traces found: #1: cmd\xxx\main.go:94:19: xxx.main calls kratos.App.Run, which eventually calls http.Server.Serve #2: cmd\xxx\main.go:94:19: xxx.main calls kratos.App.Run, which eventually calls http.Server.ServeTLS Vulnerability #2: GO-2023-2043 Improper handling of special tags within script contexts in html/template More info: https://pkg.go.dev/vuln/GO-2023-2043 Standard library Found in: html/[email protected] Fixed in: html/[email protected] Example traces found: #1: cmd\xxx\main.go:94:19: xxx.main calls kratos.App.Run, which eventually calls template.Template.Execute #2: cmd\xxx\main.go:94:19: xxx.main calls kratos.App.Run, which eventually calls template.Template.ExecuteTemplate Vulnerability #3: GO-2023-2041 Improper handling of HTML-like comments in script contexts in html/template More info: https://pkg.go.dev/vuln/GO-2023-2041 Standard library Found in: html/[email protected] Fixed in: html/[email protected] Example traces found: #1: cmd\xxx\main.go:94:19: xxx.main calls kratos.App.Run, which eventually calls template.Template.Execute #2: cmd\xxx\main.go:94:19: xxx.main calls kratos.App.Run, which eventually calls template.Template.ExecuteTemplate === Informational === Found 3 vulnerabilities in packages that you import, but there are no call stacks leading to the use of these vulnerabilities. You may not need to take any action. See https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck for details. Vulnerability #1: GO-2023-2045 Memory exhaustion in QUIC connection handling in crypto/tls More info: https://pkg.go.dev/vuln/GO-2023-2045 Standard library Found in: crypto/[email protected] Fixed in: crypto/[email protected] Vulnerability #2: GO-2023-2044 Panic when processing post-handshake message on QUIC connections in crypto/tls More info: https://pkg.go.dev/vuln/GO-2023-2044 Standard library Found in: crypto/[email protected] Fixed in: crypto/[email protected] Vulnerability #3: GO-2023-1988 Improper rendering of text nodes in golang.org/x/net/html More info: https://pkg.go.dev/vuln/GO-2023-1988 Module: golang.org/x/net Found in: golang.org/x/[email protected] Fixed in: golang.org/x/[email protected] Your code is affected by 3 vulnerabilities from the Go standard library. Share feedback at https://go.dev/s/govulncheck-feedback. 输出内容分为2块,第一块是 Vulnerability 信息,是项目中存在的漏洞,可以看到发现了3个漏洞及具体的原因、触发函数、发现的版本和修复的版本。第二块是 Informational 是一些没有直接引用的包中存在的安全漏洞。 ...

十月 14, 2023 · overstarry

Go WSDL

最近在实现一个功能时需要使用第三方的接口,由于第三方只提供了一个 WSDL 文件的链接,于是研究了 golang 如何解析 WSDL 并调用相应接口, 本文就是介绍 WSDL 和 go 如何解析并调用。 WSDL 介绍 WSDL 是 Web Services Description Language(Web服务描述语言)的缩写。它是一种用于描述基于Web服务的通信协议和消息格式的XML格式语言。 WSDL 被广泛用于描述Web服务的接口和操作。它定义了Web服务所提供的功能、方法、参数、数据类型以及与服务进行交互的方式。通过WSDL文件,客户端应用程序可以了解如何与特定的Web服务进行通信。 WSDL文件通常包含以下几个主要部分: 服务定义:描述了Web服务的名称、命名空间和位置。 类型定义:定义了Web服务中使用的数据类型,例如字符串、整数等。 消息定义:定义了Web服务中使用的消息格式,包括输入和输出消息。 操作定义:定义了Web服务的操作或方法,包括输入和输出消息以及相关的参数。 绑定定义:定义了Web服务使用的通信协议和消息格式,例如SOAP(Simple Object Access Protocol)和HTTP(Hypertext Transfer Protocol)。 服务定义:将服务、绑定和端口等部分组合在一起,定义了Web服务的完整描述。 使用WSDL,开发人员可以生成客户端代码,使其能够与Web服务进行交互。客户端可以根据WSDL文件了解Web服务的结构和可用方法,以便正确地构造请求和解析响应。 总之,WSDL是一种用于描述Web服务接口和操作的语言,它提供了一种标准化的方式来描述和访问Web服务。 gowsdl go语言如何解析 wsdl呢,我们使用 gowsdl 来解析 wsdl ,生成相应的 golang 代码。 安装 go install github.com/hooklift/gowsdl/cmd/gowsdl@latest 生成代码 使用命令 gowsdl -o myservice.go http://www.example.com/myservice?wsdl 生成代码。如果网络情况不好,我们也可以将 WSDL 文件下载下来解析 gowsdl -o xx.go a.xml。 解析完毕会生成相应的客户端文件,我们只要通过生成的客户端链接服务即可执行相应的方法。 code: package main import ( "adx/myservice" "fmt" "github.com/hooklift/gowsdl/soap" "golang.org/x/oauth2" "log" ) func main() { client := soap.NewClient("https://ads.xxx?wsdl", soap.WithHTTPHeaders(map[string]string{ "Authorization": fmt.Sprintf("Bearer %s", xxxx), })) service := myservice.NewxxServiceInterface(client) ReportableType := myservice.xx type_ := myservice.xx reply, err := service.xx(&myservice.xx{ Keys: []*myservice.xx{{ Name: "test111", DisplayName: "test111", Type_: &type_, ReportableType: &ReportableType, }}, }) if err != nil { log.Fatal(err) return } log.Println(reply) } 小结 在对 soap 库的简单尝试后,发现了一些问题: ...

九月 23, 2023 · overstarry

playwright-go浏览器截图

以前的文章介绍了 chromedp 进行浏览器网页截图, 这次介绍一种新的网页截图的方法——即使用 playwright 进行浏览器网页截图。 playwright 介绍 Playwright是一个用于自动化浏览器操作的开源工具集。它由微软开发并于2020年发布,旨在提供一种跨浏览器、跨平台的解决方案,可用于测试Web应用程序、编写爬虫、执行自动化任务等。 Playwright支持多种主流浏览器,包括Chrome、Firefox、Safari和Edge,它提供了一组简单易用的API,可以模拟用户与Web页面的交互行为,例如点击、填写表单、导航等。与其他类似工具相比,Playwright的一个重要特点是它的跨浏览器支持,这意味着你可以使用相同的代码在不同浏览器上运行你的自动化任务,而不需要为每个浏览器单独编写代码。 Playwright还提供了强大的调试功能,可以帮助开发人员在自动化过程中定位和解决问题。它支持截图和录制操作,使得调试变得更加直观和高效。 另外,Playwright还具有一些高级功能,例如可以模拟不同的设备、网络环境和地理位置,以及支持并发执行多个浏览器实例等,这些功能使得它在编写复杂的自动化任务时非常有用。 由于我日常主要使用 go 语言进行开发,所以本文的内容主要以 playwright 的 go 模块 playwright-go 为主要介绍。 安装 go get -u github.com/playwright-community/playwright-go 安装相关浏览器和操作系统依赖项: go run github.com/playwright-community/playwright-go/cmd/playwright@latest install --with-deps # Or go install github.com/playwright-community/playwright-go/cmd/playwright@latest playwright install --with-deps 也可以在代码中使用以下代码安装: err := playwright.Install() 通过安装截图可以看出安装了3大主流浏览器和ffmpeg。 例子 接下来我们看一个官方的例子,从Hacker News中抓取当前投票最高的项目。 package main import ( "fmt" "log" "github.com/playwright-community/playwright-go" ) func main() { pw, err := playwright.Run() if err != nil { log.Fatalf("could not start playwright: %v", err) } browser, err := pw.Chromium.Launch() if err != nil { log.Fatalf("could not launch browser: %v", err) } page, err := browser.NewPage() if err != nil { log.Fatalf("could not create page: %v", err) } if _, err = page.Goto("https://news.ycombinator.com"); err != nil { log.Fatalf("could not goto: %v", err) } entries, err := page.Locator(".athing").All() if err != nil { log.Fatalf("could not get entries: %v", err) } for i, entry := range entries { title, err := entry.Locator("td.title > span > a").TextContent() if err != nil { log.Fatalf("could not get text content: %v", err) } fmt.Printf("%d: %s\n", i+1, title) } if err = browser.Close(); err != nil { log.Fatalf("could not close browser: %v", err) } if err = pw.Stop(); err != nil { log.Fatalf("could not stop Playwright: %v", err) } } ...

九月 2, 2023 · overstarry