Created
December 9, 2014 15:11
-
-
Save yangbajing/eb1f4453b7dbaa600def to your computer and use it in GitHub Desktop.
spray-client示例
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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