Comments (9)
@seratch Sorry for the hold up. Yesss that helped Thank You very much. Maybe not directly but with that we were able to rewrite some logic. So if someone need's working code here it is:
import datetime
import sys
import time
import slack_sdk
from slack_sdk.errors import SlackApiError
from slack_sdk import WebClient
sys.path.append(r'C:\Users\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
SLACK_API_TOKEN = 'xoxb-1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1'
ARCHIVE_LAST_MESSAGE_AGE_DAYS = 360
oldest_message_time_to_prevent_archive = (
datetime.datetime.now() - datetime.timedelta(days=ARCHIVE_LAST_MESSAGE_AGE_DAYS)
).timestamp()
client = WebClient(SLACK_API_TOKEN)
my_user_id = client.auth_test()['user_id']
processed_channels = set()
def post_archive_message(channel_name):
message = (
f"The Slack channel '{channel_name}' has been archived due to long inactivity.\n\n"
"If you have any questions, doubts, or if you wish to unarchive the channel, "
"please feel free to raise an IT ticket at [IT Ticket System](https:/xxxxxxxxxxxxxxcom/)."
)
response = client.chat_postMessage(channel=f"#{channel_name}", text=message)
print(response)
def channel_has_recent_messages(channel_id):
# Getting up to 2 messages younger than ARCHIVE_LAST_MESSAGE_AGE_DAYS
global response
if channel_id in processed_channels:
return False
real_messages = []
try:
response = client.conversations_history(
channel=channel_id,
oldest=str(oldest_message_time_to_prevent_archive),
limit=5
)
# Filter out message about our bot joining this channel
if response["messages"] is not None:
for m in response["messages"]:
if 'user' not in m or m['user'] != my_user_id:
real_messages.append(m)
if real_messages:
print('#' + channel['name'] + ': Has recent messages')
time.sleep(2)
else:
print("No conversation history")
except slack_sdk.errors.SlackApiError as e:
print(e)
# If we found at least one - return True, if not - False
return any(message for message in real_messages)
max_retries = 1
retry_delay = 61
next_cursor = None
response = client.conversations_list(
exclude_archived=True,
limit=999,
types=["public_channel", "private_channel"]
)
for page in response:
print('Going to next page....')
for channel in page['channels']:
if not channel['is_member']:
for retry_count in range(max_retries):
try:
client.conversations_join(channel=channel['id'])
except slack_sdk.errors.SlackApiError as e:
print(f"Slack API error while joining channel {channel['name']}: {e.response['error']}")
if retry_count < max_retries - 1:
print(f"Retrying in {retry_delay} seconds...")
time.sleep(retry_delay)
else:
print("Max retries reached. Skipping this channel.")
continue
if channel_has_recent_messages(channel['id']):
print('#' + channel['name'] + ': looks active')
else:
print('There is no messages or threads found in #' + channel['name'])
print('#' + channel['name'] + ': archiving')
try:
for retry_count in range(max_retries):
try:
client.conversations_archive(channel=channel['id'])
post_archive_message(channel['name']) # Post the archive message
break
except slack_sdk.errors.SlackApiError as e:
print(f"Slack API error while archiving channel {channel['name']}: {e.response['error']}")
if retry_count < max_retries - 1:
print(f"Retrying in {retry_delay} seconds...")
time.sleep(retry_delay)
else:
print("Max retries reached. Skipping this channel.")
break # Skip to the next channel
except Exception:
print("There is no slack message")
Unfortunately during making this bot and trying everything i added so much Token scopes that i have no idea which really are needed and now im afraid to take them out, but In term of code itself this is the best way to go
from python-slack-sdk.
Hi, @rudykojot! Thank you for your question!
After taking a brief glance at your code and the error you received, I'm wondering what would happen if you tried to decrease the limit in the conversations_list
API call. As noted in the docs:
This method uses cursor-based pagination to make it easier to incrementally collect information. To begin pagination, specify a limit value under 1000. We recommend no more than 200 results at a time.
I recommend trying to reduce the limit and seeing if that affects the results at all!
from python-slack-sdk.
@hello-ashleyintech Hey thanks for suggestion but this makes only to code crash sooner
from python-slack-sdk.
The internal_error is totally Slack's server-side fault. If the error is temporarily occurring, adding ServerErrorRetryHandler
to your WebClient
instance may mitigate the issue. To learn how to enable it, please refer to the following resources:
- https://github.com/slackapi/python-slack-sdk/blob/v3.23.0/slack_sdk/http_retry/builtin_handlers.py#L92-L110
- https://slack.dev/python-slack-sdk/web/index.html#retryhandler
from python-slack-sdk.
@seratch Unfortunetly this also did not help. On one side i know that this error suggest that this is slack server fault however, before it also gave me this error and the problem was with wrong indentation in the code so it's tricky
from python-slack-sdk.
I remember that the server can return "internal_error" when it fails to handle an unexpected argument data while such a request should be responded as client error. So, you may be able to find a workaround by modifying some parts of your code. That being said, I cannot pinpoint the cause of your situation with currently given information.
I know this could be frustrating but please contact our customer support team with your app and workspace information. They can check the server-side logs and communicate with engineering teams for you.
from python-slack-sdk.
@seratch @hello-ashleyintech Little update after contacting slack support they responded me with those:
"I had a look in the logs for the past 7 days and the majority of the errors are related to conversations.replies being ratelimited. If you do reach the rate limit, then as mentioned in our Rate limit doc, you can rely on the Retry-After header to determine when you'll be able to send messages again:
https://api.slack.com/docs/rate-limits#headers
While rate limits cannot be increased, turned off, overridden, or otherwise changed, I would recommend implementing some kind of queueing system that handles the calls to keep below the rate limit.
Looking at conversations.list I see all the error=internal_error are related to status_true_error.keyword: Invalid encoded id Can you check that you are passing in correct data."
and another one after i tried implement some ratelimit logic and ask them if something changed:
"Not seeing any issues in relation to conversations.replies. I'm just seeing a few errors each day for conversations.list
error=internal_error Invalid encoded id
Are you validating your requests? Seems to be something invalid in your payload
https://api.slack.com/authentication/verifying-requests-from-slack#making__validating-a-request "
Anybody has some ideas how to fix it in my code?
from python-slack-sdk.
@seratch @hello-ashleyintech (another update) I will copy my message for slack support to save time maybe you have some idea on if we are right or maybe have some ideas to fix it, because i think me and my collogue found where the issue lies.
"Ok so after reviewing the code carefully with some support and investigating on when the code crushes i think the most possible reason it's that the "next_cursor" method in conversations.list doesn't work properly, This is most possible because if we change the limit for 10 it crashes after 10, if we change it to 999 it crashes after 999, so there is no problem with specific channels there is a problem with reaching next pagination and since the max limit is 999 and we have over 4000 channels it will never gonna clean all of them, So my question is is it possible that my code or bot settings are lacking something to reach next pagination or is it problem or slack_sdk client side and now we have to wait until it get fixed. It might be helpful to add that we are able to "extract" next cursor value so most likely code logic is correct."
from python-slack-sdk.
I am not sure if this could be helpful for you, but this SDK provides an easy to paginate this way: https://github.com/slackapi/python-slack-sdk/blob/v3.23.0/tests/slack_sdk/web/test_web_client.py#L47-L52 Relying on the built-in feature instead of trying to do pagnation on your own may help.
from python-slack-sdk.
Related Issues (20)
- files_upload() initial_comment isn't formatted (regression) when posting a Slack post HOT 5
- Download file using WebClient HOT 1
- Add MongoDB installation store HOT 2
- Happy Holidays! ❄️ ⏳ The team will be on break from Dec 22nd 2023 to Jan 3rd 2024
- Built-in InstallationStores fail to resolve a valid bot token when both bot and user-only installations co-exist in database tables HOT 2
- block/type/image should allow image_url to reference an uploaded file to Slack without having to make it public HOT 2
- aiohttp based socket_mode failed to reconnect and enter a broken state HOT 6
- Add "slack_file" properties to "image" blocks/elements under slack_sdk.models
- Option to block link url preview HOT 1
- Append `thread_ts` to the payload of a lazy listener in Slash Commands HOT 2
- What is 'Received a response in a non-JSON format' in chat.update HOT 3
- Can't install async (optional) dependencies in 3.26.2 HOT 1
- VSCode (with jedi) can't suggest imports beyond base level of package HOT 5
- [error ] Failed to receive or enqueue a message: TypeError, object of type 'NoneType' has no len() HOT 1
- I am trying to post a message to slack along with a attachment i am getting error as The server responded with: {'ok': False, 'error': 'channel_not_found'} HOT 4
- Unpredictable behaviour using .files_upload_v2 HOT 3
- websocket_client-based SocketModeClient does not reconnect after a DNS outage HOT 1
- ModuleNotFoundError: no module named 'slack' HOT 14
- client.files_upload_v2 complains about channel not found but client.files_upload works. HOT 4
- `RichTextElement.elements` items are never promoted to a proper Python object type HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from python-slack-sdk.