Graph API: What is the correct way to interrupt Pagination - microsoft-graph-api

I am using this script to fetch Chats. I need 100 chats maximum but it may happen that a chat do not have 100 messages. How can I handle that case in this script?
I am using Node Package Microsoft Graph Client.
const { Client, PageIterator } = require('#microsoft/microsoft-graph-client');
async getChatList(GroupChatId) {
let messages = [];
let count = 0;
let pauseAfter = 100; // 100 messages limit
let response = await this.graphClient
.api(`/chats/${GroupChatId}/messages`)
.version('beta')
.get();
let callback = (data) => {
messages.push(data);
count++;
return count < pauseAfter;
}
let pageIterator = new PageIterator(this.graphClient, response, callback);
await pageIterator.iterate();
return messages;
}

As I answered on the GitHub issue you opened, the iterator should stop all by itself if it runs out of items to iterate before hitting your "maximum". However, I think you're hitting a bug in the specific API you're using /chats/id/messages.
The problem is that this API is returning a nextLink value in it's response even if there are no next pages. It shouldn't be, and I'm reporting that to the Teams folks. That's causing the pageIterator to try to get the next set of results, which returns 0 items and a nextLink. You're stuck in an infinite loop.
So because of this, using the pageIterator just won't work for this API. You'll need to do the iteration yourself. Here's some TypeScript code to show it:
let keepGoing: Boolean = true;
do
{
// If there are no items in the page, then stop
// iterating.
keepGoing = currentPage.value.length > 0;
// Loop through the current page
currentPage.value.forEach((message) => {
console.log(JSON.stringify(message.id));
});
// If there's a next link follow it
if (keepGoing && !isNullOrUndefined(currentPage["#odata.nextLink"]))
{
currentPage = await client
.api(currentPage["#odata.nextLink"])
.get();
}
} while (keepGoing);

You need to check with a conditional statement if the message has value or not.
The pseudo code is given below:
let callback = (data) => {
if(data != "" || data != null)
{
messages.push(data);
count++;
return count < pauseAfter;
}
else{
return;
}
}

Related

Broadcasting to Members of a Database Using Twilio Messaging Services

