Facebook Graph API {id}/feed?limit=x - restrict to messages since a certain message id - c#

I have a small problem, I am working on an aggregation application that is collecting messages from pages in realtime.
This is working fine, but I get the same message on every call and then filter out the messages that I have already seen manually.
This means that a large amount of data is being transferred every time I make a call to the graph api.
Is there a way to limit the message as messages since this message id?
currently using the c# Facebook SDK
var fb = new FacebookClient("access_token");
dynamic parameters = new ExpandoObject();
parameters.limit = _facebookMessagesToRetrieveAtATime.ToString(CultureInfo.InvariantCulture);
//Want to add a new param here to say messages since this id.
var facebookUrl = String.Format("{0}/feed", "Page ID");
dynamic resp = fb.Get(facebookUrl, parameters);
Thanks in advance.

You can use the since url parameter in your calls, as described at https://developers.facebook.com/docs/graph-api/using-graph-api/v2.1#paging
This would make it necessary that you store somewhere in your application the timestamp when you last requested the respective feed
This would yield in
var facebookUrl = String.Format("{0}/feed?since={last_update_timestamp}", "Page ID");
where {last_update_timestamp} is the timestamp (unixtime in seconds) of the last update.

Related

About Twilio web hooks

I have developed application, which is sending sms by twilio.
I need to track sms statuses - deliveries, fails, etc. for this reason I use twilio provided web hooks.
Of course I save sent sms into database - for some purposes and then also updating sms status in the db.
I achieved this by getting smsId - what twilio returns when sending sms - this id is saved into db - to track deliveries as mentioned above.
Actual question:
web hook is posting very fast to my endpoint status - actually for that time I event don't expect it to be saved in db.
I tried some of the optimizations - but nothing helped - still web hook is faster - so the resource is not in db - and of course I get NullReferenceException.
dealing with that - I came to the solution - to trying reading resource multiple times with some delays and at the end it gets resource and everything is fine.
actually - I don't like querying database multiple times for very small amount of time.
What can be other solution?
Code sample:
var response = _notificationSender.SendSms(new SendSmsRequest
{
Text = text,
ToNumber = contact.Mobile ?? contact.Phone
});
_db.Database.ExecuteSqlCommand(#"INSERT INTO [Table] ([field], .. ) Values(Field1,...),");
SendSms:
public SendSmsResponse SendSms(SendSmsRequest request)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
TwilioClient.Init(_twilioConfiguration.AccountSid, _twilioConfiguration.Token);
var message = MessageResource.Create(
body: request.Text,
from: new Twilio.Types.PhoneNumber(FromNumber),
statusCallback: new Uri(_twilioConfiguration.StatusCallbackUrl),
to: new Twilio.Types.PhoneNumber(request.ToNumber)
);
return new SendSmsResponse
{
Ok = true,
From = _twilioConfiguration.FromNumbers.First().Value,
Sid = message.Sid,
ErrorCode = (TwillioErrorCode?)message.ErrorCode,
SmsStatus = response.SmsStatus
};
}

Send and return variable with c# API call?

I have a c# script task in an ssis package designed to geocode data through my company's proprietary system. It currently works like this:
1) Pull query of addresses and put in data table
2) Loop through that table and Foreach row, build request, send request, wait for response, then insert back into the database.
The issue is that each call takes forever to return, because before going out and getting a new address on the api side, it checks a current database(string match) to ensure the address does not already exist. If not exists, then go out and get me new data from a service like google.
Because I'm doing one at a time, it makes it easy to keep the ID field with the record when I go back to insert it into the database.
Now comes the issue at hand... I was told to configure this as multi-thread or asynchronous. Here is the page I was reading on here about this topic:
ASP.NET Multithreading Web Requests
var urls = new List<string>();
var results = new ConcurrentBag<OccupationSearch>();
Parallel.ForEach(urls, url =>
{
WebRequest request = WebRequest.Create(requestUrl);
string response = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();
var result = JsonSerializer().Deserialize<OccupationSearch>(new JsonTextReader(new StringReader(response)));
results.Add(result);
});
Perhaps I'm thinking about this wrong, but if I send 2 requests(A & B) and lets say B actually returns first, how can I ensure that when I go back to update my database I'm updating the correct record? Can I send the ID with the API call and return it?
My thoughts are to create an array of requests, burn through them without waiting for a response and return those value in another array, that I will then loop through on my insert statement.
Is this a good way of going about this? I've never used Parrallel.ForEach, and all the info I find on it is too technical for me to visualize and apply to my situation.
Perhaps I'm thinking about this wrong, but if I send 2 requests(A & B) and lets say B actually returns first, how can I ensure that when I go back to update my database I'm updating the correct record? Can I send the ID with the API call and return it?
None of your code contains anything that looks like an "ID," but I assume everything you need is in the URL. If that is the case, one simple answer is to use a Dictionary instead of a Bag.
List<string> urls = GetListOfUrlsFromSomewhere();
var results = new ConcurrentDictionary<string, OccupationSearch>();
Parallel.ForEach(urls.Distinct(), url =>
{
WebRequest request = WebRequest.Create(url);
string response = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();
var result = JsonSerializer().Deserialize<OccupationSearch>(new JsonTextReader(new StringReader(response)));
results.TryAdd(url, result);
});
After this code is done, the results dictionary will contain entries that correlate each response back to the original URL.
Note: you might want to use HttpClient instead of WebClient, and you should take care to dispose of your disposable objects, e.g. StreamReader and StringReader.

