Selenium c# w/ 2Captcha Recaptcha v2 - c#

So the website requires a captcha fill out in-order to login.
I'm using C# winforms and Selenium Webdrivers along with 2Captcha's API
Here's the code I got to send the request to 2Captcha's
public string SendCaptcha(string APIKey,string GoogleKey,string PageURL)
{
#region Captcha Solve
try
{
#region POST
System.Net.ServicePointManager.Expect100Continue = false;
var request = (HttpWebRequest)WebRequest.Create("http://2captcha.com/in.php");
var postData = "key="+APIKey+"&method=userrecaptcha&googlekey="+GoogleKey+"&pageurl="+PageURL;
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
#endregion
#region GET
if (responseString.Contains("OK|"))
{
string results = responseString.Replace("OK|", "");
return results;
}
else
{
return "Error";
}
#endregion
}
catch (Exception e)
{
string tt = e.Message;
return tt;
}
#endregion
}
Here's the code i got to get the solved captcha ID from 2Captcha
public string GetAnswer(string result,string APIKey)
{
#region Captcha Solve
try
{
#region POST
System.Net.ServicePointManager.Expect100Continue = false;
var request = (HttpWebRequest)WebRequest.Create("http://2captcha.com/res.php");
var postData = "key="+APIKey+"&action=get&id="+result;
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
#endregion
#region GET
if (responseString.Contains("OK|"))
{
string results = responseString.Replace("OK|", "");
return results;
}
else
{
return "Error";
}
#endregion
}
catch (Exception e)
{
string tt = e.Message;
return tt;
}
#endregion
}
And here is the login/Captcha thing
EHtvdrive.Url = "http://earnhoney.com";
EHtvdrive.FindElementByXPath("//*[#id='regorlogdiv']").Click();
Thread.Sleep(5000);
EHtvdrive.FindElementByXPath("//*[#id='email']").SendKeys(textBox4.Text);
EHtvdrive.FindElementByXPath("//*[#id='psswrd']").SendKeys(textBox3.Text);
label16.Invoke((MethodInvoker)delegate { label16.Text = "Solving Captcha."; });
label16.Invoke((MethodInvoker)delegate { label16.ForeColor = Color.Orange; });
string datakey = EHtvdrive.FindElementByXPath("//[#id='reCAPReg']").GetAttribute("data-sitekey");
string result = SendCaptcha(textBox5.Text, datakey, "http://www.earnhoney.com/en");
Thread.Sleep(60000);
string answer = GetAnswer(result, textBox5.Text);
IJavaScriptExecutor js = (IJavaScriptExecutor)EHtvdrive;
string title = (string)js.ExecuteScript("document.getElementById('g-recaptcha-response').innerHTML='" + answer + "';");
//MessageBox.Show(answer);
Thread.Sleep(3000);
EHtvdrive.FindElementById("loginbtn").Click();
Thread.Sleep(3000);
So the problem is that it gives me the Error return on the GetAnswer. Any help here? I know this is pretty complicated but really could use some help on this.

Related

strava login via httpwebrequest failed

