I have such a code snippet in a Telegram bot in php
case $message == '/nitromonth' || $data_2['callback_query']['data'] == '/nitromonth':
$chat_id = $data['from']['id'];
$method = 'Send a message';
$send_data = [
'text' => $nitromonth,
'reply_markup' => [
'inline_keyboard' => [
[
[
"text" => $translations['ButtonBuy'][$lang],
"callback_data" => '/buy_first_packet_ds'
],
[
"text" => $translations['Repurchase'][$lang],
"callback_data" => '/discord'
],
],
[
[
"text" => $translations['BackCat'][$lang],
"callback_data" => '/products'
],
],
]
]
];
break;
It calls a message with such buttons on command, is there any way to create a .config file for the bot, where it will indicate, for example:
"button[number]" "/commands"
Where [Number] is the ordinal number, 1, 2, 3.. 10, etc.
Where /commands is a command, as indicated in the line
case $message == '/nitromonth' ||$data_2['callback_query']['data'] == '/nitromonth':
there can be nth number of such lines in cfg, each new line generates code above itself when the bot starts, without creating 1000 lines with the same the same code
I'm not a very good php developer, so I'm asking for help
Related
I'm having a hard time using a method setData() of the HttpBody class. I'm passing the parameter to the method as an object, but I recieve an error message.
How do I pass the parameter:
public function create(string $resource, $body)
{
$client = $this->googleClient();
$service = new CloudHealthcare($client);
$parent = "projects/my_project_id/locations/my_location/datasets/my_dataset/fhirStores/repository";
$httpBody = new HttpBody();
$httpBody->setContentType('application/fhir+json;charset=utf-8');
$httpBody->setData([
"resourceType" => "Patient",
"id" => "23434",
"meta" => [
"versionId" => "12",
"lastUpdated" => "2014-08-18T15:43:30Z"
],
"text" => [
"status" => "generated",
"div" => "<!-- Snipped for Brevity -->"
],
"extension" => [
[
"url" => "http://example.org/consent#trials",
"valueCode" => "renal"
]
],
"identifier" => [
[
"use" => "usual",
"label" => "MRN",
"system" => "http://www.goodhealth.org/identifiers/mrn",
"value" => "123456"
]
],
"name" => [
[
"family" => [
"Levin"
],
"given" => [
"Henry"
],
"suffix" => [
"The 7th"
]
]
],
"gender" => [
"text" => "Male"
],
"birthDate" => "1932-09-24",
"active" => true
]);
$data = $service->projects_locations_datasets_fhirStores_fhir->create($parent, $resource, $httpBody);
return $data;
}
Following the error message I get.
The error says I didn't pass the resourceType field, but it was passed:
Google\Service\Exception: {
"issue": [
{
"code": "structure",
"details": {
"text": "unparseable_resource"
},
"diagnostics": "missing required field \"resourceType\"",
"expression": [
""
],
"severity": "error"
}
],
"resourceType": "OperationOutcome"
} in file /usr/share/nginx/vendor/google/apiclient/src/Http/REST.php on line 128
How should I pass the parameter to receive the success message?
Tkanks!
I haven't tried the PHP client libraries specifically, but for most languages you don't want to use the HttpBody class - it's an indication that the method accepts something in the body of the request that is just text from the perspective of the method signature. I would try passing the JSON string directly.
this question was asked before and was ignored, if you have a solution for it then your contribution is valuable, is there any way to change the default sound of the FCM notification if I'm using the below code, changing "sound"=>"arrive" to soundtrack path is not working?
thank you
public function toFcm($notifiable) {
$message = new FcmMessage();
$notification = [
'body' => trans('lang.notification_your_order', ['parcel_id' => $this->parcel->id, 'order_status' => $this->parcel->parcelStatus->status]),
'image' => Config::get('app.url').'/uploads/parcel.png',
'icon' => Config::get('app.url').'/uploads/parcel.png',
"title" => "Order Updated",
"content_available" => true,
"priority" => "high",
"sound"=>"arrive",
'id' => 'orders',
];
$data = [
'click_action' => "FLUTTER_NOTIFICATION_CLICK",
'id' => 'orders',
'status' => 'done',
'message' => $notification,
];
$message->content($notification)->data($data)->priority(FcmMessage::PRIORITY_HIGH);
return $message;
}
Ensure that the name of the sound matches the name of the sound installed inside the res/raw folder, then ensure your request is correctly formatted
example: "filename.mp3"
{
"token": "client_notification_token", <- or topic
"notification": {
"title": "Push notification title",
"body": "Push body",
"sound": "filename", <-- points to src/res/raw/filename.mp3
}
...
}
Source: https://medium.flatstack.com/migrate-to-api-26-push-notifications-with-custom-sound-vibration-light-14846ebc9e96
I'm trying to secure my callback url when completed event is triggered.
My Controller:
public function callbackSubscriptionCompleted(
int $subscriptionId,
DocusignService $docusignService,
Request $request
) {
$signature = $request->headers->get("X-DocuSign-Signature-1");
$payload = file_get_contents('php://input');
$isValid = $docusignService->isValidHash($signature, $payload);
if (!$isValid) {
throw new ApiException(
Response::HTTP_BAD_REQUEST,
'invalid_subscription',
'Signature not OK'
);
}
return new Response("Signature OK", Response::HTTP_OK);
}
My DocusignService functions:
private function createEnvelope(Company $company, Subscription $subscription, LegalRepresentative $legalRepresentative, Correspondent $correspondent, $correspondents) : array
{
// ...
$data = [
'disableResponsiveDocument' => 'false',
'emailSubject' => 'Your Subscription',
'emailBlurb' => 'Subscription pending',
'status' => 'sent',
'notification' => [
'useAccountDefaults' => 'false',
'reminders' => [
'reminderEnabled' => 'true',
'reminderDelay' => '1',
'reminderFrequency' => '1'
],
'expirations' => [
'expireEnabled' => 'True',
'expireAfter' => '250',
'expireWarn' => '2'
]
],
'compositeTemplates' => [
[
'serverTemplates' => [
[
'sequence' => '1',
'templateId' => $this->templateId
]
],
'inlineTemplates' => [
[
'sequence' => '2',
'recipients' => [
'signers' => [
[
'email' => $legalRepresentative->getEmail(),
'name' => $legalRepresentative->getLastname(),
'recipientId' => '1',
'recipientSignatureProviders' => [
[
'signatureProviderName' => 'universalsignaturepen_opentrust_hash_tsp',
'signatureProviderOptions' => [
'sms' => substr($legalRepresentative->getCellphone(), 0, 3) == '+33' ? $legalRepresentative->getCellphone() : '+33' . substr($legalRepresentative->getCellphone(), 1),
]
]
],
'roleName' => 'Client',
'clientUserId' => $legalRepresentative->getId(),
'tabs' => [
'textTabs' => $textTabs,
'radioGroupTabs' => $radioTabs,
'checkboxTabs' => $checkboxTabs
]
]
]
]
]
]
]
],
'eventNotification' => [
"url" => $this->router->generate("api_post_subscription_completed_callback", [
"subscriptionId" => $subscription->getId()
], UrlGeneratorInterface::ABSOLUTE_URL),
"includeCertificateOfCompletion" => "false",
"includeDocuments" => "true",
"includeDocumentFields" => "true",
"includeHMAC" => "true",
"requireAcknowledgment" => "true",
"envelopeEvents" => [
[
"envelopeEventStatusCode" => "completed"
]
]
]
];
$response = $this->sendRequest(
'POST',
$this->getBaseUri() . '/envelopes',
[
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $this->getCacheToken()
],
json_encode($data)
);
}
public function isValidHash(string $signature, string $payload): bool
{
$hexHash = hash_hmac('sha256',utf8_encode($payload),utf8_encode($this->hmacKey));
$base64Hash = base64_encode(hex2bin($hexHash));
return $signature === $base64Hash;
}
I've created my hmac key in my Docusign Connect and i'm receiving the signature in the header and the payload but the verification always failed.
I've followed the Docusign documentation here
What's wrong ?
PS: Sorry for my bad english
Your code looks good to me. Make sure that you are only sending one HMAC signature. That way your hmacKey is the correct one.
As a check, I'd print out the utf8_encode($payload) and check that it looks right (it should be the incoming XML, no headers). Also, I don't think it should have a CR/NL in it at the beginning. That's the separator between the HTTP header and body.
Update
I have verified that the PHP code from the DocuSign web site works correctly.
The payload value must not contain either a leading or trailing newline. It should start with <?xml and end with >
I suspect that your software is adding a leading or trailing newline.
The secret (from DocuSign) ends with an =. It is a Base64 encoded value. Do not decode it. Just use it as a string.
Another update
The payload (the body of the request) contains zero new lines.
If you're printing the payload, you'll need to wrap it in <pre> since it includes < characters. Or look at the page source.
It contains UTF-8 XML such as
<?xml version="1.0" encoding="utf-8"?><DocuSignEnvelopeInformation xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.docusign.net/API/3.0"><EnvelopeStatus><RecipientStatuses><RecipientStatus><Type>Signer</Type><Email>larry#worldwidecorp.us</Email><UserName>Larry Kluger</UserName><RoutingOrder>1</RoutingOrder><Sent>2020-08-05T03:11:13.057</Sent><Delivered>2020-08-05T03:11:27.657</Delivered><DeclineReason xsi:nil="true" /><Status>Delivered</Status><RecipientIPAddress>5.102.239.40</RecipientIPAddress><CustomFields /><TabStatuses><TabStatus><TabType>Custom</TabType><Status>Active</Status><XPosition>223</XPosition><YPosition>744....
We've done some more testing, and the line
$payload = file_get_contents('php://input');
should be very early in your script. The problem is that a framework can munge the php://input stream so it won't work properly thereafter.
Note this page from the Symfony site -- it indicates that the right way to get the request body is:
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\ParameterBag;
$app->before(function (Request $request) {
$payload = $request->getContent();
hmac_verify($payload, $secret);
});
I would try to use the Symfony code instead of file_get_contents('php://input');
I would like to know how to change the text when clicked button attached to it (Inline keyboards). It's in a telegram channel.
Something like this but with my code below (no need for more options).
The code I have now:
$data = [
'text' => 'choose options yes or no',
'chat_id' => '-100234234234'
];
$keyboard = array(
"inline_keyboard" => array(
array(
array(
"text" => "Yes",
"callback_data" => "myCallbackData"
),
array(
"text" => "No",
"callback_data" => "myCallbackData"
)
)
)
file_get_contents("https://api.telegram.org/bot$token/sendMessage?" . http_build_query($data) . "&parse_mode=html&reply_markup=$keyboard");
After sending the message;
Remember the message_id returned by Telegram
Call /getUpdates to get the callback_data of pressed button
Use /editMessageText to update the first message
Example;
<?php
// Create data
$data = http_build_query([
'text' => 'Yes - No - Stop?',
'chat_id' => '1234567890'
]);
// Create keyboard
$keyboard = json_encode([
"inline_keyboard" => [
[
[
"text" => "Yes",
"callback_data" => "yes"
],
[
"text" => "No",
"callback_data" => "no"
],
[
"text" => "Stop",
"callback_data" => "stop"
]
]
]
]);
// Send keyboard
$url = "https://api.telegram.org/bot$token/sendMessage?{$data}&reply_markup={$keyboard}";
$res = #file_get_contents($url);
// Get message_id to alter later
$message_id = json_decode($res)->result->message_id;
// Continually check for a 'press'
while (true) {
// Call /getUpdates
$updates = #file_get_contents("https://api.telegram.org/bot$token/getUpdates");
$updates = json_decode($updates);
// Check if we've got a button press
if (count($updates->result) > 0 && isset(end($updates->result)->callback_query->data)) {
// Get callback data
$callBackData = end($updates->result)->callback_query->data;
// Check for 'stop'
if ($callBackData === 'stop') {
// Say goodbye and remove keyboard
$data = http_build_query([
'text' => 'Bye!',
'chat_id' => '1234567890',
'message_id' => $message_id
]);
$alter_res = #file_get_contents("https://api.telegram.org/bot$token/editMessageText?{$data}");
// End while
break;
}
// Alter text with callback_data
$data = http_build_query([
'text' => 'Selected: ' . $callBackData,
'chat_id' => '1234567890',
'message_id' => $message_id
]);
$alter_res = #file_get_contents("https://api.telegram.org/bot$token/editMessageText?{$data}&reply_markup={$keyboard}");
}
// Sleep for a second, and check again
sleep(1);
}
Note:
This example is written based on OP's code, just to show the idea of altering an inline_keyboard.
This code is purely as an example, there should be a lot more error checking etc...
Based on the comment, I've included a while true to keep on checking for new press.
Please I need some help......am developing a Facebook messenger chatbot and I have issue with the List template. When I send the template, the response is received and displays well on the web but on the messenger app, everything gets lumped in one button. Any idea will be appreciated. Thanks.
if($message == "about"){
$answer = ["attachment"=>[
"type"=>"template",
"payload"=>[
"template_type"=>"list",
"elements"=>[
[
"title"=> "Founder",
"image_url"=> "https://www.cloudways.com/blog/wp-content/uploads/Migrating-Your-Symfony-Website.jpg",
"subtitle"=> "Frederick Angel",
"default_action"=> [
"type"=> "web_url",
"url"=> "https://www.cloudways.com/blog/migrate-symfony-from-cpanel-to-cloud-hosting/",
"webview_height_ratio"=> "tall",
// "messenger_extensions"=> true
// "fallback_url"=> "https://peterssendreceiveapp.ngrok.io/"
],
"buttons"=>[
[
"type"=>"postback",
"title"=>"Read about him",
"payload"=>"Frederick Angel",
"webview_height_ratio"=> "tall",
// "messenger_extensions"=>true
],
]
],
[
"title"=>"Concepts?",
"default_action"=> [
"type"=> "web_url",
"url"=> "https://www.cloudways.com/blog/migrate-symfony-from-cpanel-to-cloud-hosting/",
"webview_height_ratio"=> "tall",
// "messenger_extensions"=> true
// "fallback_url"=> "https://peterssendreceiveapp.ngrok.io/"
],
"buttons"=>[
[
"type"=>"postback",
"title"=>"Read about it",
"payload"=>"concepts",
"webview_height_ratio"=> "tall"
],
]
]
]
]];
$template = [
'recipient' => [ 'id' => $senderId ],
'message' => $answer
];
}