How to call, Hang up, put on hold and unhold calls using Twilio?

I have a Twilio number and I understood that in order to do those 4 actions(Call, Hang up, put onhold and unhold calls) I need to create a conference call, but I don't understand how I add my Twilio number to the conference and how do I add another number of a mobile of a client. For example, if my Twilio number is " +9728888888" and the customer's I want to call to mobile number is "+9725555555" – I want code examples of :
1. Calling the customer(from Twilio number " +9728888888" to mobile number "+9725555555")
2. Hold the call
3. UnHold the cold
4. Hangout the call.
I'm using Twilio NuGet on web api project. Can you give me the code examples , considering the numbers I gave(Twilio and mobile) for all of those four scenarios above? I would really appreciate it.
BTW, I saw the code example on their site:
using Twilio.TwiML;
class Example
{
static void Main()
{
var response = new VoiceResponse();
var dial = new Dial();
dial.Conference("moderated-conference-room",
startConferenceOnEnter: false);
response.Dial(dial);
System.Console.WriteLine(response.ToString());
}
}
but it doesn't acknowledge the Twilio or the mobile phone or even the Twilio authentication so I'm not sure how can it work..
Twilio developer evangelist here.
If you want to make a call from your Twilio number to a end user and put both your agent and the user into a conference call then this is the way that I would do it. I am not, however, a C# developer, so while I'll try to give code samples I'm not experienced in .NET web api projects.
You say that you are using the Twilio package from Nuget, that's a good start.
First up, you need to generate a call to your agent and place them in the conference call to wait for the user. To do this, you would use the Twilio REST API to place the call. That code looks a bit like this
const string accountSid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
const string authToken = "your_auth_token";
TwilioClient.Init(accountSid, authToken);
var to = new PhoneNumber("AGENT_PHONE_NUMBER");
var from = new PhoneNumber("+9728888888");
var call = CallResource.Create(
to,
from,
url: new Uri("http://example.com/conference")
);
When this call connects with the agent's number Twilio will make a request to the URL that is sent to the API. Your application needs to respond to tell Twilio what to do with the call. In this case, we should put the agent into a <Conference> to wait for the user. Within this action we also need to generate a call to the user.
public IHttpActionResult Conference()
{
// make the call to the user
var to = new PhoneNumber("+9725555555");
var from = new PhoneNumber("+9728888888");
var call = CallResource.Create(
to,
from,
url: new Uri("http://example.com/user_conference")
);
// return the TwiML
var response = new VoiceResponse();
var dial = new Dial();
dial.Conference("Conference", endConferenceOnExit: true);
response.Dial(dial);
Ok(response.ToString());
}
Note: I've set the agent side of this conference to endConferenceOnExit: true. This means that when the agent hangs up, the conference call will end for all participants.
Now, Twilio will make the call to the user and when that connects ask the new URL what to do with the call. This time you just need to respond with the TwiML to connect to the same conference. I'll leave that for you to deal with.
Finally, to put participants on hold you need to use the REST API again. You need to get the conference SID and the SID of the participant you want to put on hold. Since you will be putting the user on hold from your agent, you get both of these SIDs in the second webhook callback to your application.
With the conference and call SID, make a POST request like this:
const string conferenceSid = "CONFERENCE_SID";
const string callSid = "CALL_SID";
ParticipantResource.Update(
conferenceSid,
callSid,
hold: true,
holdUrl: new Uri("http://example.com/hold")
);
You can also provide a hold URL which can provide music while the user waits. For more information, check the participant resource documentation. Unholding the user is the same process, but you set hold to false.
Let me know if this gets you on the way to creating this feature.

