I have to send emails using particular gmail account in flutter - flutter

I want to send an email using a particular email address. But in my app first I sign in using google and then send emails using Gmail API using logged in user auth-headers.
But in this, anyone can log in and send emails. but I want only a particular email can send emails from my app. So I statically store auth headers for that particular email and sending email but my problem is that auth headers is expire after some time.
Here my code for google sign In:
GoogleSignIn googleSignIn = new GoogleSignIn(
scopes: <String>['https://www.googleapis.com/auth/gmail.send'],
);
await googleSignIn.signIn().then((data) async {
await data.authHeaders.then((result) async {
var header = {
'Authorization': result['Authorization'],
'X-Goog-AuthUser': result['X-Goog-AuthUser']
};
await testingEmail(data.email, header);
});
});
Code for send email:
Future<Null> testingEmail(String userId, Map header) async {
header['Content-type'] = 'application/json';
var from = userId;
var to = 'email in which send email';
var subject = 'subject of mail';
var message = 'Body of email';
var content = '''
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
to: $to
from: 'Email alias name <$from>'
subject: $subject
$message''';
var bytes = utf8.encode(content);
var base64 = base64Encode(bytes);
var body = json.encode({'raw': base64});
String url = 'https://www.googleapis.com/gmail/v1/users/' +
userId +
'/messages/send';
final http.Response response =
await http.post(url, headers: header, body: body);
if (response.statusCode != 200) {
return Future.error("Something went wrong");
}
}
Help me to sort out this problem

You can refresh your token
Future<String> getRefreshToken()async{
if(_auth?.currentUser() !=null){
// print("user----------${_auth.currentUser()}");
FirebaseUser user = await _auth?.currentUser();
if(user !=null){
dynamic value = await user?.getIdToken(refresh: true);
String tokenValue = value?.token;
return tokenValue;
}
return null;
}
return null;
}

Related

How to upload image to server in flutter

How does uploading image to server works in flutter! The ImagePicker return a path to directory,what url should be sent to server and what url should be used to show image on app if I want to upload a png format with autorization token in form-data with key profile_image and to show the similar Image.Below is one of the multiple I tried..
asyncFileUpload(File file) async {
var request = http.MultipartRequest(
"POST",
_getUri(
'/profilepicture',
));
var token = getHeaders();
request.headers["authorization"] = token as String;
;
var pic = await http.MultipartFile.fromPath("profile_image", file.path);
request.files.add(pic);
var response = await request.send();
var responseData = await response.stream.toBytes();
var responseString = String.fromCharCodes(responseData);
print(responseString);
}
What you are sending to the server is .png file and what is supposed to be shown to the user is the image in the server(url path) not the url path from phone. Therefore if the response returns that url all you need to do is get hold of it in the NetworkImage('url') or Image.network('url')
Note: It would be easy if you first show the picked image in your view then have a button that does the submit to the server. If successful replace the image picked url with the url from the server
asyncFileUpload(File file) async {
try {
var request = http.MultipartRequest(
'POST',Uri.parse('url'));
var token = getHeaders();
request.headers["authorization"] = token as String;
request.headers.addAll({
'Content-Type': 'application/json'
});
//request.fields.addAll({
// 'user_id': userId,
//});
request.files.add(await http.MultipartFile.fromPath('profile_image',file.path));
var response = await request.send();
var serverResponse = await http.Response.fromStream(response);
final responseData = json.decode(serverResponse.body);
if(response.statusCode == 200 || response.statusCode == 201){
return responseData;
}else{
return responseData;
}
} catch (e) {
print("Error occurred: $e");
return Future.error(e);
}
}

How to make a http post using form data in flutter

I'm trying to do a http post request and I need to specify the body as form-data, because the server don't take the request as raw or params.
here is the code I tried
** Future getApiResponse(url) async {
try {
// fetching data from the url
final response = await http.get(Uri.parse(url));
// checking status codes.
if (response.statusCode == 200 || response.statusCode == 201) {
responseJson = jsonDecode(response.body);
// log('$responseJson');
}
// debugPrint(response.body.toString());
} on SocketException {
throw FetchDataException(message: 'No internet connection');
}
return responseJson;
}
}
but its not working. here is the post man request
enter image description here
its not working on parms. only in body. its because this is in form data I guess.
how do I call form data in flutter using HTTP post?
First of all you can't send request body with GET request (you have to use POST/PUT etc.) and you can use Map for request body as form data because body in http package only has 3 types: String, List or Map. Try like this:
var formDataMap = Map<String, dynamic>();
formDataMap['username'] = 'username';
formDataMap['password'] = 'password';
final response = await http.post(
Uri.parse('http/url/of/your/api'),
body: formDataMap,
);
log(response.body);
For HTTP you can try this way
final uri = 'yourURL';
var map = new Map<String, dynamic>();
map['device-type'] = 'Android';
map['username'] = 'John';
map['password'] = '123456';
http.Response response = await http.post(
uri,
body: map,
);
I have use dio: ^4.0.6 to create FormData and API Calling.
//Create Formdata
formData = FormData.fromMap({
"username" : "John",
"password" : "123456",
"device-type" : "Android"
});
//API Call
final response = await (_dio.post(
yourURL,
data: formData,
cancelToken: cancelToken ?? _cancelToken,
options: options,
))

