Skip to content

Instantly share code, notes, and snippets.

@yangbajing
Created December 9, 2014 15:11
Show Gist options
  • Save yangbajing/eb1f4453b7dbaa600def to your computer and use it in GitHub Desktop.
Save yangbajing/eb1f4453b7dbaa600def to your computer and use it in GitHub Desktop.
spray-client示例
package net.yangbajing.weixin.qy.client
import java.lang.reflect.InvocationTargetException
import akka.actor.ActorRefFactory
import akka.util.Timeout
import com.typesafe.scalalogging.StrictLogging
import net.yangbajing.weixin.qy.message._
import net.yangbajing.weixin.qy.util.WeixinQYConf
import net.yangbajing.weixin.util._
import org.json4s.JsonAST.JInt
import org.json4s.jackson.{JsonMethods, Serialization}
import org.json4s.{Formats, JValue, MappingException}
import spray.client.pipelining._
import spray.http._
import spray.httpx.marshalling.Marshaller
import spray.httpx.unmarshalling.Unmarshaller
import yangbajing.common.MessageException
import scala.concurrent.{ExecutionContext, Future}
/**
* 直接访问微信接口
* Created by Yang Jing on 2014-10-13.
*/
object WeixinQyClient {
def apply(weixinConf: WeixinQYConf, weixinApp: WeixinApp
)(implicit system: ActorRefFactory, ec: ExecutionContext, timeout: Timeout, format: Formats) =
new WeixinQyClient(weixinConf, weixinApp)
}
class WeixinQyClient private(weixinConf: WeixinQYConf, weixinApp: WeixinApp
)(implicit actorRefFactory: ActorRefFactory, ec: ExecutionContext, timeout: Timeout, format: Formats) extends StrictLogging {
implicit def json4sMarshaller[T <: AnyRef] =
Marshaller.delegate[T, String](ContentTypes.`application/json`)(Serialization.write(_))
implicit def umJValue: Unmarshaller[JValue] = Unmarshaller[JValue](MediaTypes.`application/json`) {
case x: HttpEntity.NonEmpty ⇒
try JsonMethods.parse(x.asString(defaultCharset = HttpCharsets.`UTF-8`))
catch {
case MappingException("unknown error", ite: InvocationTargetException) ⇒ throw ite.getCause
}
}
implicit def umErrorMessage: Unmarshaller[ErrMsg] = json4sUnmarshaller[ErrMsg]
implicit def umRespCreateDepartment: Unmarshaller[RespCreateDepartment] = json4sUnmarshaller[RespCreateDepartment]
implicit def umRespListDepartment: Unmarshaller[RespListDepartment] = json4sUnmarshaller[RespListDepartment]
implicit def umRespUser: Unmarshaller[RespUser] = json4sUnmarshaller[RespUser]
implicit def umRespUserDeptList: Unmarshaller[RespUserDeptList] = json4sUnmarshaller[RespUserDeptList]
implicit def umRespSendMessage: Unmarshaller[RespSendMessage] = json4sUnmarshaller[RespSendMessage]
implicit def umCustomMenu: Unmarshaller[CustomMenu] = json4sUnmarshaller[CustomMenu]
implicit def umRespCreateTag: Unmarshaller[RespCreateTag] = json4sUnmarshaller[RespCreateTag]
implicit def umRespTagUserList: Unmarshaller[RespTagUserList] = json4sUnmarshaller[RespTagUserList]
implicit def umRespDelTagUserList: Unmarshaller[RespDelTagUserList] = json4sUnmarshaller[RespDelTagUserList]
val pipelineJValue = sendReceive ~> unmarshal[JValue]
val pipelineErrorMessage = sendReceive ~> unmarshal[ErrMsg]
val pipelineRespCreateDepartment = sendReceive ~> unmarshal[RespCreateDepartment]
val pipelineRespListDepartment = sendReceive ~> unmarshal[RespListDepartment]
val pipelineRespUser = sendReceive ~> unmarshal[RespUser]
val pipelineRespUserDeptList = sendReceive ~> unmarshal[RespUserDeptList]
val pipelineMessageSend = sendReceive ~> unmarshal[RespSendMessage]
val pipelineCustomMenu = sendReceive ~> unmarshal[CustomMenu]
val pipelineRespTag = sendReceive ~> unmarshal[RespCreateTag]
val pipelineRespTagUserList = sendReceive ~> unmarshal[RespTagUserList]
val pipelineRespDelTagUserList = sendReceive ~> unmarshal[RespDelTagUserList]
def createTag(accessToken: String, tag: ReqCreateTag): Future[RespCreateTag] = {
val url = weixinConf.urls.tagCreate.format(accessToken)
pipelineRespTag(Post(url, tag))
}
def updateTag(accessToken: String, tag: ReqUpdateTag): Future[ErrMsg] = {
val url = weixinConf.urls.tagUpdate.format(accessToken)
pipelineErrorMessage(Post(url, tag))
}
def deleteTag(accessToken: String, tagId: Int): Future[ErrMsg] = {
val url = weixinConf.urls.tagDelete.format(accessToken, tagId)
println(url)
pipelineErrorMessage(Get(url))
}
def getTagUserList(accessToken: String, tagId: Int): Future[RespTagUserList] = {
val url = weixinConf.urls.tagGetUser.format(accessToken, tagId)
println(url)
pipelineRespTagUserList(Get(url))
}
def addTagUserList(accessToken: String, tag: ReqTagUserList): Future[ErrMsg] = {
val url = weixinConf.urls.tagAddUser.format(accessToken)
pipelineErrorMessage(Post(url, tag))
}
def delTagUserList(accessToken: String, tag: ReqTagUserList): Future[RespDelTagUserList] = {
val url = weixinConf.urls.tagDelUser.format(accessToken)
println(url)
pipelineRespDelTagUserList(Post(url, tag))
}
def getUserInfo(accessToken: String, code: String): Future[UserInfo] = {
val url = weixinConf.urls.userGetuserinfo.format(accessToken, code, weixinApp.id)
pipelineJValue(Get(url)).flatMap { jv =>
println(s"at: $accessToken, code: $code\njv: $jv")
jv \ "errcode" match {
case JInt(_) => Future.failed(MessageException(jv.extract[ErrMsg]))
case _ => Future.successful(jv.extract[UserInfo])
}
}
}
def createMenu(accessToken: String, menu: CustomMenu): Future[ErrMsg] = {
val url = weixinConf.urls.menuCreate.format(accessToken, weixinApp.id)
pipelineErrorMessage(Post(url, menu))
}
def deleteMenu(accessToken: String): Future[ErrMsg] = {
val url = weixinConf.urls.menuDelete.format(accessToken, weixinApp.id)
pipelineErrorMessage(Get(url))
}
def getMenu(accessToken: String): Future[CustomMenu] = {
val url = weixinConf.urls.menuGet.format(accessToken, weixinApp.id)
pipelineCustomMenu(Get(url))
}
def sendMessage(accessToken: String, entity: JValue): Future[RespSendMessage] = {
val url = weixinConf.urls.messageSend.format(accessToken)
logger.debug("sendMessage url: " + url)
pipelineMessageSend(Post(url, entity))
}
def createUser(accessToken: String, entity: ReqUser): Future[ErrMsg] = {
val url = weixinConf.urls.userCreate.format(accessToken)
pipelineErrorMessage(Post(url, entity))
}
def updateUser(accessToken: String, entity: ReqUser): Future[ErrMsg] = {
val url = weixinConf.urls.userUpdate.format(accessToken)
pipelineErrorMessage(Post(url, entity))
}
def deleteUser(accessToken: String, userId: String): Future[ErrMsg] = {
val url = weixinConf.urls.userDelete.format(accessToken, userId)
pipelineErrorMessage(Get(url))
}
def getUser(accessToken: String, userId: String): Future[RespUser] = {
val url = weixinConf.urls.userGet.format(accessToken, userId)
println("getUser url: " + url)
pipelineRespUser(Get(url))
}
def getUserDeptList(accessToken: String, deptId: Int, fetchChild: Int = 0, status: Int = 0): Future[RespUserDeptList] = {
val url = weixinConf.urls.userDeptList.format(accessToken, deptId, fetchChild, status)
pipelineRespUserDeptList(Get(url))
}
def updateDepartment(accessToken: String, entity: ReqUpdateDepartment): Future[ErrMsg] = {
val url = weixinConf.urls.departmentUpdate.format(accessToken)
pipelineErrorMessage(Post(url, entity))
}
def deleteDepartment(accessToken: String, deptId: Int): Future[ErrMsg] = {
val url = weixinConf.urls.departmentDelete.format(accessToken, deptId)
pipelineErrorMessage(Get(url))
}
def createDepartment(accessToken: String, entity: ReqCreateDepartment): Future[RespCreateDepartment] = {
val url = weixinConf.urls.departmentCreate.format(accessToken)
pipelineRespCreateDepartment(Post(url, entity))
}
def listDepartment(accessToken: String): Future[RespListDepartment] = {
val url = weixinConf.urls.departmentList.format(accessToken)
pipelineRespListDepartment(Get(url))
}
/**
* 获取access_token
* @return
*/
def getAccessToken: Future[AccessToken] = {
implicit val um = json4sUnmarshaller[JValue]
val url = weixinConf.urls.accessToken.format(weixinConf.corp_id, weixinApp.secret)
pipelineJValue(Get(url)).map { jv =>
jv.extractOpt[AccessToken] match {
case Some(at) =>
logger.debug("getAccessToken: " + at)
at
case None => throw MessageException(jv.extract[ErrMsg])
}
}.mapTo[AccessToken]
}
private def json4sUnmarshaller[T: Manifest] =
Unmarshaller[T](MediaTypes.`application/json`) {
case x: HttpEntity.NonEmpty ⇒
try {
val s = x.asString(defaultCharset = HttpCharsets.`UTF-8`)
println(s)
Serialization.read[T](s)
} catch {
case e: Exception =>
throw e;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment