How can wait my Telegram Bot for a incoming message? - php

How can I let interact my Telegram Bot with Users? E.g.:
User: /buy
Bot: What do you want to buy?
User: Icecream
Bot: You have successfully bought Icecream!
So how can I do this?
switch($message) {
[...]
case "/buy":
sendMessage($chatID, "What do you want to buy?");
//Here I need your help :D
break;
}

Assuming you are using a webhook to receive updates, your php script runs again on every update you are receiving.
In this case, you will need to save a certain "status" of the user which you are checking everytime your bot receives a message to indicate what you have to do next.
An example would be:
switch($message) {
case "/buy":
sendMessage($chatID, "What do you want to buy? Icecream, Water or Sprite?");
$storage[$chatID]['status'] = 'awaitingProductChoice';
saveStorage();
break;
}
You need to save $storage[$userId] somehow (saveStorage();). Ideally would be to use a database, if you haven't got one, use file_put_contents('storage.json', json_encode($storage)); or something similar to serialize it. SESSIONS won't work, since Telegram Servers do not send cookies.
Then place some similar code before your switch statement:
$storage = readStorage(); // load from DB or file_get_contents from file
if ($storage[$chatID]['status'] === 'awaitingProductChoice') {
// return " You have successfully bought Icecream!"
$storage[$chatID]['product choice'] = $message['text'];
} else if ($storage[$chatID]['status'] === 'other stuff') {
// other step
}
else switch($message) [...]

Related

PHP - Telegram Bot interactive query

I'm trying to query some data from my database. there is three option for searching data from database
User id
Phone no.
E-mail
I've created an inline keyboard by choosing a search option from the above list
Screenshot of bot chat
I'm looking for a solution where if I choose user_id then the bot will ask me to insert user_id. And will accept the only user_id as input. otherwise, it will return with an error message.
if I choose email from the inline keyboard at that time bot will accept only email that time. other bot commands will not be accepted until any error or success is returned from the bot.
I'm using Laravel as my backend.
You should have a column called state for each user_id.
And when you receive any message you should check the state before responding.
So, This is pseudo-code:
$Bot = new TelegramBot(getenv('BOT_TOKEN'));
function MessageHandler($message)
{
$state = DB::table('users')->row(['user_id' => $message->from->id])->column('state');
if ($state === false)
{
# Create new row for this user..
}
switch ($state)
{
case 'SEARCHING_BY_ID':
# Check if message is number
break;
case 'SEARCHING_BY_PHONE':
# Check if message is phone number
break;
case 'SEARCHING_BY_MAIL':
# Check if message is E-mail
break;
default:
# Now you should process by any command
break;
}
}
$Bot->OnMessage(MessageHandler);

call recording using twilio proxy api

