AWS SQS FIFO Received message was empty - python-3.x

I'm learning AWS SQS and I've sent 1 messages to a FIFO queue. But when I try to receive messages, I cant get meesage.
What is my mistake?
Senders code (lambda-function)
XURL=quote(URL)
client = boto3.client('sqs')
url_fifo = 'https://sqs.xxxxxx.com/xxxxxx/que.fifo'
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
response = client.send_message(
QueueUrl=url_fifo,
MessageBody=f'URL: {XURL}, EventTime: {now}',
MessageDeduplicationId=str(time.time_ns()),
MessageGroupId='Group1'
)
Receivers code (lambda-function)
name = 'que.fifo'
sqs = boto3.resource('sqs')
url_fifo = 'https://sqs.xxxxxx.amazonaws.com/xxxxxxx/que.fifo'
queue = sqs.get_queue_by_name(QueueName=name)
msg_list = queue.receive_messages(QueueUrl=url_fifo, MaxNumberOfMessages=1)
print(msg_list)
if msg_list:
for message in msg_list:
print(message.body)
URL=message.body
message.delete()
else:
print("no message")
result log
2023-02-07T13:47:50.326+09:00 []
2023-02-07T13:47:50.326+09:00 no message

You are calling the Queue object receive_messages method, but passing parameters expected by the client object receive_message method. Check out the two hyperlinks, I have linked them accordingly to different sections in the documentation.
Therefore, your code should be
client = boto3.client('sqs')
url_fifo = 'https://sqs.xxxxxx.amazonaws.com/xxxxxxx/que.fifo'
msg_list = client.receive_message(QueueUrl=url_fifo, MaxNumberOfMessages=1)

Related

Getting not persistent messages from nats.io server

My question is simple:
Now this code sends empty message to subject chan.01.msg and gets message that is being currently broadcasted or prints nats: timeout. Altogether this request message is also shown (something like: Received a message on chan.01.msg _INBOX.<hash_my>.<salt_up>: b'') on subject and is not desirable there. I do filter it in callback, but I really feel that it's kinda wrong way to do it.
Can I just pull messages with desired subject?
async def msgcb(msg):
"""
Message callback function
"""
subject = msg.subject
reply = msg.reply
data = msg.data
if len(data) > 0:
print(f"Received a message on {subject} {reply}: {data}")
logging.debug("Prepare to subscribe")
sub = await nc.subscribe(subject="chan.01.msg", cb=msgcb)
logging.debug("loop process messages on subject")
while True:
await asyncio.sleep(1)
try:
resp = await nc.request('chan.01.msg')
print(resp)
except Exception as e:
print(e)
You are subscribing to the same subject where you are publishing so naturally would get the message when sending a request. To avoid receiving messages the same client produces you can use the no_echo option on connect.

Gmail API: How to move a draft into INBOX, like we can do in Gmail UI

The Gmail API docs states that
Messages and threads can have multiple labels associated with them; however, draft messages cannot have labels applied to them.
However, we can move a draft to inbox using Gmail web UI.
I would like to do the same thing using API. How can this be done?
Thanks to #DalmTo, I found a solution as below.
message = email.mime.text.MIMEText("This is the body")
message['to'] = "to#example.com"
message['from'] = "to#subject.com"
message['subject'] = "Test draft"
payload1 = {"message": {
"raw": base64.urlsafe_b64encode(message.as_bytes()).decode("utf-8"),
# "labelIds": ["INBOX"] # This will cause an error
}}
res1 = google.post("/gmail/v1/users/me/drafts", json=payload1)
payload2 = {"addLabelIds": ["INBOX"], "removeLabelIds":[]}
thread_id = res1.json()["message"]["threadId"]
res2 = google.post(f"/gmail/v1/users/me/threads/{thread_id}/modify", json=payload2)
# Or (both works)
# message_id = res1.json()["message"]["id"]
# res2 = google.post(f"/gmail/v1/users/me/messages/{thread_id}/modify", json=payload2)

Easy integration of chatbot with slack-app