fine people of Stack Overflow.
I'm trying to solve a problem I'm having involving twilio functions, messaging services, and databases.
What I'm attempting to do is send a message to all members of a database at once.
My code is a mess, as Javascript isn't my native language and I'm rather new to twilio.
The problem I believe I'm having is with the async/await feature of javascript.
Here is my code so far:
// Boiler Plate Deta Code
const { Deta } = require("deta");
// Function to access database and get object of conta
async function FetchDB(db) {
let res = await db.fetch();
allItems = res.items;
// continue fetching until last is not seen
while (res.last){
res = await db.fetch({}, {last: res.last});
allItems = allItems.concat(res.items);
}
}
// Function to get total number of contacts.
async function ReturnNumberOfContacts(allItems) {
number_of_contacts = allItems.length;
}
// Function to send message to contact in database.
async function SendMessages(allItems, message) {
allItems.forEach(contact => {
let users_name = contact.name
client.messages
.create({
body: `Hey ${users_name}! ${message}`,
messagingServiceSid: messaging_service,
to: contact.key
})
});
}
// Function to submit response to broadcaster.
async function SuccessResponse(user_name, number_of_contacts) {
responseObject = {
"actions": [
{
"say": `${user_name}, your broadcast has successfully sent to ${number_of_contacts} contacts.`
},
{
"listen": true
}
]
}
}
// Main Function
exports.handler = async function(context, event, callback) {
// Placeholder for number of contacts
let number_of_contacts;
// Place holder for object from database of all contacts
let allItems;
// Placeholder for users message
let message;
// Placeholder for response to user
let responseObject;
//Twilio and Deta, Etc Const
const client = require('twilio')(context.ACCOUNT_SID, context.AUTH_TOKEN);
const deta = Deta(context.DETA_PROJECT_KEY);
const db = deta.Base("users2");
const messaging_service = context.MESSAGING_SERVICE;
// From Phone Number
const from = event.UserIdentifier;
// Parse memory
const memory = JSON.parse(event.Memory);
// Fetch all items from database and return total number of contacts.
// Update relavent variables
await FetchDB(db, allItems).then(ReturnNumberOfContacts(allItems));
// Figure out if message came from short circuit broadcast or normal
if (memory.triggered) {
message = memory.message;
} else {
message = memory.twilio.collected_data.broadcast_message.answers.message_input.answer;
}
// Check if verified and set name.
const current_user = await db.get(from);
// Get the current users name or set a default value
let user_name = current_user.name || "friend";
// Determine if user is an authorized broadcaster
if (from === context.BROADCAST_NUMBER) {
// Decide if the sending of a message should be cancelled.
if (message.toLowerCase() === "c" || message.toLowerCase() === "cancel") {
responseObject = {
"actions": [
{
"say": `${user_name}, you have canceled your request and no messages have been sent.`
},
{
"listen": false
}
]
}
// Return Callback and end task
callback(null, responseObject);
}
// Move forward with sending a message.
else {
// Send message to users in database and send success message to broadcaster.
await SendMessages(message, client, messaging_service)
.then(SuccessResponse(user_name, number_of_contacts))
return callback(null, responseObject);
}
// The user is not authorized so return this.
}
return callback(null, {
"actions": [
{
"say": "You are not authorized to broadcast."
},
{
"listen": false
}
]
})
};
So when the Fetch() function is triggered, I want the database to load a list of everyone and have twilio send them the desired message saved in the message variable. I have the code working so that I can read from the database and get the proper values, and send a single text message with the desired message, but the problem I'm having now is integrating it all together.
Thanks if anyone can point me in the right direction here.
Again, I'm new to javascript and more specifically asynchronous programming.
Twilio developer evangelist here.
The issue from the error says that allItems is undefined when you call ReturnNumberOfContacts.
I think the issue comes from trying to use allItems as a sort of global variable, same for number_of_contacts. It would be better for FetchDB to resolve with the list of items and ReturnNumberOfContacts to resolve with the number of the items.
You also have some arguments missing when you call SendMessages in your function. I've updated it to the point that I think it will work:
// Boiler Plate Deta Code
const { Deta } = require("deta");
// Function to access database and get object of conta
async function FetchDB(db) {
let res = await db.fetch();
let allItems = res.items;
// continue fetching until last is not seen
while (res.last) {
res = await db.fetch({}, { last: res.last });
allItems = allItems.concat(res.items);
}
return allItems;
}
// Function to send message to contact in database.
async function SendMessages(allItems, message, client, messagingService) {
return Promise.all(
allItems.map((contact) => {
let usersName = contact.name;
return client.messages.create({
body: `Hey ${usersName}! ${message}`,
messagingServiceSid: messagingService,
to: contact.key,
});
})
);
}
// Main Function
exports.handler = async function (context, event, callback) {
// Placeholder for users message
let message;
//Twilio and Deta, Etc Const
const client = require("twilio")(context.ACCOUNT_SID, context.AUTH_TOKEN);
const deta = Deta(context.DETA_PROJECT_KEY);
const db = deta.Base("users2");
const messagingService = context.MESSAGING_SERVICE;
// From Phone Number
const from = event.UserIdentifier;
// Parse memory
const memory = JSON.parse(event.Memory);
// Fetch all items from database and return total number of contacts.
// Update relavent variables
const allItems = await FetchDB(db);
const numberOfContacts = allItems.length;
// Figure out if message came from short circuit broadcast or normal
if (memory.triggered) {
message = memory.message;
} else {
message =
memory.twilio.collected_data.broadcast_message.answers.message_input
.answer;
}
// Check if verified and set name.
const currentUser = await db.get(from);
// Get the current users name or set a default value
let userName = currentUser.name || "friend";
// Determine if user is an authorized broadcaster
if (from === context.BROADCAST_NUMBER) {
// Decide if the sending of a message should be cancelled.
if (message.toLowerCase() === "c" || message.toLowerCase() === "cancel") {
// Return Callback and end task
callback(null, {
actions: [
{
say: `${userName}, you have canceled your request and no messages have been sent.`,
},
{
listen: false,
},
],
});
}
// Move forward with sending a message.
else {
// Send message to users in database and send success message to broadcaster.
await SendMessages(allItems, message, client, messagingService);
return callback(null, {
actions: [
{
say: `${userName}, your broadcast has successfully sent to ${numberOfContacts} contacts.`,
},
{
listen: true,
},
],
});
}
// The user is not authorized so return this.
}
return callback(null, {
actions: [
{
say: "You are not authorized to broadcast.",
},
{
listen: false,
},
],
});
};
What I did here was change FetchDB to only take the db as an argument, then to create a local allItems variable that collects all the contacts and then returns them.
async function FetchDB(db) {
let res = await db.fetch();
let allItems = res.items;
// continue fetching until last is not seen
while (res.last) {
res = await db.fetch({}, { last: res.last });
allItems = allItems.concat(res.items);
}
return allItems;
}
This is then called in the main body of the function to assign a local variable. I also replaced the ReturnNumberOfContacts function with a simple assignment.
const allItems = await FetchDB(db);
const numberOfContacts = allItems.length;
One thing you may want to consider is how many contacts you are trying to send messages to during this function. There are a few limits you need to be aware of.
Firstly, Function execution time is limited to 10 seconds so you need to make sure you can load and send all your messages within that amount of time if you want to use a Twilio Function for this.
Also, there are limits for the number of concurrent connections you can make to the Twilio API. That limit used to be 100 connections per account, but it may vary these days. When sending asynchronous API requests as you do in JavaScript, the platform will attempt to create as many connections to the API that it can in order to trigger all the requests asynchronously. If you have more than 100 contacts you are trying to send messages to here, that will quickly exhaust your available concurrent connections and you will receive 429 errors. You may choose to use a queue, like p-queue, to ensure your concurrent connections never get too high. The issue in this case is that it will then take longer to process the queue which brings me back to the original limit of 10 seconds of function execution.
So, I think the above code may work in theory now, but using it in practice may have other issues that you will need to consider.