Generate PDF and attach to Gmail:MIME Multipart request flutter web app

The requirement is to generate a receipt in the form of pdf and send an email to the user using Gmail API. I am able to send attachment but not attachment and message together (multipart). Here is the dart code written for a web app. If I add base64Str - i.e. bytes generated from pdf in the contentMultiPart, it simply creates pdf of base64 string. Hence I am attaching to body externally. Please help with Multipart MIME message.
class AdminCredentials {
final String? email;
final String? accessToken;
final String? idToken;
AdminCredentials(this.email, this.accessToken, {this.idToken});
}
generatepdf() async {
final pdf = pw.Document();
pdf.addPage(pw.Page(
pageFormat: PdfPageFormat.a4,
build: (pw.Context context) {
return pw.Center(
child: pw.Text("Hello World"),
); // Center
})); // Page
final bytes = await pdf.save();
return bytes;
}
sendEmail(AdminCredentials? adminCredentials) async {
Map<String, String> header = {};
header['Authorization'] = 'Bearer ${adminCredentials!.accessToken}';
header['Accept'] = 'application/json';
header['Content-type'] = 'application/json';
var pdfbytes = await generatepdf();
final base64Str = base64Encode(pdfbytes);
var from = adminCredentials.email;
var to = "test#gmail.com";
var subject ='Receipt';
var message = '<h1>Receipt generated against your flat </h1>\n<p>Dear Sir/Madam,<br/><br/>Thanks for your payment. Please find attached the receipt generated against your flat <br/><br/>Thanks and regards<br/>Office</p>';
var contentMultiPart = '''
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: multipart/mixed; charset="UTF-8"; boundary="part";
to: ${to}
from: ${from}
subject: ${subject}
--part
Content-Type: application/pdf; charset="base64"; Content-Disposition=application; name=receipt.pdf;
--part
Content-Type: text/html; charset="us-ascii";
$message
--part--
''';
List<int> bytes = utf8.encode(contentMultiPart);
String base64 = base64Encode(bytes);
var body = json.encode({'raw': base64+base64Str});
String apiUrl = 'https://www.googleapis.com/gmail/v1/users/' + from! + '/messages/send?uploadType=multipart';
Uri uri = Uri.parse(apiUrl);
final http.Response response = await http.post(uri, headers: header, body: body);
debugPrint('Response send');
print(json.decode(response.body));
if (response.statusCode != 200) {
final Map<String, dynamic> data = json.decode(response.body);
print('error: ' + response.statusCode.toString());
print(data);
return false;
} else {
print('ok: ' + response.statusCode.toString());
print('ok: ' + response.headers.toString());
return true;
}
}

Simple http request with basicauth stucks

I don’t really want to do anything other than a simple HTTP-request with a GET parameter and Basic Auth.
For this, I have written the following small class. However, not much seems to happen here. The request is started but it doesn’t seem to return any result. It runs and runs and should timeout or something like that.
class HttpService {
Future<List<Post>> getPosts() async {
final queryParameters = {
'data_type': 'temps_today',
};
String username = 'user';
String password = 'password';
String basicAuth =
'Basic ' + base64Encode(utf8.encode('$username:$password'));
print(basicAuth);
Response res = await get(Uri.https('mydomain.com', '/gartentemp/api/get_temp_data.php', queryParameters), headers: <String, String>{'authorization': basicAuth}); //stucks here
print(res.statusCode);
if (res.statusCode == 200) {
List<dynamic> body = jsonDecode(res.body);
List<Post> posts = body
.map(
(dynamic item) => Post.fromJson(item),
)
.toList();
return posts;
} else {
throw "Unable to retrieve posts.";
}
}
}
In the browser, a JSON file is delivered without any problems.
What's wrong with my try?
Thx niesel

How to Sending sms and email using Dart (Flutter)?

I am trying to build and app in flutter which sends email and SMS. Purpose is to reset password (forgot Password). But I am not able to find a suitable package for it. The email or SMS should be sent with out user interaction once they click reset password. The SMS and email will be sent from their mobile to the very same number or email.
Any alternate suggestions?
For Email, you can use this mailer package => https://pub.dev/packages/mailer
Update:
If this function didn't work then lower your mailer package version.
Example:
Future<void> sendMail(String name, String otp, String recipientEmail) async {
// ignore: deprecated_member_use
SmtpServer smtpServer = gmail('yourEmail', 'Password');
Message message = Message()
..from = address('yourEmail', 'UserName')
..recipients.add(recipientEmail)
..subject = 'Any Text.'
..html = "Any Text.";
try {
final sendReport = await send(message, smtpServer);
PrintLog.printMessage('Message sent: ' + sendReport.toString());
} on MailerException catch (e) {
PrintLog.printMessage('Message not sent. ' + e.toString());
for (var p in e.problems) {
PrintLog.printMessage('Problem: ${p.code}: ${p.msg}');
}
}
var connection = PersistentConnection(smtpServer);
await connection.send(message);
await connection.close();
}
For SMS, you can use Url Launcher Package => https://pub.dev/packages/url_launcher
Example:
_textMe() async {
if (Platform.isAndroid) {
const uri = 'sms:YourNumber?body=hello%20there';
await launch(uri);
} else if (Platform.isIOS) {
// iOS
const uri = 'sms:YourNumber&body=hello%20there';
await launch(uri);
}
}