/// <summary> /// 发送一次性订阅消息 /// </summary> /// <param name="accessToken"></param> /// <param name="openId"></param> /// <param name="templateId"></param> /// <param name="scene"></param> /// <param name="title"></param> /// <param name="value"></param> /// <param name="color"></param> /// <param name="url"></param> /// <param name="miniProgram"></param> /// <returns></returns> public string SendDisposableMessage(string accessToken, string openId, string templateId, int scene, string title, string value, string color = null, string url = null, MiniProgram miniProgram = null) { #region 参数验证 if (string.IsNullOrEmpty(accessToken)) { throw new ArgumentException("Access Token为空"); } if (string.IsNullOrEmpty(openId)) { throw new ArgumentException("接受者OpenId为空"); } if (string.IsNullOrWhiteSpace(templateId)) { throw new ArgumentException("模板Id为空"); } if (miniProgram != null && string.IsNullOrEmpty(miniProgram.AppId)) { throw new ArgumentException("小程序AppId为空"); } if (miniProgram != null && string.IsNullOrEmpty(miniProgram.PagePath)) { throw new ArgumentException("小程序跳转页面为空"); } if (string.IsNullOrEmpty(value)) { throw new ArgumentException("Value为空"); } if (string.IsNullOrEmpty(title)) { throw new ArgumentException("Title为空"); } #endregion IRestRequest request = new RestRequest("cgi-bin/message/template/subscribe", Method.POST); request.AddQueryParameter("access_token", accessToken); request.AddJsonBody(new { touser = openId, template_id = templateId, url = url, miniProgram = miniProgram == null ? null : miniProgram, scene = scene, title = title, data = new { content = new { value = value, color = color } } }); IRestResponse response = _restClient.Execute(request); Error err = JsonConvert.DeserializeObject <Error>(response.Content); if (err.errcode != 0) { throw new WeixinInterfaceException(err.errmsg); } return(err.errmsg); }
/// <summary> /// 发送模板消息 /// </summary> /// <param name="accessToken"></param> /// <param name="openId"></param> /// <param name="templateId"></param> /// <param name="data"></param> /// <param name="url"></param> /// <param name="miniProgram"></param> /// <returns></returns> public long SendTMessage(string accessToken, string openId, string templateId, Dictionary <string, TemplateData> data, string url = null, MiniProgram miniProgram = null) { #region 参数验证 if (string.IsNullOrEmpty(accessToken)) { throw new ArgumentException("Access Token为空"); } if (string.IsNullOrEmpty(openId)) { throw new ArgumentException("接受者OpenId为空"); } if (string.IsNullOrWhiteSpace(templateId)) { throw new ArgumentException("模板Id为空"); } if (miniProgram != null && string.IsNullOrEmpty(miniProgram.AppId)) { throw new ArgumentException("小程序AppId为空"); } if (miniProgram != null && string.IsNullOrEmpty(miniProgram.PagePath)) { throw new ArgumentException("小程序跳转页面为空"); } if (data == null || data.Count == 0) { throw new ArgumentException("Data为空"); } foreach (var item in data) { if (string.IsNullOrEmpty(item.Key)) { throw new ArgumentException("Data中存在为空的值"); } if (string.IsNullOrEmpty(item.Value.Value)) { throw new ArgumentException($"{item.Key}的值为空"); } } #endregion #region 组装Json string jsonStr = string.Empty; jsonStr += $"{{"; jsonStr += $"\"touser\": \"{openId}\","; jsonStr += $"\"template_id\": \"{templateId}\","; jsonStr += $"\"url\": \"{url ?? ""}\","; if (miniProgram != null) { jsonStr += $"\"miniprogram\": {{"; jsonStr += $"\"appid\": \"{(miniProgram == null ? "" : miniProgram.AppId)}\","; jsonStr += $"\"pagepath\": \"{(miniProgram == null ? "" : miniProgram.PagePath)}\""; jsonStr += $"}},"; } jsonStr += $"\"data\": {{"; foreach (var item in data) { jsonStr += $"\"{item.Key}\": {{"; jsonStr += $"\"value\": \"{item.Value.Value}\","; jsonStr += $"\"color\": \"{item.Value.Color ?? ""}\""; jsonStr += $"}},"; } if (jsonStr.EndsWith(",")) { jsonStr = jsonStr.Remove(jsonStr.Length - 1, 1); } jsonStr += $"}}"; jsonStr += $"}}"; #endregion IRestRequest request = new RestRequest("cgi-bin/message/template/send", Method.POST); request.AddHeader("Accept", "application/json"); request.Parameters.Clear(); request.AddQueryParameter("access_token", accessToken); request.AddParameter("application/json", jsonStr, ParameterType.RequestBody); IRestResponse response = _restClient.Execute(request); Error err = JsonConvert.DeserializeObject <Error>(response.Content); if (err.errcode != 0) { throw new WeixinInterfaceException(err.errmsg); } TMessageId tMessageId = JsonConvert.DeserializeObject <TMessageId>(response.Content); return(tMessageId.msgid); }
protected virtual async Task RemoveMiniProgramUserAsync(IdentityUser identityUser, MiniProgram miniProgram) { var mpUserMapping = await _miniProgramUserRepository.GetAsync(x => x.MiniProgramId == miniProgram.Id && x.UserId == identityUser.Id); await _miniProgramUserRepository.DeleteAsync(mpUserMapping, true); }
protected virtual async Task UpdateMiniProgramUserAsync(IdentityUser identityUser, MiniProgram miniProgram, string unionId, string openId, string sessionKey) { var mpUserMapping = await _miniProgramUserRepository.FindAsync(x => x.MiniProgramId == miniProgram.Id && x.UserId == identityUser.Id); if (mpUserMapping == null) { mpUserMapping = new MiniProgramUser(GuidGenerator.Create(), CurrentTenant.Id, miniProgram.Id, identityUser.Id, unionId, openId); await _miniProgramUserRepository.InsertAsync(mpUserMapping, true); } else { mpUserMapping.SetOpenId(openId); mpUserMapping.SetUnionId(unionId); mpUserMapping.UpdateSessionKey(sessionKey, Clock); await _miniProgramUserRepository.UpdateAsync(mpUserMapping, true); } }
protected virtual async Task <LoginResultInfoModel> GetLoginResultAsync(MiniProgram miniProgram, LoginInput input) { var code2SessionResponse = await _loginService.Code2SessionAsync(miniProgram.AppId, miniProgram.AppSecret, input.Code); _signatureChecker.Check(input.RawData, code2SessionResponse.SessionKey, input.Signature); var openId = code2SessionResponse.OpenId; var unionId = code2SessionResponse.UnionId; if (input.LookupUseRecentlyTenant) { Guid?tenantId; using (_dataFilter.Disable <IMultiTenant>()) { tenantId = await _miniProgramUserRepository.FindRecentlyTenantIdAsync(miniProgram.Id, openId); } using var tenantChange = CurrentTenant.Change(tenantId); } // 如果 auth.code2Session 没有返回用户的 UnionId if (unionId.IsNullOrWhiteSpace()) { if (!input.EncryptedData.IsNullOrWhiteSpace() && !input.Iv.IsNullOrWhiteSpace()) { // 方法1:通过 EncryptedData 和 Iv 解密获得用户的 UnionId var decryptedData = _jsonSerializer.Deserialize <Dictionary <string, object> >( AesHelper.AesDecrypt(input.EncryptedData, input.Iv, code2SessionResponse.SessionKey)); unionId = decryptedData.GetOrDefault("unionId") as string; } else { // 方法2:尝试通过 OpenId 在 MiniProgramUser 实体中查找用户的 UnionId // Todo: should use IMiniProgramUserStore unionId = await _miniProgramUserRepository.FindUnionIdByOpenIdAsync(miniProgram.Id, openId); } } string loginProvider; string providerKey; if (unionId.IsNullOrWhiteSpace()) { loginProvider = await _miniProgramLoginProviderProvider.GetAppLoginProviderAsync(miniProgram); providerKey = openId; } else { loginProvider = await _miniProgramLoginProviderProvider.GetOpenLoginProviderAsync(miniProgram); providerKey = unionId; } return(new LoginResultInfoModel { LoginProvider = loginProvider, ProviderKey = providerKey, Code2SessionResponse = code2SessionResponse }); }
public Task <Message> Say(MiniProgram miniProgram, params Contact[]?replyTo) { throw new NotImplementedException(); }
public virtual Task <string> GetOpenLoginProviderAsync(MiniProgram miniProgram) { Check.NotNullOrWhiteSpace(miniProgram.OpenAppIdOrName, nameof(miniProgram.OpenAppIdOrName)); return(Task.FromResult(WeChatOpenLoginProviderPrefix + miniProgram.OpenAppIdOrName)); }