Hi I'm trying to login via https://www.strava.com/session with HttpWebrequest but it doesn't log me in. It gives me an response of 302 which is good but it never redirect me to https://www.strava.com/dashboard.
this is the code that I'm using
Httpclient:
public class HttpClient
{
private const string UserAgent = "Mozilla/5.0";
public CookieCollection CookieCollection;
public HttpWebRequest WebRequest;
public HttpWebResponse WebResponse;
public int code { get; set; }
public string location { get; set; }
public string PostData(string url, string postData, string refer = "")
{
WebRequest = (HttpWebRequest)System.Net.WebRequest.Create(url);
WebRequest.UserAgent = UserAgent;
WebRequest.Referer = refer;
WebRequest.AllowAutoRedirect =false;
WebRequest.Timeout = 10000;
WebRequest.KeepAlive = true;
WebRequest.CookieContainer = new CookieContainer();
if (CookieCollection != null && CookieCollection.Count > 0)
{
WebRequest.CookieContainer.Add(CookieCollection);
}
WebRequest.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
WebRequest.Method = "POST";
try
{
var postBytes = Encoding.UTF8.GetBytes(postData);
WebRequest.ContentLength = postBytes.Length;
var postDataStream = WebRequest.GetRequestStream();
postDataStream.Write(postBytes, 0, postBytes.Length);
postDataStream.Close();
try
{
WebResponse = (HttpWebResponse)WebRequest.GetResponse();
this.code = (int)WebResponse.StatusCode;
this.location = WebResponse.Headers["Location"];
if (WebResponse.StatusCode == HttpStatusCode.OK ||WebResponse.StatusCode == HttpStatusCode.Redirect)
{
WebResponse.Cookies = WebRequest.CookieContainer.GetCookies(WebRequest.RequestUri);
if (WebResponse.Cookies.Count > 0)
{
if (CookieCollection == null)
{
CookieCollection = WebResponse.Cookies;
}
else
{
foreach (Cookie oRespCookie in WebResponse.Cookies)
{
var bMatch = false;
foreach (
var oReqCookie in
CookieCollection.Cast<Cookie>()
.Where(oReqCookie => oReqCookie.Name == oRespCookie.Name))
{
oReqCookie.Value = oRespCookie.Value;
bMatch = true;
break;
}
if (!bMatch)
CookieCollection.Add(oRespCookie);
}
}
}
var reader = new StreamReader(WebResponse.GetResponseStream());
var responseString = reader.ReadToEnd();
reader.Close();
return responseString;
}
}
catch (WebException wex)
{
if (wex.Response != null)
{
using (var errorResponse = (HttpWebResponse)wex.Response)
{
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
var error = reader.ReadToEnd();
return error;
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return "Error in posting data" ;
}
public string GetData(string url, string post = "")
{
var responseStr = string.Empty;
WebRequest = (HttpWebRequest)System.Net.WebRequest.Create(url);
WebRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8";
WebRequest.Method = "GET";
WebRequest.KeepAlive = true;
WebRequest.Credentials = CredentialCache.DefaultCredentials;
WebRequest.UserAgent = UserAgent;
WebRequest.CookieContainer = new CookieContainer();
if (CookieCollection != null && CookieCollection.Count > 0)
{
WebRequest.CookieContainer.Add(CookieCollection);
}
if (!string.IsNullOrEmpty(post))
{
var postBytes = Encoding.UTF8.GetBytes(post);
WebRequest.ContentLength = postBytes.Length;
var postDataStream = WebRequest.GetRequestStream();
postDataStream.Write(postBytes, 0, postBytes.Length);
postDataStream.Close();
}
WebResponse wresp = null;
try
{
wresp = WebRequest.GetResponse();
var downStream = wresp.GetResponseStream();
if (downStream != null)
{
using (var downReader = new StreamReader(downStream))
{
responseStr = downReader.ReadToEnd();
}
}
return responseStr;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
if (wresp != null)
{
wresp.Close();
wresp = null;
}
}
finally
{
WebRequest = null;
}
return responseStr;
}
}
Getting crfs-token:
private string GetToken()
{
string token = "";
String sourcestring = hc.GetData(loginURL);
Regex metaTag = new Regex(#"<meta[\s]+[^>]*?name[\s]?=[\s""']+(.*?)[\s""']+content[\s]?=[\s""']+(.*?)[""']+.*?>");
foreach (Match m in metaTag.Matches(sourcestring))
{
if (m.Groups[2].Value.Contains("token"))
{
continue;
}
token = m.Groups[2].Value;
}
return token;
}
Custom keyvaluepair
private string PostParam(Dictionary<string, string> data)
{
var sb = new StringBuilder();
var p = new List<string>();
foreach (KeyValuePair<string, string> pair in data)
{
sb.Clear();
sb.Append(pair.Key).Append("=").Append(pair.Value);
p.Add(sb.ToString());
}
var pp = string.Join("&", p);
return pp;
}
Login:
private HttpClient hc = new HttpClient();
Dictionary data = new Dictionary();
data.Add("utf8", "✓");
data.Add("authenticity_token", GetToken());
data.Add("plan", "");
data.Add("email", "email");
data.Add("password", "password");
hc.PostData(sessionURL,WebUtility.UrlEncode(PostParam(data)), loginURL);
Can someone tell me what I'm doing wrong? if I look the request header when trying to login to strava in browser its the same but still it doesn't log me.
I found the problem.
You need to encode only the token (and the UTF8 character), not the full post data.
This works for me (for some reason I need to run the code two times)
// First time says "logged out"
Dictionary<string, string> data = new Dictionary<string, string>();
data.Add("utf8", WebUtility.UrlEncode("✓"));
string token = GetToken();
string tokenEncoded = WebUtility.UrlEncode(token);
data.Add("authenticity_token", tokenEncoded);
data.Add("plan", "");
data.Add("email", "youremail");
data.Add("password", "yourpwd");
data.Add("remember_me", "on");
string parameters = PostParam(data);
hc.PostData(sessionURL, parameters, loginURL);
// Second time logs in
Dictionary<string, string> data = new Dictionary<string, string>();
data.Add("utf8", WebUtility.UrlEncode("✓"));
string token = GetToken();
string tokenEncoded = WebUtility.UrlEncode(token);
data.Add("authenticity_token", tokenEncoded);
data.Add("plan", "");
data.Add("email", "youremail");
data.Add("password", "yourpwd");
data.Add("remember_me", "on");
string parameters = PostParam(data);
hc.PostData(sessionURL, parameters, loginURL);
Note:
// Keep this on default value "true"
//WebRequest.AllowAutoRedirect = false;
remark: you can use this code (see my previous post) to change activity's status (privacy) after logging in:
Dictionary<string, string> data2 = new Dictionary<string, string>();
data2.Add("utf8", WebUtility.UrlEncode("✓"));
string token2 = GetToken();
string tokenEncoded2 = WebUtility.UrlEncode(token2);
data2.Add("_method", "patch");
data2.Add("authenticity_token", tokenEncoded2);
data2.Add("activity%5Bvisibility%5D", "only_me"); // or "followers_only"
string parameters2 = PostParam(data2);
hc.PostData("https://www.strava.com/activities/youractivityID", parameters2, loginURL);

I am trying to write a console app in c# that consume a web service running on tomcat, to perform a "PUT" method with an xml file

public static String TransferMessage(String uri, String resource,
String xml_data, Method httpmethod,
ReturnType returnType)
{
try
{
WebRequest request = WebRequest.Create(uri + resource);
request.Method = httpmethod.ToString();
request.ContentType = #"application/xml;";
//request.Headers.Add("Token", token);
request.Timeout = Convert.ToInt32((new TimeSpan(1, 0, 0)).TotalMilliseconds);
request.ContentLength = Encoding.UTF8.GetByteCount(xml_data);
if (httpmethod != Method.GET)
using (Stream stream = request.GetRequestStream())
{
stream.Write(Encoding.UTF8.GetBytes(xml_data), 0,
Encoding.UTF8.GetByteCount(xml_data));
stream.Flush();
stream.Close();
}
return getResponseContent(request.GetResponse());
}
catch(Exception e)
{
Console.WriteLine(e);
}
return null;
}
Main method:
var res_xml = MethodHelper.TransferMessage(endpoint, "/" + resource,xml,
MethodHelper.Method.PUT,
MethodHelper.ReturnType.XML);
I am getting this error
ERROR javax.xml.bind.UnmarshalException\n - with
linked exception:\n[org.xml.sax.SAXParseException; line Number: 1;
columnNumber: 1; Content is not allowed in prolog.]
try{
string contend = "";
using (var streamReader = new StreamReader(new FileInfo(#"C:\Users\absmbez\Desktop\temp\upload.xml").OpenRead()))
{
contend = streamReader.ReadToEnd();
}
HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(url);
webrequest.Method = "PUT";
webrequest.ContentType = "application/xml";
Encoding enc = System.Text.Encoding.GetEncoding("utf-8");
byte[] requestData = enc.GetBytes(contend);
webrequest.ContentLength = requestData.Length;
using (var stream = webrequest.GetRequestStream())
{
stream.Write(requestData, 0, requestData.Length);
}
HttpWebResponse webresponse = (HttpWebResponse)webrequest.GetResponse();
StreamReader responseStream = new StreamReader(webresponse.GetResponseStream(), enc);
string result = string.Empty;
result = responseStream.ReadToEnd();
webresponse.Close();
return result;
}
catch (Exception e)
{
Console.WriteLine(e);
}

Get detailed error information on creating httpwebrequest from c# to website

I am checking a website is active or not using below code. If website is inactive like screen shot. I want to log the detailed error information from the response. how can i do it..? please suggest..
private static bool CheckWebSiteActive()
{
bool isWebSiteActive = false;
try
{
StreamReader sr = null;
Stream resst = null;
HttpWebResponse response = null;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(ConfigurationManager.AppSettings["webSiteToCheck"]);
request.Timeout = 10000;
request.AllowAutoRedirect = false; // find out if this site is up and don't follow a redirector
request.Method = "HEAD";
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (WebException we)
{
using (WebResponse Wresponse = we.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)Wresponse;
Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
using (Stream data = Wresponse.GetResponseStream())
{
string text = new StreamReader(data).ReadToEnd();
Console.WriteLine(text);
}
}
//response = (HttpWebResponse)we.Response;
//resst = response.GetResponseStream();
//sr = new StreamReader(resst);
log.Error(sr.ReadToEnd());
}
isWebSiteActive = ((int)response.StatusCode == 200 && response.StatusCode == HttpStatusCode.OK) ? true : false;
}catch(Exception Ex)
{
log.Error(Ex.Message.ToString());
}
return isWebSiteActive;
}
Thanks in adv.

Send push to Android by C# using FCM (Firebase Cloud Messaging)

I am using this code to send notification message by C# with GCM, using Winforms, Webforms, whatever. Now I want to send to FCM (Firebase Cloud Messaging). Should I update my code? :
public class AndroidGCMPushNotification
{
public AndroidGCMPushNotification()
{
//
// TODO: Add constructor logic here
//
}
public string SendNotification(string deviceId, string message)
{
string SERVER_API_KEY = "server api key";
var SENDER_ID = "application number";
var value = message;
WebRequest tRequest;
tRequest = WebRequest.Create("https://android.googleapis.com/gcm/send");
tRequest.Method = "post";
tRequest.ContentType = " application/x-www-form-urlencoded;charset=UTF-8";
tRequest.Headers.Add(string.Format("Authorization: key={0}", SERVER_API_KEY));
tRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));
string postData = "collapse_key=score_update&time_to_live=108&delay_while_idle=1&data.message=" + value + "&data.time=" + System.DateTime.Now.ToString() + "&registration_id=" + deviceId + "";
Console.WriteLine(postData);
Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
tRequest.ContentLength = byteArray.Length;
Stream dataStream = tRequest.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse tResponse = tRequest.GetResponse();
dataStream = tResponse.GetResponseStream();
StreamReader tReader = new StreamReader(dataStream);
String sResponseFromServer = tReader.ReadToEnd();
tReader.Close();
dataStream.Close();
tResponse.Close();
return sResponseFromServer;
}
}
but the GCM was changed to FCM. Is this same code to send the notification?
Where can I find the SERVER_API_KEY? Is the same solution?
firebase cloud messaging with c#:
working all .net platform (asp.net, .netmvc, .netcore)
WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
//serverKey - Key from Firebase cloud messaging server
tRequest.Headers.Add(string.Format("Authorization: key={0}", "AIXXXXXX...."));
//Sender Id - From firebase project setting
tRequest.Headers.Add(string.Format("Sender: id={0}", "XXXXX.."));
tRequest.ContentType = "application/json";
var payload = new
{
to = "e8EHtMwqsZY:APA91bFUktufXdsDLdXXXXXX..........XXXXXXXXXXXXXX",
priority = "high",
content_available = true,
notification = new
{
body = "Test",
title = "Test",
badge = 1
},
data = new
{
key1 = "value1",
key2 = "value2"
}
};
string postbody = JsonConvert.SerializeObject(payload).ToString();
Byte[] byteArray = Encoding.UTF8.GetBytes(postbody);
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
{
if (dataStreamResponse != null) using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
//result.Response = sResponseFromServer;
}
}
}
}
Here is another approach of writing Notification Service inside ASP.Net REST API.
public async Task<bool> NotifyAsync(string to, string title, string body)
{
try
{
// Get the server key from FCM console
var serverKey = string.Format("key={0}", "Your server key - use app config");
// Get the sender id from FCM console
var senderId = string.Format("id={0}", "Your sender id - use app config");
var data = new
{
to, // Recipient device token
notification = new { title, body }
};
// Using Newtonsoft.Json
var jsonBody = JsonConvert.SerializeObject(data);
using (var httpRequest = new HttpRequestMessage(HttpMethod.Post, "https://fcm.googleapis.com/fcm/send"))
{
httpRequest.Headers.TryAddWithoutValidation("Authorization", serverKey);
httpRequest.Headers.TryAddWithoutValidation("Sender", senderId);
httpRequest.Content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
using (var httpClient = new HttpClient())
{
var result = await httpClient.SendAsync(httpRequest);
if (result.IsSuccessStatusCode)
{
return true;
}
else
{
// Use result.StatusCode to handle failure
// Your custom error handler here
_logger.LogError($"Error sending notification. Status Code: {result.StatusCode}");
}
}
}
}
catch (Exception ex)
{
_logger.LogError($"Exception thrown in Notify Service: {ex}");
}
return false;
}
References:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
I have posted this answer as this question was viewed most and this server side code was written in VS 2015 in C# for sending push notification either single device based on device id or subscribed topic to Xamarin Android app
public class FCMPushNotification
{
public FCMPushNotification()
{
// TODO: Add constructor logic here
}
public bool Successful
{
get;
set;
}
public string Response
{
get;
set;
}
public Exception Error
{
get;
set;
}
public FCMPushNotification SendNotification(string _title, string _message, string _topic)
{
FCMPushNotification result = new FCMPushNotification();
try
{
result.Successful = true;
result.Error = null;
// var value = message;
var requestUri = "https://fcm.googleapis.com/fcm/send";
WebRequest webRequest = WebRequest.Create(requestUri);
webRequest.Method = "POST";
webRequest.Headers.Add(string.Format("Authorization: key={0}", YOUR_FCM_SERVER_API_KEY));
webRequest.Headers.Add(string.Format("Sender: id={0}", YOUR_FCM_SENDER_ID));
webRequest.ContentType = "application/json";
var data = new
{
// to = YOUR_FCM_DEVICE_ID, // Uncoment this if you want to test for single device
to="/topics/"+_topic, // this is for topic
notification=new
{
title=_title,
body=_message,
//icon="myicon"
}
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
webRequest.ContentLength = byteArray.Length;
using (Stream dataStream = webRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse webResponse = webRequest.GetResponse())
{
using (Stream dataStreamResponse = webResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
result.Response = sResponseFromServer;
}
}
}
}
}
catch(Exception ex)
{
result.Successful = false;
result.Response = null;
result.Error = ex;
}
return result;
}
}
and its uses
// start sending push notification to apps
FCMPushNotification fcmPush = new FCMPushNotification();
fcmPush.SendNotification("your notificatin title", "Your body message","news");
// end push notification
Yes, you should update your code to use Firebase Messaging interface.
There's a GitHub Project for that here.
using Stimulsoft.Base.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
namespace _WEBAPP
{
public class FireBasePush
{
private string FireBase_URL = "https://fcm.googleapis.com/fcm/send";
private string key_server;
public FireBasePush(String Key_Server)
{
this.key_server = Key_Server;
}
public dynamic SendPush(PushMessage message)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(FireBase_URL);
request.Method = "POST";
request.Headers.Add("Authorization", "key=" + this.key_server);
request.ContentType = "application/json";
string json = JsonConvert.SerializeObject(message);
//json = json.Replace("content_available", "content-available");
byte[] byteArray = Encoding.UTF8.GetBytes(json);
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
HttpWebResponse respuesta = (HttpWebResponse)request.GetResponse();
if (respuesta.StatusCode == HttpStatusCode.Accepted || respuesta.StatusCode == HttpStatusCode.OK || respuesta.StatusCode == HttpStatusCode.Created)
{
StreamReader read = new StreamReader(respuesta.GetResponseStream());
String result = read.ReadToEnd();
read.Close();
respuesta.Close();
dynamic stuff = JsonConvert.DeserializeObject(result);
return stuff;
}
else
{
throw new Exception("Ocurrio un error al obtener la respuesta del servidor: " + respuesta.StatusCode);
}
}
}
public class PushMessage
{
private string _to;
private PushMessageData _notification;
private dynamic _data;
private dynamic _click_action;
public dynamic data
{
get { return _data; }
set { _data = value; }
}
public string to
{
get { return _to; }
set { _to = value; }
}
public PushMessageData notification
{
get { return _notification; }
set { _notification = value; }
}
public dynamic click_action
{
get
{
return _click_action;
}
set
{
_click_action = value;
}
}
}
public class PushMessageData
{
private string _title;
private string _text;
private string _sound = "default";
//private dynamic _content_available;
private string _click_action;
public string sound
{
get { return _sound; }
set { _sound = value; }
}
public string title
{
get { return _title; }
set { _title = value; }
}
public string text
{
get { return _text; }
set { _text = value; }
}
public string click_action
{
get
{
return _click_action;
}
set
{
_click_action = value;
}
}
}
}
Based on Teste's code .. I can confirm the following works. I can't say whether or not this is "good" code, but it certainly works and could get you back up and running quickly if you ended up with GCM to FCM server problems!
public AndroidFCMPushNotificationStatus SendNotification(string serverApiKey, string senderId, string deviceId, string message)
{
AndroidFCMPushNotificationStatus result = new AndroidFCMPushNotificationStatus();
try
{
result.Successful = false;
result.Error = null;
var value = message;
WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
tRequest.Headers.Add(string.Format("Authorization: key={0}", serverApiKey));
tRequest.Headers.Add(string.Format("Sender: id={0}", senderId));
string postData = "collapse_key=score_update&time_to_live=108&delay_while_idle=1&data.message=" + value + "&data.time=" + System.DateTime.Now.ToString() + "&registration_id=" + deviceId + "";
Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
result.Response = sResponseFromServer;
}
}
}
}
}
catch (Exception ex)
{
result.Successful = false;
result.Response = null;
result.Error = ex;
}
return result;
}
public class AndroidFCMPushNotificationStatus
{
public bool Successful
{
get;
set;
}
public string Response
{
get;
set;
}
public Exception Error
{
get;
set;
}
}
You need change url from https://android.googleapis.com/gcm/send to https://fcm.googleapis.com/fcm/send and change your app library too. this tutorial can help you https://firebase.google.com/docs/cloud-messaging/server#implementing-http-connection-server-protocol
Try to send a json object.
Replace this:
tRequest.ContentType = " application/x-www-form-urlencoded;charset=UTF-8";
string postData = "collapse_key=score_update&time_to_live=108&delay_while_idle=1&data.message=" + value + "&data.time=" + System.DateTime.Now.ToString() + "&registration_id=" + deviceId + "";
Console.WriteLine(postData);
Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
For this:
tRequest.ContentType = "application/json";
var data = new
{
to = deviceId,
notification = new
{
body = "This is the message",
title = "This is the title",
icon = "myicon"
}
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
Here's the code for server side firebase cloud request from C# / Asp.net.
Please note that your client side should have same topic.
e.g.
FirebaseMessaging.getInstance().subscribeToTopic("news");
public String SendNotificationFromFirebaseCloud()
{
var result = "-1";
var webAddr = "https://fcm.googleapis.com/fcm/send";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(webAddr);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Headers.Add("Authorization:key=" + YOUR_FIREBASE_SERVER_KEY);
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"to\": \"/topics/news\",\"data\": {\"message\": \"This is a Firebase Cloud Messaging Topic Message!\",}}";
streamWriter.Write(json);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
return result;
}
You can use this library, makes it seamless to send push notifications using Firebase Service from a C# backend download here
public SendNotice(int deviceType, string deviceToken, string message, int badge, int status, string sound)
{
AndroidFCMPushNotificationStatus result = new AndroidFCMPushNotificationStatus();
try
{
result.Successful = false;
result.Error = null;
var value = message;
WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
var serializer = new JavaScriptSerializer();
var json = "";
tRequest.Headers.Add(string.Format("Authorization: key={0}", "AA******"));
tRequest.Headers.Add(string.Format("Sender: id={0}", "11********"));
if (DeviceType == 2)
{
var body = new
{
to = deviceToken,
data = new
{
custom_notification = new
{
title = "Notification",
body = message,
sound = "default",
priority = "high",
show_in_foreground = true,
targetScreen = notificationType,//"detail",
},
},
priority = 10
};
json = serializer.Serialize(body);
}
else
{
var body = new
{
to = deviceToken,
content_available = true,
notification = new
{
title = "Notification",
body = message,
sound = "default",
show_in_foreground = true,
},
data = new
{
targetScreen = notificationType,
id = 0,
},
priority = 10
};
json = serializer.Serialize(body);
}
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
result.Response = sResponseFromServer;
}
}
}
}
}
catch (Exception ex)
{
result.Successful = false;
result.Response = null;
result.Error = ex;
}
}
I write this code and It's worked for me .
public static string ExcutePushNotification(string title, string msg, string fcmToken, object data)
{
var serverKey = "AAAA*******************";
var senderId = "3333333333333";
var result = "-1";
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://fcm.googleapis.com/fcm/send");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Headers.Add(string.Format("Authorization: key={0}", serverKey));
httpWebRequest.Headers.Add(string.Format("Sender: id={0}", senderId));
httpWebRequest.Method = "POST";
var payload = new
{
notification = new
{
title = title,
body = msg,
sound = "default"
},
data = new
{
info = data
},
to = fcmToken,
priority = "high",
content_available = true,
};
var serializer = new JavaScriptSerializer();
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = serializer.Serialize(payload);
streamWriter.Write(json);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
return result;
}
I am using this approach and it is working fine:
public class PushNotification
{
private static readonly ILog Logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
// firebase
private static Uri FireBasePushNotificationsURL = new Uri("https://fcm.googleapis.com/fcm/send");
private static string ServerKey = ConfigurationManager.AppSettings["FIREBASESERVERKEY"];
public static async Task<bool> SendPushNotification(List<SendNotificationModel> notificationData)
{
try
{
bool sent = false;
foreach (var data in notificationData)
{
var messageInformation = new Message()
{
notification = new Notification()
{
title = data.Title,
text = data.Message,
ClickAction = "FCM_PLUGIN_ACTIVITY"
},
data = data.data,
priority="high",
to =data.DeviceId
};
string jsonMessage = JsonConvert.SerializeObject(messageInformation);
//Create request to Firebase API
var request = new HttpRequestMessage(HttpMethod.Post, FireBasePushNotificationsURL);
request.Headers.TryAddWithoutValidation("Authorization", "key=" + ServerKey);
request.Content = new StringContent(jsonMessage, Encoding.UTF8, "application/json");
HttpResponseMessage result;
using (var client = new HttpClient())
{
result = await client.SendAsync(request);
sent = result.IsSuccessStatusCode;
}
}
return sent;
}
catch(Exception ex)
{
Logger.Error(ex);
return false;
}
}
}
Following Approach, I have used for writing Firebase Notification Service inside ASP.Net REST API.
public async Task<bool> NotifyAsync(string to, string title, string body)
{
try
{
//Server key from FCM console
var serverKey = string.Format("key={0}", "Provide your Server key here from Fibase console");
//Sender id from FCM console
var senderId = string.Format("id={0}", "Provide your Sender Id here from Firebase Console");
var data = new
{
to, // Recipient device token
notification = new { title, body }
};
// Using Newtonsoft.Json
var jsonBody = JsonConvert.SerializeObject(data);
using (var httpRequest = new HttpRequestMessage(HttpMethod.Post, "https://fcm.googleapis.com/fcm/send"))
{
httpRequest.Headers.TryAddWithoutValidation("Authorization", serverKey);
httpRequest.Headers.TryAddWithoutValidation("Sender", senderId);
httpRequest.Content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
using (var httpClient = new HttpClient())
{
var result = await httpClient.SendAsync(httpRequest);
if (result.IsSuccessStatusCode)
{
return true;
}
else
{
// Use result.StatusCode to handle failure
// Your custom error handler here
return false;
}
}
}
}
catch (Exception ex)
{
throw ex;
}
return false;
}
Refer This blog for send Group Notification
https://firebase.google.com/docs/cloud-messaging/android/send-multiple

