欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

GO制作微信機(jī)器人的流程分析

 更新時(shí)間:2022年08月01日 10:59:08   作者:Code?Writers  
這篇文章主要介紹了利用go制作微信機(jī)器人,本文主要包括項(xiàng)目基礎(chǔ)配置及詳細(xì)代碼講解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

這些天在學(xué)習(xí)Go,也寫了幾篇關(guān)于閱讀Gin后端項(xiàng)目代碼的博客。但編程這種,一定要實(shí)際上手練習(xí),要不然都是紙上談兵。于是就想上手自己實(shí)際寫一些代碼來練練手。思來想去,不知道能寫些什么來練手。后來突然想到,之前寫過用Python做微信聊天機(jī)器人(博客傳送門),當(dāng)時(shí)代碼沒有放到git上,后來重置了服務(wù)器導(dǎo)致代碼全部沒了?,F(xiàn)在正好苦于不知道做什么項(xiàng)目練手,可以用Go也實(shí)現(xiàn)一套微信聊天機(jī)器人。

說干就干,照著之前自己寫的博客,看了下當(dāng)時(shí)Python的代碼。轉(zhuǎn)而用Go優(yōu)化了下并實(shí)現(xiàn)。

0.回顧流程

根據(jù)之前Python寫的自動(dòng)發(fā)消息的機(jī)器人可知,要想發(fā)消息就需要三個(gè)參數(shù):company_id、secret、angent_id。 對(duì)于這三個(gè)參數(shù)如何獲取,可參考文章開頭的傳送門。整個(gè)發(fā)送消息過程就是 首先通過company_id和secret來調(diào)用接口獲取token,再通過token和angent_id來給對(duì)應(yīng)接口發(fā)送post請(qǐng)求,就可以把post請(qǐng)求體中的信息發(fā)送到微信上。

1.項(xiàng)目基礎(chǔ)配置

由于目前對(duì)Go的項(xiàng)目布局學(xué)習(xí)的還不是特別熟練,而且對(duì)于項(xiàng)目基礎(chǔ)部分如果從頭開始做的話,需要耗費(fèi)大量時(shí)間。因此我使用了基于開源gin項(xiàng)目進(jìn)行二次開發(fā)的方法,實(shí)現(xiàn)這個(gè)機(jī)器人。

前幾天在學(xué)習(xí)Gin時(shí),發(fā)現(xiàn)了一位老哥封裝了個(gè)Gin腳手架,可以達(dá)到開箱即用目的。項(xiàng)目地址: github傳送門。 里邊把讀取配置文件,編寫路由,連接數(shù)據(jù)庫(kù)等多個(gè)操作均進(jìn)行了實(shí)現(xiàn)。因此可以基于這個(gè)項(xiàng)目來進(jìn)行二次開發(fā),做微信機(jī)器人。

在把項(xiàng)目clone下來后,可以先看下整個(gè)項(xiàng)目的布局,主要的業(yè)務(wù)核心代碼都放在了internal 下面。如果我們要實(shí)現(xiàn)一個(gè)主動(dòng)給微信發(fā)消息的功能,那么多說了就是寫一個(gè)發(fā)送消息的方法,讓后端調(diào)用這個(gè)方法即可。

要想基于此項(xiàng)目來開發(fā)微信機(jī)器人,首先就要將三個(gè)參數(shù)配置上。項(xiàng)目中,對(duì)于各種參數(shù)均在config.yaml中配置,因?yàn)榭梢栽谶@個(gè)配置文件中增加這三個(gè)參數(shù)的配置:

然后在代碼的config/autoload目錄下新增一個(gè)weCaht.go 文件,接收配置文件中的配置。

package autoload
type WeChatConfig struct {
AgentId string ini:"wechat" yaml:"agent_id"
Secret string ini:"wechat" yaml:"secret"
CompanyId string ini:"wechat" yaml:"company_id"
}
var WeChat = WeChatConfig{}

并且,將此配置加入到項(xiàng)目的配置集合中。在config/config.go中添加如下代碼:

這樣操作,就可以通過代碼來讀取配置文件了。在其他包中,可以通過如下方式來訪問對(duì)應(yīng)的值

config.Config.WeChat.CompanyId //yaml中的company_id字段

2. Redis封裝

因?yàn)橐o微信發(fā)送消息,首先要獲取到token,而官方介紹此token的有效時(shí)長(zhǎng)為2小時(shí)。在之前Python的項(xiàng)目中,是直接將token寫到了文件中,通過文件來讀取。在此項(xiàng)目中,我想直接使用redis來存儲(chǔ)。因?yàn)槭褂胷edis來存儲(chǔ)的話,可以設(shè)置key值時(shí)長(zhǎng),過了這個(gè)時(shí)長(zhǎng)就自動(dòng)清除,這樣就方便了許多。

而我們基于這個(gè)gin-layout項(xiàng)目中,已經(jīng)對(duì)redis做了一層封裝,具體代碼可查看data/redis.go,主要是通過對(duì)外暴露一個(gè)Rdb的結(jié)構(gòu)體,來操作redis

而目前我們這邊使用redis,只會(huì)用到對(duì)應(yīng)的set和get方法。因此我對(duì)這個(gè)項(xiàng)目中的redis又做了一層封裝。只對(duì)外暴露set,get,del方法。
首先將Rdb變量名改為小寫,這樣就代表不對(duì)外暴露,然后在此文件中添加如下代碼

func SetRedis(key string, value string, t int64) bool {
expire := time.Duration(t) * time.Second
if err := rdb.Set(ctx, key, value, expire).Err(); err != nil {
return false
}
return true
}

func GetRedis(key string) string {
result, err := rdb.Get(ctx, key).Result()
if err != nil {
return “”
}
return result
}

func DelRedis(key string) bool {
_, err := rdb.Del(ctx, key).Result()
if err != nil {
return false
}
return true
}

這樣,后續(xù)使用redis時(shí)候,只需要調(diào)用data.SetRedis(xxx) 即可。
然后就是修改配置文件,啟用redis,這里根據(jù)實(shí)際的redis配置來寫即可。

3.消息體封裝

在最終給微信服務(wù)器發(fā)送post請(qǐng)求時(shí),對(duì)應(yīng)的請(qǐng)求體格式如下:

{
“touser”: “@all”,
“msgtype”: “text”,
“agentid”: “xxxxx”,
“text”: {“content”: “xxxx”}
}

因此,接下來可以對(duì)這個(gè)結(jié)構(gòu)體做一個(gè)封裝。在model包下,新建一個(gè)send_msg.go文件

package model
type wcSendcontent struct {
Content string json:"content"
}
type WcSendMsg struct {
ToUser string json:"touser"
MsgType string json:"msgtype"
AgentId string json:"agentid"
Text wcSendcontent json:"text"
}
func (t *WcSendMsg) SetMessage(message string) {
t.Text.Content = message
}

這里針對(duì)message信息,專門對(duì)外暴露了一個(gè)方法來進(jìn)行設(shè)置。

4.核心代碼

在設(shè)置好redis,消息體封裝后,就可以編寫核心的代碼了。主要就是通過發(fā)送http請(qǐng)求,獲取token,再通過token發(fā)送post請(qǐng)求來發(fā)送消息。我們可以在service包下新建一個(gè)weChat.go的文件,里邊新建一個(gè)SendWeChat方法來進(jìn)行消息發(fā)送操作。

package service

import (
“bytes”
“encoding/json”
“errors”
“fmt”
c "github.com/wannanbigpig/gin-layout/config"
"github.com/wannanbigpig/gin-layout/data"
"github.com/wannanbigpig/gin-layout/internal/model"
log "github.com/wannanbigpig/gin-layout/internal/pkg/logger"
"github.com/wannanbigpig/gin-layout/pkg/utils"
"go.uber.org/zap"
)

