Trial abusers

@Gustavo Silva
Tooling or a tutorial on how to combat trial abusers who create multiple accounts to avoid paying Apify and community creators
can you elaborate?
16 Replies
flat-fuchsia
flat-fuchsia5mo ago
I have seen users of rented actors that I believe are creating multiple Apify accounts so they can always stay in trial and avoid paying for a subscription. We can combat this by limiting the number of dataset results for trial users.
afraid-scarlet
afraid-scarlet5mo ago
ah, I see
We can combat this by limiting the number of dataset results for trial users.
well, thay can still create more accounts
flat-fuchsia
flat-fuchsia5mo ago
But let's say they want to scrape a page with 1000 results and you limit it to 100. If your target website has no way of skipping the first 100 then they will never be able to read results 101-1000 with your actor.
sensitive-blue
sensitive-blue5mo ago
How do you know if the user is on trial? Is there way to get this information from inside of the actor?
azzouzana
azzouzana5mo ago
To handle these cases, the best I could do is checking whether the user is a free user or a paying user in the actor code and based on that, I limit the returned dataset items to X, here's an example in js: const user = await Actor.apifyClient.user().get(); console.log(user.isPaying) or this in python: client = Actor.apify_client.user() user_data = await client.get() print(user_data.get('isPaying')) One more thing I occasionally do. in addition to the previous check, is checking whether this free user ran the actor in the last hour (I get the running user, and his concerned actor's runs) more than 5 times and if he did, I reduce the ability to run the actor to once every 30 minutes
afraid-scarlet
afraid-scarlet5mo ago
I'm not sure if isPaying refers o trail/non trail or to being paid user on Apify platform in general
azzouzana
azzouzana5mo ago
It refers to Apify platform not the actor (free/paid) but the closet I could do
afraid-scarlet
afraid-scarlet5mo ago
yea, me too
conscious-sapphire
conscious-sapphire5mo ago
It's up to Apify to prevent this. I gave feedback about the ease of creating an account and they fixed some things. But there are still some people who use multiple accounts due to the low security of registering by email only. Examples where they block this on an IP basis can be seen in #apify-platform
passive-yellow
passive-yellow5mo ago
This is endless fight but Apify is improving the fraud detection every month
flat-fuchsia
flat-fuchsia5mo ago
This can be a joint effort between Apify and public actor developers, as it is in the best interest of both parties. If Apify provides a better way to determine whether a user is paying for the current actor or is in trial mode, creators can then implement strategies to limit abuse in the actor's logic.
conscious-sapphire
conscious-sapphire5mo ago
hello how to check if the user in the trial period !
Louis Deconinck
Louis Deconinck4mo ago
How do you get the actor runs of a given user of your actor?
azzouzana
azzouzana4mo ago
@Louis Deconinck something like this import { Actor } from 'apify'; import { ApifyClient } from 'apify-client'; (async () => { await Actor.init(); // Retrieve the Actor ID dynamically (auto-injected in Apify environment) const actorId = Actor.config().actorId; if (!actorId) { console.error('Actor ID not found. Are you running this on the Apify platform?'); process.exit(1); } // Initialize ApifyClient using the injected API token const client = new ApifyClient({ token: Actor.config().token }); // Fetch runs for the current actor const runs = await client.actor(actorId).runs().list(); console.log('Recent runs:', runs.items); await Actor.exit(); })(); (This might not 100% work, I'm not on my computer now)
Louis Deconinck
Louis Deconinck4mo ago
Thanks for the code, how is this different from await Actor.apifyClient.runs().list()? Why do you need Actor.config().actorId;? How do you identify the user that did the run, or does this only return the runs of the current user? Output looks like this:
{
"id": "HG7ML7M8z78YcAPEB",
"actId": "HDSasDasz78YcAPEB",
"actorTaskId": "KJHSKHausidyaJKHs",
"status": "SUCCEEDED",
"startedAt": "2019-11-30T07:34:24.202Z",
"finishedAt": "2019-12-12T09:30:12.202Z",
"buildId": "HG7ML7M8z78YcAPEB",
"buildNumber": "0.0.2",
"meta": {
"origin": "DEVELOPMENT"
},
"usageTotalUsd": 0.2,
"defaultKeyValueStoreId": "sfAjeR4QmeJCQzTfe",
"defaultDatasetId": "3ZojQDdFTsyE7Moy4",
"defaultRequestQueueId": "so93g2shcDzK3pA85"
}
{
"id": "HG7ML7M8z78YcAPEB",
"actId": "HDSasDasz78YcAPEB",
"actorTaskId": "KJHSKHausidyaJKHs",
"status": "SUCCEEDED",
"startedAt": "2019-11-30T07:34:24.202Z",
"finishedAt": "2019-12-12T09:30:12.202Z",
"buildId": "HG7ML7M8z78YcAPEB",
"buildNumber": "0.0.2",
"meta": {
"origin": "DEVELOPMENT"
},
"usageTotalUsd": 0.2,
"defaultKeyValueStoreId": "sfAjeR4QmeJCQzTfe",
"defaultDatasetId": "3ZojQDdFTsyE7Moy4",
"defaultRequestQueueId": "so93g2shcDzK3pA85"
}
azzouzana
azzouzana4mo ago
The code I shared with you was generated by crawlee chatgpt helper, that's why I said it might not work 100%. I'd say there's Actor.config().actorId; is just an explicit way to mean the same thing in this case, but could also be used to fetch others actors runs triggered by current user. (Not 100% sur because I didn't have much time studying the sdk, I just picked what worked for me) Yes, that returns the current actor's runs triggered by the running user

Did you find this page helpful?