i'm trying to use telethon to send messages to telegram groups. after some times runing, it reruens:
A wait of 16480 seconds is required (caused by ResolveUsernameRequest).
the code is:
async def main():
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
config = configparser.ConfigParser()
config.read("seetings.ini",encoding= 'utf-8')
message = config['Customer']['message']
internal = config['Customer']['internal']
count = 0
excel_data = pandas.read_excel('tg_groups.xlsx', sheet_name='Groups')
for column in excel_data['GroupUsername'].tolist():
try:
if str(excel_data['GroupUsername'][count]) == 'None':
count += 1
continue
else:
chat = await client.get_input_entity(str(excel_data['GroGroupUsernameupID'][count]))
await client.send_message(entity=chat, message=message)
except Exception as e:
print(e)
time.sleep(int(internal))
count = count + 1
continue
time.sleep(int(internal))
count = count + 1
if __name__ == '__main__':
if proxytype == 'HTTP':
print('HTTP')
client = TelegramClient('phone'+phone, api_id, api_hash, proxy=(socks.HTTP, 'localhost', int(proxyport))).start()
if proxytype == 'socks5':
print('SOCKS5')
client = TelegramClient('phone'+phone, api_id, api_hash, proxy=(socks.SCOKS5, 'localhost', int(proxyport))).start()
myself = client.get_me()
print(myself)
freqm = config['Customer']['freq']
print(int(freqm))
while True:
with client:
client.loop.run_until_complete(main())
time.sleep(int(freqm))`
`
from the 'Entity' guide, it says get_input_entity method will search the user info from session file cache, why it it still call the 'ResolveUsernameRequest'to get the user info? anything i missed?
thanks for any advice.
'Entity' guide, it says get_input_entity method will search the user info from session file cache, why it it still call the 'ResolveUsernameRequest'to get the user info? anything i missed or the session file didn't keep the user info cache?
Since I am writing a client, my friends from the USA noticed that the code does not go through SMS, but only through a call. but I don’t understand how to do it, how to request a call(
await client.connect()
code_settings = types.CodeSettings(
current_number=True,
allow_flashcall=False,
allow_app_hash=False
)
result = await client(functions.auth.SendCodeRequest(
phone_number=phone,
api_id=api_id,
api_hash=api_hash,
settings=code_settings
))
# time.sleep(10)
result = await client(functions.auth.ResendCodeRequest(
phone_number=phone,
phone_code_hash=result.phone_code_hash
))
# time.sleep(20)
result = await client(functions.auth.ResendCodeRequest(
phone_number=phone,
phone_code_hash=result.phone_code_hash
))
# result = await client(SentCodeTypeCall(5))
# result = await client(functions.auth.)
while not isinstance(result.type, SentCodeTypeCall):
# time.sleep(10)
result = await client(functions.auth.ResendCodeRequest(
phone_number=phone,
phone_code_hash=result.phone_code_hash
))
# time.sleep(20)
# await client(functions.auth.SendCodeRequest(
# phone_number=phone,
# api_id=api_id,
# api_hash=api_hash,
# settings=code_settings
# ))
def code_callback():
code = input('Please enter the code you received: ')
return code
time.sleep(5)
await client.start(phone=phone, code_callback=code_callback)
I assume this is not the correct code.
can I tell the SendCode Request method to call immediately without sending SMS?
I want to setup a consumer with amqp to read from a specific queue. Some googling pointed out that this can be done with amqp_basic_get, and looking into the documentation, the actual message is retrieved with amqp_read_message. I also found this example which I tried to follow for implementing the basic_get. Nevertheless, I am failing to get and read a message from a specific queue.
My scenario is like this: I have two programs that communicate by publishing and consuming from the rabbitmq server. In each, a connection is declared, with two channels, one meant for consuming, and one for publishing. The flow of information is like this: program A gets the current time and publishes to rabbitmq. Upon receiving this message, program B gets its own time, packages its time and the received time in a message that it publishes to rabbitmq. Program A should consume this message. However, I cannot succeed in reading from the namedQueue.
Program A (in c++, and uses the amqp.c) is implemented as follows:
... after creating the connection
//Create channels
amqp_channel_open_ok_t *res = amqp_channel_open(conn, channelIDPub);
assert(res != NULL);
amqp_channel_open_ok_t *res2 = amqp_channel_open(conn, channelIDSub);
assert(res2 != NULL);
//Declare exchange
exchange = "exchangeName";
exchangetype = "direct";
amqp_exchange_declare(conn, channelIDPub, amqp_cstring_bytes(exchange.c_str()),
amqp_cstring_bytes(exchangetype.c_str()), 0, 0, 0, 0,
amqp_empty_table);
...
throw_on_amqp_error(amqp_get_rpc_reply(conn), printText.c_str());
//Bind the exchange to the queue
const char* qname = "namedQueue";
amqp_bytes_t queue = amqp_bytes_malloc_dup(amqp_cstring_bytes(qname));
amqp_queue_declare_ok_t *r = amqp_queue_declare(
conn, channelIDSub, queue, 0, 0, 0, 0, amqp_empty_table);
throw_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue");
if (queue.bytes == NULL) {
fprintf(stderr, "Out of memory while copying queue name");
return;
}
amqp_queue_bind(conn, channelIDSub, queue, amqp_cstring_bytes(exchange.c_str()),
amqp_cstring_bytes(queueBindingKey.c_str()), amqp_empty_table);
throw_on_amqp_error(amqp_get_rpc_reply(conn), "Binding queue");
amqp_basic_consume(conn, channelIDSub, queue, amqp_empty_bytes, 0, 0, 1,
amqp_empty_table);
throw_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming");
// ...
// In order to get a message from rabbitmq
amqp_rpc_reply_t res, res2;
amqp_message_t message;
amqp_boolean_t no_ack = false;
amqp_maybe_release_buffers(conn);
printf("were here, with queue name %s, on channel %d\n", queueName, channelIDSub);
amqp_time_t deadline;
struct timeval timeout = { 1 , 0 };//same timeout used in consume(json)
int time_rc = amqp_time_from_now(&deadline, &timeout);
assert(time_rc == AMQP_STATUS_OK);
do {
res = amqp_basic_get(conn, channelIDSub, amqp_cstring_bytes("namedQueue"), no_ack);
} while (res.reply_type == AMQP_RESPONSE_NORMAL &&
res.reply.id == AMQP_BASIC_GET_EMPTY_METHOD
&& amqp_time_has_past(deadline) == AMQP_STATUS_OK);
if (AMQP_RESPONSE_NORMAL != res.reply_type || AMQP_BASIC_GET_OK_METHOD != res.reply.id)
{
printf("amqp_basic_get error codes amqp_response_normal %d, amqp_basic_get_ok_method %d\n", res.reply_type, res.reply.id);
return false;
}
res2 = amqp_read_message(conn,channelID,&message,0);
printf("error %s\n", amqp_error_string2(res2.library_error));
printf("5:reply type %d\n", res2.reply_type);
if (AMQP_RESPONSE_NORMAL != res2.reply_type) {
printf("6:reply type %d\n", res2.reply_type);
return false;
}
payload = std::string(reinterpret_cast< char const * >(message.body.bytes), message.body.len);
printf("then were here\n %s", payload.c_str());
amqp_destroy_message(&message);
Program B (in python) is as follows
#!/usr/bin/env python3
import pika
import json
from datetime import datetime, timezone
import time
import threading
cosimTime = 0.0
newData = False
lock = threading.Lock()
thread_stop = False
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
connectionPublish = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channelConsume = connection.channel()
channelPublish = connectionPublish.channel()
print("Declaring exchange")
channelConsume.exchange_declare(exchange='exchangeName', exchange_type='direct')
channelPublish.exchange_declare(exchange='exchangeName', exchange_type='direct')
print("Creating queue")
result = channelConsume.queue_declare(queue='', exclusive=True)
queue_name = result.method.queue
result2 = channelPublish.queue_declare(queue='namedQueue', exclusive=False, auto_delete=False)
channelConsume.queue_bind(exchange='exchangeName', queue=queue_name,
routing_key='fromB')
channelPublish.queue_bind(exchange='exchangeName', queue="namedQueue",
routing_key='toB')
print(' [*] Waiting for logs. To exit press CTRL+C')
def callbackConsume(ch, method, properties, body):
global newData, cosimTime
print("\nReceived [x] %r" % body)
#cosimTime = datetime.datetime.strptime(body, "%Y-%m-%dT%H:%M:%S.%f%z")
with lock:
newData = True
cosimTime = body.decode()
cosimTime = json.loads(cosimTime)
#print(cosimTime)
def publishRtime():
global newData
while not thread_stop:
if newData:
#if True:
with lock:
newData = False
msg = {}
msg['rtime'] = datetime.now(timezone.utc).astimezone().isoformat(timespec='milliseconds')
msg['cosimtime'] = cosimTime["simAtTime"]
print("\nSending [y] %s" % str(msg))
channelPublish.basic_publish(exchange='exchangeName',
routing_key='toB',
body=json.dumps(msg))
#time.sleep(1)
channelConsume.basic_consume(
queue=queue_name, on_message_callback=callbackConsume, auto_ack=True)
try:
thread = threading.Thread(target = publishRtime)
thread.start()
channelConsume.start_consuming()
except KeyboardInterrupt:
print("Exiting...")
channelConsume.stop_consuming()
thread_stop = True
connection.close()
What program A outputs is:
amqp_basic_get error codes amqp_response_normal 1, amqp_basic_get_ok_method 3932232
which is the code for AMQP_BASIC_GET_EMPTY_METHOD.
Program B gets the data, and publishes continuously.
If I slightly modify B to just publish all the time a specific string, then it seems that the amqp_basic_get returns successfully, however then it fails at amqp_read_message with the code AMQP_RESPONSE_LIBRARY_EXCEPTION.
Any idea how to get this to work, what I am missing the setup?
The issue was in the queue_declare where the auto_delete parameter was not matching on both sides.
server
I have tried almost everything to receive text from python
I don't know where the problem comes from from the client or from the server
try:
llamadacod = self.request.recv(1024)
llamada = self.decode(llamadacod)
print(f"{color.A}{llamada}")
time.sleep(0.1)
if llamada == "conectado":
msg = "Hello"
msgcod = self.encode(msg)
print(f"{color.G}{msg}")
self.request.send(msgcod)
client
val thread = Thread(Runnable {
try{
val client = Socket("localHost",25565)
client.setReceiveBufferSize(1024)
client.outputStream.write("conectado".toByteArray())
val text = InputStreamReader(client.getInputStream())
recibir = text.toString()
client.outputStream.write("Client_desconect".toByteArray())
client.close()
I already solved it, the solution was very simple, you just had to ensure that both the server and the client would occupy the same way of communicating
client :
val input = DataInputStream(client.getInputStream())
id = input.readUTF()
server:
self.request.send(len(msg).to_bytes(2, byteorder='big'))
self.request.send(msg)
We are on: akka-stream-experimental_2.11 1.0.
Inspired by the example
We wrote a TCP receiver as follows:
def bind(address: String, port: Int, target: ActorRef)
(implicit system: ActorSystem, actorMaterializer: ActorMaterializer): Future[ServerBinding] = {
val sink = Sink.foreach[Tcp.IncomingConnection] { conn =>
val serverFlow = Flow[ByteString]
.via(Framing.delimiter(ByteString("\n"), maximumFrameLength = 256, allowTruncation = true))
.map(message => {
target ? new Message(message); ByteString.empty
})
conn handleWith serverFlow
}
val connections = Tcp().bind(address, port)
connections.to(sink).run()
}
However, our intention was to have the receiver not respond at all and only sink the message. (The TCP message publisher does not care about response ).
Is it even possible? to not respond at all since akka.stream.scaladsl.Tcp.IncomingConnection takes a flow of type: Flow[ByteString, ByteString, Unit]
If yes, some guidance will be much appreciated. Thanks in advance.
One attempt as follows passes my unit tests but not sure if its the best idea:
def bind(address: String, port: Int, target: ActorRef)
(implicit system: ActorSystem, actorMaterializer: ActorMaterializer): Future[ServerBinding] = {
val sink = Sink.foreach[Tcp.IncomingConnection] { conn =>
val targetSubscriber = ActorSubscriber[Message](system.actorOf(Props(new TargetSubscriber(target))))
val targetSink = Flow[ByteString]
.via(Framing.delimiter(ByteString("\n"), maximumFrameLength = 256, allowTruncation = true))
.map(Message(_))
.to(Sink(targetSubscriber))
conn.flow.to(targetSink).runWith(Source(Promise().future))
}
val connections = Tcp().bind(address, port)
connections.to(sink).run()
}
You are on the right track. To keep the possibility to close the connection at some point you may want to keep the promise and complete it later on. Once completed with an element this element published by the source. However, as you don't want any element to be published on the connection, you can use drop(1) to make sure the source will never emit any element.
Here's an updated version of your example (untested):
val promise = Promise[ByteString]()
// this source will complete when the promise is fulfilled
// or it will complete with an error if the promise is completed with an error
val completionSource = Source(promise.future).drop(1)
completionSource // only used to complete later
.via(conn.flow) // I reordered the flow for better readability (arguably)
.runWith(targetSink)
// to close the connection later complete the promise:
def closeConnection() = promise.success(ByteString.empty) // dummy element, will be dropped
// alternatively to fail the connection later, complete with an error
def failConnection() = promise.failure(new RuntimeException)