Why aren't my messages sending using Twilio Messaging Service and Twilio Functions? [duplicate]

fine people of Stack Overflow.
I'm trying to solve a problem I'm having involving twilio functions, messaging services, and databases.
What I'm attempting to do is send a message to all members of a database at once.
My code is a mess, as Javascript isn't my native language and I'm rather new to twilio.
The problem I believe I'm having is with the async/await feature of javascript.
Here is my code so far:
// Boiler Plate Deta Code
const { Deta } = require("deta");
// Function to access database and get object of conta
async function FetchDB(db) {
let res = await db.fetch();
allItems = res.items;
// continue fetching until last is not seen
while (res.last){
res = await db.fetch({}, {last: res.last});
allItems = allItems.concat(res.items);
}
}
// Function to get total number of contacts.
async function ReturnNumberOfContacts(allItems) {
number_of_contacts = allItems.length;
}
// Function to send message to contact in database.
async function SendMessages(allItems, message) {
allItems.forEach(contact => {
let users_name = contact.name
client.messages
.create({
body: `Hey ${users_name}! ${message}`,
messagingServiceSid: messaging_service,
to: contact.key
})
});
}
// Function to submit response to broadcaster.
async function SuccessResponse(user_name, number_of_contacts) {
responseObject = {
"actions": [
{
"say": `${user_name}, your broadcast has successfully sent to ${number_of_contacts} contacts.`
},
{
"listen": true
}
]
}
}
// Main Function
exports.handler = async function(context, event, callback) {
// Placeholder for number of contacts
let number_of_contacts;
// Place holder for object from database of all contacts
let allItems;
// Placeholder for users message
let message;
// Placeholder for response to user
let responseObject;
//Twilio and Deta, Etc Const
const client = require('twilio')(context.ACCOUNT_SID, context.AUTH_TOKEN);
const deta = Deta(context.DETA_PROJECT_KEY);
const db = deta.Base("users2");
const messaging_service = context.MESSAGING_SERVICE;
// From Phone Number
const from = event.UserIdentifier;
// Parse memory
const memory = JSON.parse(event.Memory);
// Fetch all items from database and return total number of contacts.
// Update relavent variables
await FetchDB(db, allItems).then(ReturnNumberOfContacts(allItems));
// Figure out if message came from short circuit broadcast or normal
if (memory.triggered) {
message = memory.message;
} else {
message = memory.twilio.collected_data.broadcast_message.answers.message_input.answer;
}
// Check if verified and set name.
const current_user = await db.get(from);
// Get the current users name or set a default value
let user_name = current_user.name || "friend";
// Determine if user is an authorized broadcaster
if (from === context.BROADCAST_NUMBER) {
// Decide if the sending of a message should be cancelled.
if (message.toLowerCase() === "c" || message.toLowerCase() === "cancel") {
responseObject = {
"actions": [
{
"say": `${user_name}, you have canceled your request and no messages have been sent.`
},
{
"listen": false
}
]
}
// Return Callback and end task
callback(null, responseObject);
}
// Move forward with sending a message.
else {
// Send message to users in database and send success message to broadcaster.
await SendMessages(message, client, messaging_service)
.then(SuccessResponse(user_name, number_of_contacts))
return callback(null, responseObject);
}
// The user is not authorized so return this.
}
return callback(null, {
"actions": [
{
"say": "You are not authorized to broadcast."
},
{
"listen": false
}
]
})
};
So when the Fetch() function is triggered, I want the database to load a list of everyone and have twilio send them the desired message saved in the message variable. I have the code working so that I can read from the database and get the proper values, and send a single text message with the desired message, but the problem I'm having now is integrating it all together.
Thanks if anyone can point me in the right direction here.
Again, I'm new to javascript and more specifically asynchronous programming.
Twilio developer evangelist here.
The issue from the error says that allItems is undefined when you call ReturnNumberOfContacts.
I think the issue comes from trying to use allItems as a sort of global variable, same for number_of_contacts. It would be better for FetchDB to resolve with the list of items and ReturnNumberOfContacts to resolve with the number of the items.
You also have some arguments missing when you call SendMessages in your function. I've updated it to the point that I think it will work:
// Boiler Plate Deta Code
const { Deta } = require("deta");
// Function to access database and get object of conta
async function FetchDB(db) {
let res = await db.fetch();
let allItems = res.items;
// continue fetching until last is not seen
while (res.last) {
res = await db.fetch({}, { last: res.last });
allItems = allItems.concat(res.items);
}
return allItems;
}
// Function to send message to contact in database.
async function SendMessages(allItems, message, client, messagingService) {
return Promise.all(
allItems.map((contact) => {
let usersName = contact.name;
return client.messages.create({
body: `Hey ${usersName}! ${message}`,
messagingServiceSid: messagingService,
to: contact.key,
});
})
);
}
// Main Function
exports.handler = async function (context, event, callback) {
// Placeholder for users message
let message;
//Twilio and Deta, Etc Const
const client = require("twilio")(context.ACCOUNT_SID, context.AUTH_TOKEN);
const deta = Deta(context.DETA_PROJECT_KEY);
const db = deta.Base("users2");
const messagingService = context.MESSAGING_SERVICE;
// From Phone Number
const from = event.UserIdentifier;
// Parse memory
const memory = JSON.parse(event.Memory);
// Fetch all items from database and return total number of contacts.
// Update relavent variables
const allItems = await FetchDB(db);
const numberOfContacts = allItems.length;
// Figure out if message came from short circuit broadcast or normal
if (memory.triggered) {
message = memory.message;
} else {
message =
memory.twilio.collected_data.broadcast_message.answers.message_input
.answer;
}
// Check if verified and set name.
const currentUser = await db.get(from);
// Get the current users name or set a default value
let userName = currentUser.name || "friend";
// Determine if user is an authorized broadcaster
if (from === context.BROADCAST_NUMBER) {
// Decide if the sending of a message should be cancelled.
if (message.toLowerCase() === "c" || message.toLowerCase() === "cancel") {
// Return Callback and end task
callback(null, {
actions: [
{
say: `${userName}, you have canceled your request and no messages have been sent.`,
},
{
listen: false,
},
],
});
}
// Move forward with sending a message.
else {
// Send message to users in database and send success message to broadcaster.
await SendMessages(allItems, message, client, messagingService);
return callback(null, {
actions: [
{
say: `${userName}, your broadcast has successfully sent to ${numberOfContacts} contacts.`,
},
{
listen: true,
},
],
});
}
// The user is not authorized so return this.
}
return callback(null, {
actions: [
{
say: "You are not authorized to broadcast.",
},
{
listen: false,
},
],
});
};
What I did here was change FetchDB to only take the db as an argument, then to create a local allItems variable that collects all the contacts and then returns them.
async function FetchDB(db) {
let res = await db.fetch();
let allItems = res.items;
// continue fetching until last is not seen
while (res.last) {
res = await db.fetch({}, { last: res.last });
allItems = allItems.concat(res.items);
}
return allItems;
}
This is then called in the main body of the function to assign a local variable. I also replaced the ReturnNumberOfContacts function with a simple assignment.
const allItems = await FetchDB(db);
const numberOfContacts = allItems.length;
One thing you may want to consider is how many contacts you are trying to send messages to during this function. There are a few limits you need to be aware of.
Firstly, Function execution time is limited to 10 seconds so you need to make sure you can load and send all your messages within that amount of time if you want to use a Twilio Function for this.
Also, there are limits for the number of concurrent connections you can make to the Twilio API. That limit used to be 100 connections per account, but it may vary these days. When sending asynchronous API requests as you do in JavaScript, the platform will attempt to create as many connections to the API that it can in order to trigger all the requests asynchronously. If you have more than 100 contacts you are trying to send messages to here, that will quickly exhaust your available concurrent connections and you will receive 429 errors. You may choose to use a queue, like p-queue, to ensure your concurrent connections never get too high. The issue in this case is that it will then take longer to process the queue which brings me back to the original limit of 10 seconds of function execution.
So, I think the above code may work in theory now, but using it in practice may have other issues that you will need to consider.