Mobile Services: How to handle the case where your query string is too long?

With Azure Mobile Services Offline Support I'm issuing a PullAsync query like so:
// This list contains 53 emails
var deviceContactEmails = new List<string> { "derek#gmail.com", "sarah#gmail.com", ... };
var query = _userTable.Where(x => deviceContactEmails.Contains(x.Email));
await _userTable.PullAsync(query);
The Mobile Services SDK translates query into a URL encoded GET request with a filter like so (this was a list of 60 emails used for the Contains but I cut out a lot of the middle for brevity):
https://rememberwhen.azure-mobile.net/tables/User?$filter=((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((email%20eq%20'carlin_jmecwrv_stulberg%40tfbnw.net')%20or%20(email%20eq%20'carlin_jmecwrv_stulberg%40tfbnw.net'))%20or%20(email%20eq%20'carlin_jmecwrv_stulberg%40tfbnw.net'))%20eq%20'carlin_jmecwrv_stulberg%40tfbnw.net'))%20or%20(email%20eq%20'carlin_jmecwrv_stulberg%40tfbnw.net'))&$skip=0&$top=50&__includeDeleted=true&__systemproperties=__createdAt%2C__version
The problem is that if deviceContactEmails is too long, the service will complain about the query string length. Trying to filter on this many items in the URL is a problem, so I need to filter by passing the items in the body of the request with JSON or some other way.
So I guess the question is: How do I correctly set this up using the Mobile Service SDK with offline support so I can avoid exceeding the limit on the query string length in the URL encoded request?
It looks like I need to create a custom API to send the list of emails as the body of the request. I'll update this answer and accept if I solve it.

Post comment on a status Facebook C# API

I'm trying to post a comment to a status on Facebook. Basically what I'm doing is something like this:
var parameters = new Dictionary<string, object>(); parameters["message"] = "hello";
fb.Post("/"+id+"/comments", parameters);
Where fb is a FacebookClient object and id is the id of the status.
Unfortunately this doesn't post the comment on recent status. For instance, if I type https://graph.facebook.com/"id"/comments in a web-browser it returns no data if the status is recent, but if the status is old (more than 1 month) it returns the information about the comments on that status.
Is there a way to comment on a status, picture, etc. using this API with C#?
the fb.Post command seems to be correct. I use the same (in vb.net) and it works like expected...
string AccessToken = "...." // User's access token
FacebookClient fb = new FacebookClient(AccessToken);
dynamic parameters = new ExpandoObject();
parameters.message = txtNewComment.Text.Trim();
dynamic result=fb.Post(HiddenMyPostID.Value+"/comments", parameters);
Above is code that i use for posting new comment on any post of facebook. And It's working.
I was having the same issue so I tried few things & this worked for me
var token = "[your access token]";
var fb = new Facebook.FacebookClient(token);
var postId = "173213306032925_74xxxxxxxxxxxxx"; //replace this with your big id which comprises of [userid]_[postid]
var parameters = new Dictionary<string, object>();
parameters.Add("message", "test message");
Console.WriteLine(fb.Post(id+"/comments", parameters).ToString()); // should give new comment's id
Console.WriteLine(fb.Get(postId +"/comments").ToString()); //should give you details
//for deleting
fb.Delete(newly_created_comment_id); //should return true or false
For this, you need to learn about how can you use Graph API and you also need to learn about some parameters like
height should be in integers which indicated the height of the pixels.
redirection should be in boolean and its default value should be true.
width is in integers which indicates the width of pictures in pixels.
There are many more but it can be understood by the standard programmatic interfaces.
When you use the programming language which you prefer should be based on HTTPS requests.
The version of APIs describes that all the requests are firstly in encrypted form and then they are sent via HTTPs requests.
To do so, you need to send make a registration for your application even users are not allowed to log in.
I hope it would work for you. But apart from it, you need to do more researches.
http://wholestatus.com/

Categories