給微信伺服器發訊息

海興發表於2016-07-01

請原諒我還是沒有去看webchat-api的文件,不過我確實看了程式碼,所以接下來可以聊聊怎麼給微信伺服器發訊息。

微信伺服器開放了很多API,不過這些API還是挺整齊的,套路很簡單。說白了就是各種get或者post它提供的url一下,然後它給你一個json的響應。藉著ES 6和Promise的東風,我搞了下面這樣一個實現:

enter image description here

走在隊伍最前面的是Talker,它的身後跟著一群Manager。除此之外,Talker還有個助手,叫AccessTokenKeeper,它幫Talker管理向微信伺服器喊話用的口令。這個喊話小團伙就這三種崗位,結構簡單,權責清晰。

每次我們要發什麼訊息的時候,就把關鍵內容告訴相應的Manager,Manager會幫給你寫一份格式化的報告。就是上圖中Message那個樣子,其中會有urlmethod,json格式的parameters或者body。我們把這個Message交給Talkersend就ok了。Talker會根據Message中的method,決定用get還是post,當然,具體工作它都是交給著名的通訊員fetch去幹的。

有一點要說明的是,如果你對accessToken有特殊的要求,可以實現一個TokenStoreTalker,你怎麼存Talker並不關心,只要有loadAccessToken,需要的時候能把accessToken拿出來就可以了。

用程式碼來描述這個過程,大概是這樣的:

talker.send(UserManager.usersGet())
      .then(response => response.json())
      .then(json => {
          if(json.errcode) {                  
            console.log("Get user list got error:",json.errmsg)
            return(Error(json.errmsg))
          } else {
              console.log("Get users:",json)
              return MessageManager.textToCustom("感謝訂閱",json.next_openid)
          }
      })
      .catch(error => {
          console.log("There is an error to get nextOpenId")
      })
      .then(message => talker.send(message))
      .then(response => response.json())
      .then(json => {
              if(json.errcode) {                  
                console.log(`Send text message to customer ${nextOpenId} got error:${json.errmsg}`)
              } else {
                  console.log(`Send text message to ${nextOpenId} success`)                  
              }
       })

接下來請看我們最重要的Talker

class Talker {
    constructor(options) {    
        this.tokenKeeper = new TokenKeeper(options)
    }

    send(message) {
      switch(message.method) {
        case "get":
            return this._get(message)
        case "post":
            return this._post(message)
        default:
            return     new Promise(( resolve,reject) => {
                         reject({
                             errcode:10001,
                             errmsg:"There is no method in message"
                         })
            })
      }
    }

    _get(message) {
        ...
    }
    _post(message) {
        ...
    }
}

篇幅有限,就不完全展開了,_get和_post都很簡單,就是拿到accessToken後返回一個fetch請求。雖然Talker簡單,但Manager更簡單,比如MessageManagertextToCustomer

static textToCustom(content,openId) {
    return {
              "url":`${customUrlPrefix}send`,
              "method" : "post",
              "body": {
                           "touser":openId,
                            "msgtype":"text",
                            "text":
                            {
                                 "content":content
                            }
                        }
            }
}

最複雜的應該算是TokenKeeper了,但算上空行我也只寫了62行程式碼,還有多一半是從web-api的實現裡抄過來的,沒啥可看的。

可能隨著瞭解的不斷深入,還有更復雜的處理。但目前來看,最複雜的應該是具體業務的開發了。

相關文章