How do I obtain available worker count in twilio function calling node library?

Im looking to invoke a twilio function and obtain a count of available workers.
I have a feeling it might be related to TaskQueues and the Matching Workers who are available?
Ive come up with the following. However, users are still listed as available when they are interacting with a task, which means this wont work necessarily.
exports.handler = function (context, event, callback) {
const client = require('twilio')(context.ACCOUNT_SID, context.AUTH_TOKEN);
client.taskrouter
.workspaces('eee')
.workers.list()
.then(workers => {
data = {
availWorkersCount: Object.keys(workers.filter(x=> x.available === true && x.attributes.includes("sales"))).length
};
const response = new Twilio.Response();
response.appendHeader('Access-Control-Allow-Origin', '*');
response.appendHeader('Access-Control-Allow-Methods', 'OPTIONS POST GET');
response.appendHeader('Access-Control-Allow-Headers', 'Content-Type');
response.appendHeader('Content-Type', 'application/json');
response.setBody(data);
callback(null, response);
});
};
I know this is a bit late, but this is the chunk of code I use in a twilio function to do just this. We call the function from the studio flow and use the results to decide if I am going to route the call into voicemail or play some IVR options for picking what queue they should be put in. To use it you can pass in an optional skill to filter down the agents even more. We grab all available workers then filter down to only the ones that have the needed skill.
You could then take this and check if any of the agents that are available also have a task assigned to them then remove them from the count.
const fetch = require("node-fetch");
exports.handler = function(context, event, callback) {
let response = new Twilio.Response();
// Set the status code to 200 OK
response.setStatusCode(200);
// Set the Content-Type Header
response.appendHeader('Access-Control-Allow-Origin', '*');
response.appendHeader('Access-Control-Allow-Methods', 'OPTIONS, POST, GET');
response.appendHeader('Access-Control-Allow-Headers', 'Content-Type');
response.appendHeader('Content-Type', 'application/json');
let body = {
TotalAvailable: 0
};
let client = context.getTwilioClient();
client.taskrouter.workspaces(context.WorkspaceSid)
.workers
.list({
available: 'true',
limit: 50
})
.then((workers) => {
let agents = [];
let i = 0;
if(workers){
for(i = 0; i < workers.length; i++){
let worker = workers[i];
let item = {};
let attributes = JSON.parse(worker.attributes);
if(attributes && attributes.routing && attributes.routing.skills && attributes.routing.skills.length > 0){
item.skills = attributes.routing.skills;
item.nid = attributes.nid;
item.first_name = attributes.first_name;
item.last_name = attributes.last_name;
if(event.skill){
if(item.skills.includes(event.skill)){
// TODO: filter here
agents.push(item);
}
}else{
agents.push(item);
}
}
}
}
body.TotalAvailable = agents.length;
body.Agents = agents;
response.setBody(body);
callback(null, response);
})
.catch((ex) => {
body.error = true;
body.message = ex;
response.setBody(body);
callback(null, response);
});
};

