Basically my requirement is getting all direct messages from TweetSharp.dll for a particular user, for the time being I'm getting this messages from following line of code:
string message = null;
List<string> messages = new List<string>();
IEnumerable<TwitterDirectMessage> directMessages = service.ListDirectMessagesReceived(new ListDirectMessagesReceivedOptions());
////Fetch all current direct message:
foreach (TwitterDirectMessage directMessage in directMessages)
{
//Store each message into a list, in reverse older:
message = /*"[" + directMessage.CreatedDate.ToString() + "]" +*/ directMessage.Text;
messages.Insert(0, message);
}
But I want to use twitterService.BeginGetDirectMessage method to get all direct messages for particular user but problem is that how can get incoming new message. So let me know appropriate solution to solve this problem.
Any help is appreciated!
Tweetsharp is implementing an asynchronous programming model, check out this SO Post or the msdn on how to use Tasks to wrap asynch methods.
Related
I'm working on a project now within Twilio, using Twilio Functions, where I'm trying to set up SMS messaging so that if we receive an incoming keyword, we respond with a specific message, including a URL. The plan is to have multiple incoming keywords, with different responses so if someone sends an SMS to one of our numbers, depending on that key word, we respond with a basic message and a URL. I'm trying to figure out the best way to handle this within Twilio Functions.
I have this working for a single incoming keyword/response, as seen below.
if (incomingMessage.includes('testpark')) {
twiml.message('StartMyParking:\n\nTo start your parking, please click this link: https://blahblah.com');
} else if (incomingMessage.includes('bye')) {
twiml.message('Goodbye!');
} else {
twiml.message('Please check your zone/code and try again.');
}
While that works, I want to add in more incoming words, along with responses, such as an incoming message of 'testpark2' and a response of 'StartMyParking:\n\nTo start your parking, please click this link: https://blahblah2.com'.
Then I would want to include another one with 'testpark3' and a response of 'StartMyParking:\n\nTo start your parking, please click this link: https://blahblah3.com' and so on, all within the same script.
Can someone help me understand how to achieve this?
There are a lot of ways to achieve your desired outcome, but here's the most straightforward to begin with.
Instead of creating an else if statement for every possible keyword, you could define the keyword/response pairs up front using a JavaScript Map.
The keys of the Map will be your keywords, the values of the Map will be your responses:
const keywordResponseMap = new Map([
['testpark2', 'StartMyParking:\n\nTo start your parking, please click this link: https://blahblah2.com'],
['testpark3', 'StartMyParking:\n\nTo start your parking, please click this link: https://blahblah3.com'],
['testpark', 'StartMyParking:\n\nTo start your parking, please click this link: https://blahblah.com'],
]);
const keywords = Array.from(keywordResponseMap.keys());
let keyword;
if (incomingMessage.includes('bye')) {
twiml.message('Goodbye!');
}
else if (keyword = keywords.find(k => incomingMessage.includes(k))) {
const response = keywordResponseMap.get(keyword);
twiml.message(response);
} else {
twiml.message('Please check your zone/code and try again.');
}
Also note that I'm putting the bye case up front because it is more performant than looking for the keywords in the incomingMessage, thus you avoid unnecessarily doing that processing when a user says bye.
You can use find to search for any keyword that is in the incomingMessage, then you can use the keyword that you found to retrieve the response from the map.
If your response will always be the same except for the URL, you could further optimize this by only storing the URL in the map and using string interpolation like this:
const keywordUrlMap = new Map([
['testpark2', 'https://blahblah2.com'],
['testpark3', 'https://blahblah3.com'],
['testpark', 'https://blahblah.com'],
]);
const keywords = Array.from(keywordUrlMap.keys());
let keyword;
if (incomingMessage.includes('bye')) {
twiml.message('Goodbye!');
}
else if (keyword = keywords.find(k => incomingMessage.includes(k))) {
const url = keywordUrlMap.get(keyword);
twiml.message(`StartMyParking:\n\nTo start your parking, please click this link: ${url}`);
} else {
twiml.message('Please check your zone/code and try again.');
}
It is also important to note that I'm putting testpark last in the map because testpark matches to testpark2 and testpark3. If you'd put it first, it would always resolve to testpark even with a user submits testpark2 or similar values.
Also, I'm using the Map type because it guarantees the order in which the keys are returned, which is again important for the previous point.
When you have a lot more keywords and responses, you may have to start looking at a solution to store them externally like a database, and query the database by keyword to resolve the response.
Good luck, we can't wait to see what you build!
I have been working on this problem for a couple of days now, and feel like I'm extremely close to solving the issue. I need to cycle through an object and send a text message to each record in the object before moving on to the next line of code. The code to send works when isolated locally. But I'm having trouble getting it to work in Twilio Functions. All my code appears to work, but the text messages are not sent.
for await (const contact of allItems) {
client.messages
.create({
body: "Hey " + contact.name + "!" + " " + message,
messagingServiceSid: messaging_service,
to: contact.key
});
};
// End Send Message to Each Contact
I've attached the portion of code I believe I'm having issues with.
What I want to do, is for this piece of code to run completely before moving on to the next few lines and invoking a callback.
Any idea how I could do something like this?
Twilio developer evangelist here.
The issue here is that you are not awaiting the actual result of the asynchronous call. Locally, that doesn't matter, but within Twilio Functions once you call the callback function all asynchronous calls that have started are terminated.
To create a loop that makes asynchronous requests and waits for them all to complete you will want to use Promise.all in conjunction with map. In your example, it should look like this:
function SendMessages(allItems, message, client, messagingService) {
const apiRequests = allItems.map((contact) => {
let usersName = contact.name;
return client.messages.create({
body: `Hey ${usersName}! ${message}`,
messagingServiceSid: messagingService,
to: contact.key,
});
})
return Promise.all(apiRequests);
}
In this function we map over the list contacts returning the promise that is created when we try to send a message. The variable apiRequests becomes an array of promises that represent the requests to the API. We can then use this array of promises in Promise.all. Promise.all will only resolve once all the promises it is passed have resolved (or if a promise rejects).
I recommend you read my answer to your previous question as that brings up some further issues that you might have with this.
As part of our project we need to call Twilio to get E164 format of the Phone Number. In order to do that I followed the below steps to achieve. If the phone number is valid then the below step is working but if the phone number is not valid and we are passing the same to Twillo then it is not returning anything back and halt the process.
I know that the below mention number is not valid but that doesn't mean when I am trying to lookup with invalid number it should not return any response. It should return at least an error but actually it is not which is making me more confused. I am trying with IBM websphere server.
Can some one please help me to fix this issue or is there any way where I can set request time out for twilio lookup so that it will allow other process to continue if any failures in twilio lookup. Also, correct me if I did any mistake in my coding for twilio lookup.
Sample URL "https://lookups.twilio.com/v1/PhoneNumbers/phoneNumber"
Steps Followed:
LookupsClient client = new LookupsClient(ACCOUNT_SID, AUTH_TOKEN);
client.setHttpClient(getProxyClient());
// Twilio Lookup with country code
String twilioURL = createURL(phoneNumber, countryCd);
String twilioE164Number = getTwilioNumber(client, twilioURL);
//Twilio Lookup without country code
StringBuilder appender = new StringBuilder();
appender.append(TWILIO_URL);
appender.append(PLUS);
appender.append(phoneNumber);
String twilioE164Number = getTwilioNumber(client, appender.toString());
//Create lookup URL
private String createURL(String phoneNumber, String countryCode){
StringBuilder appender = new StringBuilder();
appender.append(phoneNumber);
appender.append(QUERY_PARAM);
appender.append(countryCode);
return TWILIO_URL+appender.toString();
}
//Get Twilio E164 Number
private String getTwilioNumber(LookupsClient client,String url){
TwilioRestResponse response;
String twilioResult = "";
try {
response = client.get(url);
String str = response.getResponseText();
//Code for parsing the JSON response and set the twilioResult.
} catch (TwilioRestException e) {
logger.error("TwilioRestException while calling twilio "+e);
}catch(Exception ex){
logger.error("Error in twilio Calling "+ex);
}
return twilioResult;
}
//Get proxy client to set.
private HttpClient getProxyClient() {
HttpHost proxy = new HttpHost(PROXY_HOST, PROXY_PORT);
//new DefaultHttpClient().getParams().setParameter(arg0, arg1)
DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),new UsernamePasswordCredentials(ACCOUNT_SID, AUTH_TOKEN));
CloseableHttpClient httpClient = HttpClients.custom()
.setRoutePlanner(routePlanner)
.setDefaultCredentialsProvider(credentialsProvider)
.build();
return httpClient;
}
v6.3.0 of twilio-java has a LookupsClient has a .getPhoneNumber() method that allows you to pass a phone number instead of requiring that you construct the URL from scratch. The whole point of using LookupsClient instead of a vanilla TwilioClient is that the class does the bulk of the work for you.
Have you tried client.getPhoneNumber(phoneNumber) in this case? This page also demonstrates the structure of the response that you should receive when using that particular endpoint. The E164-formatted phone number should be the phone_number property in the response, although I use twilio-python and I don't know how the Java library exposes response objects for your consumption.
If you aren't getting a response at all, you might want to try making the same request without your proxy configuration to make sure the proxy isn't causing the problem. As for your timeout question, twilio-java's requests are processed synchronously, one way to get around that would be to wrap the request in an asynchronous method call.
Hope some of this helps you diagnose your issue!
We currently have a generic MVC method that GET's data from ASP.NET Web API
public static T Get<T>(string apiURI, object p)
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(Config.API_BaseSite);
HttpResponseMessage response = client.GetAsync(apiURI).Result;
// Check that response was successful or throw exception
if (response.IsSuccessStatusCode == false)
{
string responseBody = response.Content.ReadAsStringAsync().Result;
throw new HttpException((int)response.StatusCode, responseBody);
}
T res = response.Content.ReadAsAsync<T>().Result;
return (T)res;
}
}
Our question is:- obviously, we can not send 'p' as you would with a post,
client.PostAsync(apiURI, new StringContent(p.ToString(), Encoding.UTF8, "application/json")
but how we go about sending this object / JSON with a get.
We have seen sending it as part of the URL, however, is there an alternative?
GET sends the values with the query string (end of url), in regards to "but how we go about sending this object / JSON with a get. We have seen sending it as part of the URL, however, is there an alternative?".
The alternative is POST or PUT.
PUT is best used when the user creates the key/url. You can look at examples such as cnn.com - where the URL's are just short versions of the article title. You want to PUT a page at that URL.
Example:
http://newday.blogs.cnn.com/2014/03/19/five-things-to-know-for-your-new-day-wednesday-march-19-2014/?hpt=hp_t2
has the url of "five-things-to-know-for-your-new-day-wednesday-march-19-2014", which was generated from the article title of "Five Things to Know for Your New Day – Wednesday, March 19, 2014"
In general, you should follow these guidelines:
Use GET when you want to fetch data from the server. Think of search engines. You can see your search query in the query string. You can also book mark it. It doesn't change anything on the server at all.
Use POST when you want to create a resource.
Use PUT when you want to create resources, but it also overwrites them. If you PUT an object twice, the servers state is only changed once. The opposite is true for POST
Use DELETE when you want to delete stuff
Neither POST nor PUT use the query string. GET does
Here is the thing. I'd like to set up a counter that shows total number of Twitter followers for a user. When the number of followers reach exactly 1,000,000, would love to do something. If there's an api to do that, how often can I call the api.
Thanks.
Hello
Sorry I don't know PHP that well, and not at all JQuery, however, here is what I've done in C# ... hope it helps ;)
// Launch the request to obtain the number of followers of the user
WebRequest request = HttpWebRequest.Create("http://twitter.com/users/show.xml?screen_name=[username]");
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
StreamReader streamReader = new StreamReader(response.GetResponseStream());
// Load response in an XML Document
XmlDocument doc = new XmlDocument();
doc.LoadXml(streamReader.ReadToEnd());
// Parse the node we're interested in...
XmlNode node = doc.DocumentElement.SelectSingleNode("followers_count");
// ... and affect the number of followers
labelScore.Text = node.InnerText;
}
Yes, you can use the users/show call to get this information. You'll find it as a property named followers_count:
"followers_count": 160752,