How to get chat_id in botpress telegram channel? - telegram

I need to authorize the user in telegram. so I need to get the chat id or user phone number. how do I get the chat_id or user phone no from telegram bot to my bot press actions
const myAction = async () => {
bp.logger.info('Here i need the chat id or mobile no')
// bp.logger.info(JSON.stringify())
let payloads = await bp.cms.renderElement('builtin_text', { text: 'Hello' }, event)
await bp.events.replyToEvent(event, payloads)
}
return myAction()

Related

Firebase Auth: How to unsubscribe from Auth observer after user creation and then subscribe again?

I am using the createUserWithEmailAndPassword() method for signing up new users. Immediately after this user creation process, I am sending an email verification. Then, in my onAuthStateChanged() I have a condition to check whether the user has verified their email. The problem is that the Auth observer is logging out the user BEFORE the email sendEmailVerification() method is complete.
Based on the below code, where is the best place to succuessfully unsubscribe the observer ? And, how to do it with Firebase JS SDK v9?
Let me explain my use case and show my code:
pages/sign-up:
async signUp() {
const auth = getAuth()
const batch = writeBatch(db)
try {
const UserCredential = await createUserWithEmailAndPassword(
auth,
this.formValues.email,
this.formValues.password
)
const userDocRef = doc(db, 'users', UserCredential.user.uid)
batch.set(userDocRef, {
uid: UserCredential.user.uid,
displayName: this.formValues.displayName,
photoURL: `https://gravatar.com/avatar/${md5(
this.formValues.email
)}?d=identicon`
})
const usernameDocRef = doc(db, 'usernames', this.formValues.displayName)
batch.set(usernameDocRef, { uid: UserCredential.user.uid })
// Commit batch
await batch.commit()
console.log('batch committed, user is:', UserCredential.user.uid)
await this.verifyEmail() // <-- user is logged out before this has a chance to fire!
verifyEmail():
async verifyEmail() {
const auth = getAuth()
const actionCodeSettings = {
url: `${this.$config.baseUrl}/email-confirmation/success`
}
try {
await sendEmailVerification(auth.currentUser, actionCodeSettings)
} catch (error) {
console.error('An email verification error happened', error)
this.errorMessage = error.message
}
},
In my onAuthStateChanged() method, I am immediately logging out the user IF their email is not yet verified. This causes the following error:
And here is how I have my onAuthStateChanged observer set up (it runs before the page is rendered):
~/plugins/auth.js:
onAuthStateChanged(auth, (user) => {
if (user) {
if (!user.emailVerified) {
// User has not verified the email yet
store.dispatch('logOutUser')
}
// TO DO: finish up rest of user logic
Should the unsubscribe be in the auth.js or the pages/sign-up page? I am unsure how to unsubscribe.
If you need to perform certain actions after signup/login, then you should unsubscribe from auth observer as you've figured out.
const authObserver = onAuthStateChanged(auth, (user) => {
// ...
}
async signUp() {
//unsubscribe here i.e when user clicks signup button
authObserver()
const auth = getAuth()
const batch = writeBatch(db)
// ...
}
Do note that, if you you auth observer is meant to redirect logged in user somewhere else then it won't do it now. So make sure you do that manually.

How to send a message to Telegram from Zapier

Zapier does not offer native integration for Telegram. How can one send a message to Telegram chat from Zapier?
Zapier offers Code actions that can execute JavaScript or Python code. You can use JavaScript fetch and Telegram HTTP API to post messages to Telegram chats through your bot.
// TG bot API documentation https://core.telegram.org/bots/api
// Set up the bot with BotFather and the API token https://telegram.me/BotFather
const TG_API_TOKEN = "xxx";
// Add the bot to a chat
// In chat type: /start to make the bot to recognise the chat
// Get chat it by calling TG getUpdates API in terminal and picking
// the chat id from the output by hand
//
// curl https://api.telegram.org/bot$TG_API_TOKEN/getUpdates | jq
//
const CHAT_ID = "xxx";
async function postData(url, data) {
// Default options are marked with *
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
return response.json(); // parses JSON response into native JavaScript objects
}
// Create the message using uptick formatting from whatever inputData field
// you choose in Zapier
const message = `Hello my old friend ${inputData.id}`;
console.log("Sending out", message);
// Create sendMessage payload
const payload = {chat_id: CHAT_ID, text: message, disable_notification: false};
// Which endpoint we are calling
const endpoint = `https://api.telegram.org/bot${TG_API_TOKEN}/sendMessage`;
// Call Telegram HTTP API
const resp = await postData(endpoint, payload);
console.log("We got", resp);
// Zapier scripts needed output - pass Telegram API response
output = resp;
There's no need to do this using Python or Javascript. You can use the POST function in Zapier's Webhooks to send a message directly via the Bot API:
URL https://api.telegram.org/bot{BOT_API_TOKEN}/sendMessage
Payload Type json
Data
text your message
chat_id -{CHANNEL_OR_GROUP_ID}
Note the use of the - symbol in front of the chat_id; you must have this in order for it to work.

Can we batch multiple onCreate events in one cloud function?

I have a cloud function newMessage to listen on any onCreate() event in firebase realtime database. When the newMessage function is triggered, it will get the snapshot of the message content, and use mailgun to send email notification for the new message.
pseudo code is like:
exports.newMessage = functions.database
.ref('/privateMessages/{userA}/{userB}/{messageId}')
.onCreate((snap, context) => {
let senderEmail, receiverEmail, messageContent;
// 1. get message senderEmail, receiverEmail and messageContent from the snap and context.
// 2. use mailgun to send email to receiverEmail for the new message
let data = {
from: senderEmail,
to: receiverEmail,
subject: 'New Message from Freebies',
text: messageContent
};
mailgun.messages().send(data, (error, body) => {
console.log(body);
});
})
return null;
})
My concern is if user is flooding the chat messages, from the newMessage, it will send email every time there comes a new message. On receiver's side, it would be annoying if there are too many email notifications in the inbox. So my question is that is it possible to have multiple onCreate() to get multiple new messages, say within 1 hour, and send only 1 email message for those new messages?

How do I update a FirebaseUser's phone number in firebase_auth?

In my Flutter app I use Firebase's phone number authentication as my main form of authentication. After authenticating, I create a user in my users collection with these details:
{
phoneNumber: FirebaseAuth.instance.currentUser().phoneNumber,
displayName: 'Comes from user textbox',
...
}
But say one day a user want's to change their phone number. How do I do this? Because I cannot simply change the user's phone number in the document, because the phone number needs to be authenticated. And after authentication, the user gets a new authUID. Which should then be a new user?
Could someone explain the logic behind a user that wants to keep their profile details but change their number.
In order to achieve this, you can use User.updatePhoneNumber. This allows you to update the phone number of a user.
You would use it in the same manner that you also authenticated with phone number in the first place (using signInWithCredential), i.e. you retrieve a credential using FirebaseAuth.verifyPhoneNumber and pass the credential that you get from either verificationCompleted or your user when they enter the SMS code they received. I will only sketch out what this would look like as I assume that you know how to perform this task:
FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber: phoneNumber,
timeout: const Duration(minutes: 2),
verificationCompleted: (credential) async {
await (await FirebaseAuth.instance.currentUser()).updatePhoneNumber(credential);
// either this occurs or the user needs to manually enter the SMS code
},
verificationFailed: null,
codeSent: (verificationId, [forceResendingToken]) async {
String smsCode;
// get the SMS code from the user somehow (probably using a text field)
final AuthCredential credential =
PhoneAuthProvider.getCredential(verificationId: verificationId, smsCode: smsCode);
await (await FirebaseAuth.instance.currentUser()).updatePhoneNumber(credential);
},
codeAutoRetrievalTimeout: null);
When updatePhoneNumber is called, you probably also want to update your database document. Alternatively, you could listen to onAuthStateChanged and update your document this way.
async function save(phone: string, e) {
e.preventDefault();
const { currentUser:fuser } = firebase.auth();
if(fuser && fuser.phoneNumber !== phone) {
try {
const verifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', {
callback: (response) => console.log('callback', response),
size: 'invisible',
});
const phoneProvider = new firebase.auth.PhoneAuthProvider();
const id = await phoneProvider.verifyPhoneNumber(phone, verifier);
const code = window.prompt('Bitte zugeschickten Code eingeben');
const cred = firebase.auth.PhoneAuthProvider.credential(id, code);
await fuser.updatePhoneNumber(cred);
console.log('phone number changed', id, cred, fuser);
setSuccess(true);
} catch(e) {
console.error(e);
}
}
}

Send push notifications using Firebase and OneSignal

Not sure if this is possible, but I have an existing Ionic 3 app which uses Firebase as a backend. Maybe it's just me, I'm not able to integrate Google login, Facebook login and push notifications in the same app. Been trying for a few days now.
I was able to install OneSignal and send push notifications to an Android device, but I want to send them programatically using tokens which are saved for each device, not from the OneSignal dashboard.
This is what I use in Firebase Cloud Functions to send notifications. Can it be modified to send the notification to OneSignal and then to each device?
`function sendFcm(userID, eventSnapshot, eventID) {
const getDeviceTokensPromise = admin.database().ref(`/fcmTokens/${userID}/`).once('value');
return Promise.all([getDeviceTokensPromise]).then(result => {
const tokensSnapshot = result[0];
const payload = {
"notification": {
"title": "Your invitation has arrived",
"body": eventSnapshot.name,
"sound": "default",
// "click_action": "FCM_PLUGIN_ACTIVITY",
"icon": "fcm_push_icon"
},
"data": {
"eventId": eventID,
"uid": userID,
"eventObj": JSON.stringify(eventSnapshot),
"notificationType": "newEventNotification"
}
};
const tokens = Object.keys(tokensSnapshot.val());
console.log(tokens);
// Send notifications to all tokens.
return admin.messaging().sendToDevice(tokens, payload).then(response => {
// For each message check if there was an error.
const tokensToRemove = [];
response.results.forEach((result, index) => {
console.log(tokens[index]);
const error = result.error;
if (error) {
console.error('Failure sending notification to', tokens[index], error);
// Cleanup the tokens which are not registered anymore.
if (error.code === 'messaging/invalid-registration-token' ||
error.code === 'messaging/registration-token-not-registered') {
tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
}
}
});
return Promise.all(tokensToRemove);
});
})
}`
After searching a bit, I found the OneSignal API. Seems that I just need to save the player id and send it or mutiple in an array to onesignal.com/api/v1/notifications. More details here: https://documentation.onesignal.com/reference#section-send-based-on-onesignal-playerids-create-notification

Resources