OData Service not returning complete response

I am reading Sharepoint list data (>20000 entries) using Odata RESTful service as detailed here -http://blogs.msdn.com/b/ericwhite/archive/2010/12/09/getting-started-using-the-odata-rest-api-to-query-a-sharepoint-list.aspx
I am able to read data but I get only the first 1000 records. I also checked that List View Throttling is set to 5000 on sharepoint server. Kindly advise.
Update:
#Turker: Your answer is spot on!! Thank you very much. I was able to get the first 2000 records in first iteration. However, I am getting the same records in each iteration of while loop. My code is as follows-
...initial code...
int skipCount =0;
while (((QueryOperationResponse)query).GetContinuation() != null)
{
//query for the next partial set of customers
query = dc.Execute<CATrackingItem>(
((QueryOperationResponse)query).GetContinuation().NextLinkUri
);
//Add the next set of customers to the full list
caList.AddRange(query.ToList());
var results = from d in caList.Skip(skipCount)
select new
{
Actionable = Actionable,
}; Created = d.Created,
foreach (var res in results)
{
structListColumns.Actionable = res.Actionable;
structListColumns.Created= res.Created;
}
skipCount = caList.Count;
}//Close of while loop
Do you see a <link rel="next"> element at the end of the feed?
For example, if you look at
http://services.odata.org/Northwind/Northwind.svc/Customers/
you will see
<link rel="next" href="http://services.odata.org/Northwind/Northwind.svc/Customers/?$skiptoken='ERNSH'" />
at the end of the feed which means the service is implementing server side paging and you need to send the
http://services.odata.org/Northwind/Northwind.svc/Customers/?$skiptoken='ERNSH'
query to get the next set of results.
I don't see anything particularly wrong with your code. You can try to dump the URLs beign requested (either from the code, or using something like fiddler) to see if the client really sends the same queries (and thus getting same responses).
In any case, here is a sample code which does work (using the sample service):
DataServiceContext ctx = new DataServiceContext(new Uri("http://services.odata.org/Northwind/Northwind.svc"));
QueryOperationResponse<Customer> response = (QueryOperationResponse<Customer>)ctx.CreateQuery<Customer>("Customers").Execute();
do
{
foreach (Customer c in response)
{
Console.WriteLine(c.CustomerID);
}
DataServiceQueryContinuation<Customer> continuation = response.GetContinuation();
if (continuation != null)
{
response = ctx.Execute(continuation);
}
else
{
response = null;
}
} while (response != null);
I had the same problem, and wanted it to be a generic solution.
So I've extended DataServiceContext with a GetAlltems methode.
public static List<T> GetAlltems<T>(this DataServiceContext context)
{
return context.GetAlltems<T>(null);
}
public static List<T> GetAlltems<T>(this DataServiceContext context, IQueryable<T> queryable)
{
List<T> allItems = new List<T>();
DataServiceQueryContinuation<T> token = null;
EntitySetAttribute attr = (EntitySetAttribute)typeof(T).GetCustomAttributes(typeof(EntitySetAttribute), false).First();
// Execute the query for all customers and get the response object.
DataServiceQuery<T> query = null;
if (queryable == null)
{
query = context.CreateQuery<T>(attr.EntitySet);
}
else
{
query = (DataServiceQuery<T>) queryable;
}
QueryOperationResponse<T> response = query.Execute() as QueryOperationResponse<T>;
// With a paged response from the service, use a do...while loop
// to enumerate the results before getting the next link.
do
{
// If nextLink is not null, then there is a new page to load.
if (token != null)
{
// Load the new page from the next link URI.
response = context.Execute<T>(token);
}
allItems.AddRange(response);
}
// Get the next link, and continue while there is a next link.
while ((token = response.GetContinuation()) != null);
return allItems;
}