I have a ChatBot application running, just want to hook this application with Slack-api as it's interface.
I used Slack RTM and maintained user-session with its slack user-id.
finally solved and written a client(API) which can easily connect to any conversation engine.
Github repo link-
https://github.com/csemanmohan/Slack_api_client
import time
import re
from slackclient import SlackClient
import requests
# 'url', chatbot endpoint and 'slack_token' is slack application user-access-token
url = "http://127.0.0.1:****/*******/v2/api"
slack_token = "xoxb-**********-***********-*************lipO8hoI"
# instantiate Slack client
slack_client = SlackClient(slack_token)
# starterbot's user ID in Slack: value is assigned after the bot starts up
starterbot_id = None
# constants
RTM_READ_DELAY = 1 # 1 second delay between reading from RTM
EXAMPLE_COMMAND = "do"
MENTION_REGEX = "^<#(|[WU].+?)>(.*)"
def parse_bot_commands(slack_events):
"""
Parses a list of events coming from the Slack RTM API to find bot commands.
If a bot command is found, this function returns a tuple of command and channel.
If its not found, then this function returns None, None.
"""
# below var msg and channel_var will be used/
# when no trigger(#app-name) passed from application
msg = ""
channel_def = ""
for event in slack_events:
if event["type"] == "message" and not "subtype" in event:
msg = event["text"]
channel_def = event["channel"]
user_id, message = parse_direct_mention(event["text"])
print("there is an event here...", user_id, message)
if user_id == starterbot_id:
return message, event["channel"]
channel_def = channel_def
return msg, channel_def
def parse_direct_mention(message_text):
"""
Finds a direct mention (a mention that is at the beginning) in message text
and returns the user ID which was mentioned. If there is no direct mention, returns None
"""
matches = re.search(MENTION_REGEX, message_text)
# the first group contains the username, the second group contains the remaining message
return (matches.group(1), matches.group(2).strip()) if matches else (None, None)
def handle_command(command, channel):
"""
Executes bot command if the command is known
"""
# Default response is help text for the user
default_response = "Not sure what you mean. Try *{}*.".format(EXAMPLE_COMMAND)
# Implemented below code-snippet for making API call to ChatBot
input_text = command
payload = {"text": input_text, "email": "manmohan#m******.com"}
headers = {'content-type': "application/json"}
resp = requests.request("POST", url, json=payload, headers=headers)
result = eval(resp.json())
print("result is: ", result)
response = result['text']
# Sends the response back to the channel
slack_client.api_call(
"chat.postMessage",
channel=channel,
text=response or default_response
)
if __name__ == "__main__":
if slack_client.rtm_connect(with_team_state=False):
print("Starter Bot connected and running!")
# Read bot's user ID by calling Web API method `auth.test`
starterbot_id = slack_client.api_call("auth.test")["user_id"]
while True:
command, channel = parse_bot_commands(slack_client.rtm_read())
if command:
handle_command(command, channel)
time.sleep(RTM_READ_DELAY)
else:
print("Connection failed. Exception traceback printed above.")

How to parse the gmail messages.get() batch response in python 3

I have batched and executed my request using the following code:
batch = BatchHttpRequest()
for msg_id in message_ids:
batch.add(service.users().messages().get(userId = 'me', id = msg_id['id']), callback = mycallbackfunc)
batch.execute()
How can I access the responses for each of the requests? I have looked through the documentation but there is no public method to get the responses.
You access the response of each request in the callback function, which is called mycallbackfunc in your example:
def process_message(request_id, response, exception):
if exception is not None:
# Do something with the exception
pass
else:
# Do something with the response
pass
batch = BatchHttpRequest()
for msg_id in message_ids:
batch.add(service.users().messages().get(userId = 'me', id = msg_id['id']), callback=process_message)
batch.execute()

How to receive messages from dead letter queue from azure service bus queue

I have a queue and when I send messages to that queue I see most of the messages are going to its dead letter queue. I want to re submit them to the same queue..
It would be very helpful to me if anyone could suggest me any solution.
One possible way is to Receive the messages from the dead letter queue and send them to the normal queue.
Python Code
Step-1: Receive the messages from the dead letter queue:
from azure.servicebus import ServiceBusClient
import json
connectionString = "Your Connection String to Service Bus"
serviceBusClient = ServiceBusClient.from_connection_string(connectionString)
queueName = "Your Queue Name created in the Service Bus"
queueClient = serviceBusClient.get_queue(queueName)
with queueClient.get_deadletter_receiver(prefetch=5) as queueReceiver:
messages = queueReceiver.fetch_next(timeout=100)
for message in messages:
# message.body is a generator object. Use next() to get the body.
body = next(message.body)
# Store the body in some list so that we can send them to normal queue.
message.complete()
Step-2: Send the messages to the normal queue:
from azure.servicebus import ServiceBusClient, Message
connectionString = "Your Service Bus Connection String"
serviceBusClient = ServiceBusClient.from_connection_string(connectionString)
queueName = "Your Queue name"
queueClient = serviceBusClient.get_queue(queueName)
messagesToSend = [<List of Messages that we got from the dead letter queue>]
with queueClient.get_sender() as sender:
for msg in messagesToSend:
sender.send(Message(msg))
Hope this helps.
Here is the sample code to read message in deadletter
from azure.servicebus import ServiceBusClient
CONNECTION_STR = "connection string"
servicebus_client = ServiceBusClient.from_connection_string(conn_str=CONNECTION_STR, logging_enable=True)
queueName ="Queue name"
with servicebus_client:
# get the Queue Receiver object for the queue
receiver = servicebus_client.get_queue_receiver(queue_name=queueName,sub_queue="deadletter")
with receiver:
for msg in receiver:
print("Received: " + str(msg))
# complete the message so that the message is removed from the queue
receiver.complete_message(msg)

Resources