HttpWebRequest BeginGetResponse not working

I'm trying use HttpWebRequest, and my BeginGetRequestStream works but it never enters the BeginGetResponse function and i have no idea why.. i've searched for a couple of hours and have not found a solution that works
public void Initialize(IScheduler scheduler)
{
if(_isCloud)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_cloudMappingServer + "/Mapping/GetAllCentralPoints");
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.BeginGetRequestStream(new AsyncCallback(ReleaseReadCallback), request);
// Instruct the thread to wait until we resume it
_waitHandle.WaitOne();
_waitHandle.Dispose();
}
}
private void ReleaseReadCallback(IAsyncResult asynchronousResult)
{
try
{
HttpWebRequest httpRequest = (HttpWebRequest)asynchronousResult.AsyncState;
using (Stream postStream = httpRequest.EndGetRequestStream(asynchronousResult))
{
using (MemoryStream memStream = new MemoryStream())
{
string queryString = string.Empty;
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(queryString);
memStream.Write(bytes, 0, bytes.Length);
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
postStream.Write(tempBuffer, 0, tempBuffer.Length);
}
}
httpRequest.BeginGetResponse(new AsyncCallback(ReleaseResponseCallback), httpRequest);
}
catch (Exception ex)
{
var test = ex;
}
}
private void ReleaseResponseCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest responseRequest = (HttpWebRequest)asynchronousResult.AsyncState;
string responseString = string.Empty;
try
{
using (HttpWebResponse resp = (HttpWebResponse)responseRequest.EndGetResponse(asynchronousResult))
{
using (StreamReader streamRead = new StreamReader(resp.GetResponseStream()))
{
responseString = streamRead.ReadToEnd();
try
{
JsonSerializerSettings settings = new JsonSerializerSettings();
List<CentralPointViewModel> _allCentralPointViewModel = JsonConvert.DeserializeObject<List<CentralPointViewModel>>(responseString, settings);
}
catch (JsonReaderException)
{
responseString = responseString.Replace('\"'.ToString(), string.Empty);
string[] responseArray = responseString.Split(';');
}
catch (JsonSerializationException)
{
responseString = responseString.Replace('\"'.ToString(), string.Empty);
}
}
}
}
catch (Exception ex)
{
}
}
It never enters the ReleaseResponseCallback function! I am able to make my server call but the response never reaches me or I am not properly receiving it.. Any help is appreciated

Categories

Resources