Get all tweets with specific hashtag

I've been experimenting with the Twitter API because I want to display a few lists of tweets on a special page.
Among those lists is a list with all tweets containing a specific hashtag (e.g. #test)
However I cannot find how to get that list in either XML or JSON (preferably the latter), does anyone know how? It is also fine if it can be done in TweetSharp
You can simply fetch http://search.twitter.com/search.json?q=%23test to get a list of tweets containing #test in JSON, where %23test is #test URL encoded.
I'm not familiar with TweetSharp, but I guess there must be a search command that you can use to search for #test, and then transform the resulting tweets into JSON yourself.
First install TweetSharp using github
https://github.com/danielcrenna/tweetsharp
Here is the code to do a search
TwitterService service = new TwitterService();
var tweets = service.Search("#Test", 100);
List<TwitterSearchStatus> resultList = new List<TwitterSearchStatus>(tweets.Statuses);
If you have more then one page results you can setup a loop and call each page
service.Search("#Test", i += 1, 100);
It seems like there is a change in the API since last few months. Here is the updated code:
TwitterSearchResult res = twitter.Search(new SearchOptions { Q = "xbox" });
IEnumerable<TwitterStatus> status = res.Statuses;
u access with this url for your tweet searchs. But u have to use OAuth protocols.
https://api.twitter.com/1.1/search/tweets.json?q=%40twitterapi
I struggled with the same problem. Here is my vague solution . Enjoy Programming.
It will get out of the function whenever your required number of tweets are acquired/fetched.
string maxid = "1000000000000"; // dummy value
int tweetcount = 0;
if (maxid != null)
{
var tweets_search = twitterService.Search(new SearchOptions { Q = keyword, Count = Convert.ToInt32(count) });
List<TwitterStatus> resultList = new List<TwitterStatus>(tweets_search.Statuses);
maxid = resultList.Last().IdStr;
foreach (var tweet in tweets_search.Statuses)
{
try
{
ResultSearch.Add(new KeyValuePair<String, String>(tweet.Id.ToString(), tweet.Text));
tweetcount++;
}
catch { }
}
while (maxid != null && tweetcount < Convert.ToInt32(count))
{
maxid = resultList.Last().IdStr;
tweets_search = twitterService.Search(new SearchOptions { Q = keyword, Count = Convert.ToInt32(count), MaxId = Convert.ToInt64(maxid) });
resultList = new List<TwitterStatus>(tweets_search.Statuses);
foreach (var tweet in tweets_search.Statuses)
{
try
{
ResultSearch.Add(new KeyValuePair<String, String>(tweet.Id.ToString(), tweet.Text));
tweetcount++;
}
catch { }
}
}

Resources