/**

@description: 給企微發(fā)送消息
@param {string} message 消息內(nèi)容
@param {string} msgType 消息類型
@return {*}
*/
func SendWeChat(message string, msgType string) error {
redis_key := “access_token”
// 嘗試從redis中讀取token
accessToken := data.GetRedis(redis_key)
http := &utils.HttpRequest{}
// 若redis中的token已過期,則重新請(qǐng)求api獲取token
if accessToken == “” {
log.Logger.Info(“access token is null, will recall”)
getTokenUrl := fmt.Sprintf(“https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s”,
c.Config.WeChat.CompanyId, c.Config.WeChat.Secret)
log.Logger.Info(“token_url”, zap.String(“url”, getTokenUrl))
http.Request(“GET”, getTokenUrl, nil)
ret := make(map[string]interface{})
if err := http.ParseJson(&ret); err != nil {
return err
}
marshal, _ := json.Marshal(ret)
log.Logger.Info(string(marshal))
accessToken = fmt.Sprintf("%v", ret[“access_token”])
// 寫入redis 有效期2小時(shí)
data.SetRedis(redis_key, accessToken, 7200)
}
msg := &model.WcSendMsg{
ToUser: “@all”,
MsgType: msgType,
AgentId: c.Config.WeChat.AgentId,
}
msg.SetMessage(message)
sendMsgUrl := fmt.Sprintf(“https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%v”, accessToken)
log.Logger.Info(“sendMsgUrl = " + string(sendMsgUrl))
header := map[string]string{“Content-Type”: “application/json”}
bytesData, _ := json.Marshal(msg)
http.Request(“POST”, sendMsgUrl, bytes.NewReader(bytesData), header)
log.Logger.Info(“bytes data = " + string(bytesData))
ret := make(map[string]interface{})
err := http.ParseJson(&ret)
if err != nil {
return err
}
if ret[“errcode”].(float64) != 0 {
errmsg := fmt.Sprintf(”%v”, ret[“errmsg”])
return errors.New(errmsg)
}
return nil
}

從上面代碼中可以看出,首先是通過redis來獲取token,若沒有則請(qǐng)求api獲取token,并將其寫入到redis中,有效期為2小時(shí)。然后生成一個(gè)之前封裝的消息的結(jié)構(gòu)體,將AgentId和message進(jìn)行填充后,通過發(fā)送post請(qǐng)求,已達(dá)到發(fā)消息的目的。

5.本地測(cè)試

若想驗(yàn)證這個(gè)方法,可以通過對(duì)外提供一個(gè)接口,訪問此接口后調(diào)用發(fā)送消息的方法。
可以在controller目錄下新建一個(gè)weChat.go,在里邊實(shí)現(xiàn)一個(gè)get請(qǐng)求的方法,獲取請(qǐng)求中的msg參數(shù),然后調(diào)用剛才實(shí)現(xiàn)的發(fā)送企微的方法。

package wechat

import (
“github.com/gin-gonic/gin”
“github.com/wannanbigpig/gin-layout/internal/pkg/error_code”
log “github.com/wannanbigpig/gin-layout/internal/pkg/logger”
r “github.com/wannanbigpig/gin-layout/internal/pkg/response”
“github.com/wannanbigpig/gin-layout/internal/service”
)

func SendMsg(c *gin.Context) {
msg, ok := c.GetQuery(“msg”)
if !ok {
msg = “please input message”
}
log.Logger.Info("send wechat message: " + msg)
err := service.SendWeChat(msg, “text”)
if err != nil {
r.Resp().FailCode(c, error_code.FAILURE, err.Error())
return
}
r.Success(c, “success”)
}

寫好后,將此方法綁定到路由上。在routers包下新建一個(gè)weChatRouter.go文件

package routers

import (
“github.com/gin-gonic/gin”
w “github.com/wannanbigpig/gin-layout/internal/controller/wechat”
)

func setWeChatRouter(r *gin.Engine) {
// version 1
v1 := r.Group(“wechat”)
{
v1.GET("/send", w.SendMsg)
}
}

這樣,后續(xù)可以通過wechat/send的url來請(qǐng)求這個(gè)接口。最后就是調(diào)用此綁定路由的方法,在routers/router.go中添加一行代碼即可

接下來啟動(dòng)項(xiàng)目,比如發(fā)送一個(gè)msg=Hello,Golang 的請(qǐng)求

curl --location --request GET “http:// I P : {IP}: IP:{PORT}/wechat/send?msg=Hello,Golang”

執(zhí)行這個(gè)命令,就可以得到本文開頭的截圖。

當(dāng)然,這個(gè)api接口主要是為了讓我們驗(yàn)證,實(shí)際項(xiàng)目運(yùn)行時(shí),建議不要這么搞。因?yàn)檫@接口沒有任何鑒權(quán)的措施,如果對(duì)外暴露了出去,那么別人也可以肆意的調(diào)用這個(gè)接口給你的企微發(fā)送消息。

到此這篇關(guān)于利用go制作微信機(jī)器人的文章就介紹到這了,更多相關(guān)go微信機(jī)器人內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang實(shí)現(xiàn)Directional Channel(定向通道)

    Golang實(shí)現(xiàn)Directional Channel(定向通道)

    這篇文章主要介紹了Golang實(shí)現(xiàn)Directional Channel(定向通道),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Go?channel結(jié)構(gòu)體源碼和讀寫和關(guān)閉過程詳解

    Go?channel結(jié)構(gòu)體源碼和讀寫和關(guān)閉過程詳解

    這篇文章主要介紹了Go?channel結(jié)構(gòu)體源碼和讀寫和關(guān)閉過程,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • go開源項(xiàng)目用戶名密碼驗(yàn)證的邏輯鬼才寫法

    go開源項(xiàng)目用戶名密碼驗(yàn)證的邏輯鬼才寫法

    這篇文章主要為大家介紹了go開源項(xiàng)目中發(fā)現(xiàn)的一個(gè)邏輯鬼才寫法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Golang教程之不可重入函數(shù)的實(shí)現(xiàn)方法

    Golang教程之不可重入函數(shù)的實(shí)現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于Golang教程之不可重入函數(shù)的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • Go源碼字符串規(guī)范檢查lint工具strchecker使用詳解

    Go源碼字符串規(guī)范檢查lint工具strchecker使用詳解

    這篇文章主要為大家介紹了Go源碼字符串規(guī)范檢查lint工具strchecker使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Go語言實(shí)現(xiàn)簡(jiǎn)單的一個(gè)靜態(tài)WEB服務(wù)器

    Go語言實(shí)現(xiàn)簡(jiǎn)單的一個(gè)靜態(tài)WEB服務(wù)器

    這篇文章主要介紹了Go語言實(shí)現(xiàn)簡(jiǎn)單的一個(gè)靜態(tài)WEB服務(wù)器,本文給出了實(shí)現(xiàn)代碼和運(yùn)行效果,學(xué)習(xí)Golang的練手作品,需要的朋友可以參考下
    2014-10-10
  • sublime3+Golang+代碼補(bǔ)全的實(shí)現(xiàn)

    sublime3+Golang+代碼補(bǔ)全的實(shí)現(xiàn)

    本文主要介紹了sublime3+Golang+代碼補(bǔ)全的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Go語言通過Luhn算法驗(yàn)證信用卡卡號(hào)是否有效的方法

    Go語言通過Luhn算法驗(yàn)證信用卡卡號(hào)是否有效的方法

    這篇文章主要介紹了Go語言通過Luhn算法驗(yàn)證信用卡卡號(hào)是否有效的方法,實(shí)例分析了Luhn算法的原理與驗(yàn)證卡號(hào)的使用技巧,需要的朋友可以參考下
    2015-03-03
  • Go 實(shí)現(xiàn)熱重啟的詳細(xì)介紹

    Go 實(shí)現(xiàn)熱重啟的詳細(xì)介紹

    這篇文章主要介紹了Go 實(shí)現(xiàn)熱重啟的詳細(xì)介紹,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 使用go xorm來操作mysql的方法實(shí)例

    使用go xorm來操作mysql的方法實(shí)例

    今天小編就為大家分享一篇關(guān)于使用go xorm來操作mysql的方法實(shí)例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-04-04

最新評(píng)論