I am doing communication between two people using Twilio proxy when any customer replies to my Twilio proxy reserved number, then the session will create and the session will handle all communication "SMS as well as call" how can I record call in this scenario.
When i am adding Twilio number to proxy pool, the "call comes in" and "message comes in" URL is changed to proxy service name.
Thanks
I found a pretty good project that examples that! And the best part is that really works very well!
Basically, you only need to set up the webhooks when a call is made and on this webhook you call the processRecordCall :D
The method is here:
async function processRecordCall(req){
let callSID = req.body.inboundResourceSid;
console.log(req.body.inboundResourceSid);
console.log(req.body.inboundResourceStatus);
console.log(req.body.outboundResourceStatus);
//The only Proxy callback we care about is the one that provides us context for the initiated outbound dial. We will ignore all other callbacks (including those with context for SMS). Alternatively and depending on the use case, we could use the Proxy "Intercept" callback, but this has additional requirements for handling error status.
if(req.body.outboundResourceStatus == "initiated")
{
//Get all recordings for a given call.
let recordings = await client.recordings.list({callSid: callSID});
console.log(recordings.length);
//We only want to start recording if there are no existing recordings for this callSid. *This may be overkill as I haven't hit this edge case. Consider it preventitive for now*
if(recordings.length == 0)
{
let recordingSet = false;
let callStatus = "";
//Self-invoking function to facilitate iterative attempts to start a recording on the given call. See example here: https://stackoverflow.com/a/3583740
(function tryRecord (i) {
setTimeout(async function () {
if(!recordingSet && i > 0)
{
console.log(`I is ${i}`);
//Fetch the call to see if still exists (this allows us to prevent unnecessary attempts to record)
//Prod code probably needs callback or async added to ensure downstream execution is as expected
let call = await client.calls(callSID).fetch();
callStatus = call.status;
//Only attempt to create the recording if the call has not yet completed
if(callStatus != "completed")
{
//Try to create the recording
try{
let result = await axios.post(`https://api.twilio.com/2010-04-01/Accounts/${accountSid}/Calls/${callSID}/Recordings.json`, {},
{
auth: {
username: accountSid,
password: authToken
}
});
//This code assumes an HTTP 201 *Created* status and thus sucessful creation of recording. Production code may need to explicitly ensure HTTP 201 (eg. handle any other possible status')
console.log(`statusCode: ${result.status}`);
recordingSet = true; //This isn't entirely necessary (eg. could just set i=1 to force stop iteration), but I'm making an assumption that most use cases will prefer having this for reporting purposes
} catch(err){
//TODO(?) - There may be specific errors that should be explicitly handeled in a production scenario (eg. 21220)
}
}
else //The call is completed, so there's no need to loop anymore
{
console.log("Force stop iteration");
i = 1; //Set i = 1 to force stop the iteration
}
}
if (--i || !recordingSet) tryRecord(i); // decrement i and call myLoop again if i > 0 or if recording is not set
}, 1000) //NOTE: 1 second time delay before retry (this can be whatever works best --responsibly-- for the customer)
})(15); //NOTE: 15 attempts to record by default (unless forced to stop or recording already started. This can be whatever works best --responsibly-- for the customer)
}
else
{
console.log("recording exists already");
}
}
else
{
console.log(`We ignored callback with outgoing status '${req.body.outboundResourceStatus}'`);
}
}
I'm linking the full project below
https://github.com/Cfee2000/twilio-proxy-admin-app

Bot Telegram php: Conversation with a specific user

After this step:
if($message == "Bot copy me")
{
sendMessage($chatid, "Sure?");
}
How a bot can reply to this specific user that said "Bot copy me" if he say "yes", for example, and copy him until he say "stop" ?
You have to use your own database. If you don't have one, the easiest way is use file.
For instance, use file_get_contents("/tmp/tg-bot-{$chatid}-status") to get status. When received Sure, use file_put_contents("/tmp/tg-bot-{$chatid}-status", "REPLY") to set.

create rtmp stream after approval in flash

Is it possible to create a netstream after the user has approved to the use off the cam?
I ask this because i want to be able to detect if a user is actually transmitting so other people can see that their cam is on.
Right now the stream gets created after hitting play while approval has not be given yet.
Is it perhaps possible to send something along with hitting the allow/deny?
I'm using AS2 with RED5.
found the answer:
Cam.onStatus = function(infoObj:Object) {
switch (infoObj.code) {
case 'Camera.Muted' :
trace("Camera access is denied");
break;
case 'Camera.Unmuted' :
send_data.camuser =user;
send_data.camon = "PRIVATE";
break;
}
}

How to user predis for publish more than one time

How can I publish info between the clients more than once?
I mean when I publish info from one user to other, he receives and backwards, but this is only once.
Because when one user send something to the other, the GET is being loaded and the receiving stops, how can I make it that way so the clients receives forever, not only once?
How pub/sub works: like a channel, you put from one side and you get the same from the other side.
So publisher data will be received only when there is some subscriber for it.
Use pubSub context and subscribe to a channel say "x" and from another side, keep taking the data, say from User, and publish it using publish command every time to the same channel.
Subscriber:
$redis = new Predis\Client(// put setting here, if req);
$pubsub = $redis->pubSub();
$pubsub->subscribe($channel1);
foreach ($pubsub as $message)
{
switch ($message->kind) {
case 'subscribe':
echo "Subscribed to {$message->channel}\n";
break;
case 'message':
// do something
break;
}
}
Publisher:
while(1) // or whatever condition
{
$redis->publish($channel2, $userdata);
}
You can use chat messages to break the connection, e.g. publish exit and check at subscriber if exit then close the connection and then check at publisher side if no subscriber attached, close it too.

Categories